mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 23:52:06 +00:00
Middleware feature 🔥
This commit is contained in:
parent
84b8a0de3f
commit
17650c25e0
@ -99,7 +99,7 @@ Learn more: https://nuxtjs.org/api/nuxt
|
||||
|
||||
## Using nuxt.js as a middleware
|
||||
|
||||
You might want to use your own server with you configurations, your API and everything awesome your created with. That's why you can use nuxt.js as a middleware. It's recommended to use it at the end of your middlewares since it will handle the rendering of your web application and won't call next().
|
||||
You might want to use your own server with you configurations, your API and everything awesome your created with. That's why you can use nuxt.js as a middleware. It's recommended to use it at the end of your middleware since it will handle the rendering of your web application and won't call next().
|
||||
|
||||
```js
|
||||
app.use(nuxt.render)
|
||||
|
@ -17,7 +17,7 @@ if (fs.existsSync(nuxtConfigFile)) {
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
options.dev = false // Force production mode (no webpack middlewares called)
|
||||
options.dev = false // Force production mode (no webpack middleware called)
|
||||
|
||||
console.log('[nuxt] Generating...') // eslint-disable-line no-console
|
||||
var nuxt = new Nuxt(options)
|
||||
|
@ -14,7 +14,7 @@ if (fs.existsSync(nuxtConfigFile)) {
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
options.dev = false // Force production mode (no webpack middlewares called)
|
||||
options.dev = false // Force production mode (no webpack middleware called)
|
||||
|
||||
var nuxt = new Nuxt(options)
|
||||
|
||||
|
10
examples/auth-routes/middleware/auth.js
Normal file
10
examples/auth-routes/middleware/auth.js
Normal file
@ -0,0 +1,10 @@
|
||||
export default function ({ store, redirect, error }) {
|
||||
// If user not connected, redirect to /
|
||||
if (!store.state.authUser) {
|
||||
// return redirect('/')
|
||||
error({
|
||||
message: 'You are not connected',
|
||||
statusCode: 403
|
||||
})
|
||||
}
|
||||
}
|
@ -6,6 +6,5 @@ module.exports = {
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||
{ hid: 'description', content: 'Auth Routes example' }
|
||||
]
|
||||
},
|
||||
loading: { color: '#3B8070' }
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@
|
||||
"name": "auth-routes",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"axios": "^0.15.3",
|
||||
"body-parser": "^1.15.2",
|
||||
"cross-env": "^3.1.3",
|
||||
"express": "^4.14.0",
|
||||
"express-session": "^1.14.2",
|
||||
"nuxt": "latest",
|
||||
"whatwg-fetch": "^2.0.1"
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "node server.js",
|
||||
|
@ -8,11 +8,6 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
// we use fetch() because we do not need to set data to this component
|
||||
fetch ({ store, redirect }) {
|
||||
if (!store.state.authUser) {
|
||||
return redirect('/')
|
||||
}
|
||||
}
|
||||
middleware: 'auth'
|
||||
}
|
||||
</script>
|
||||
|
@ -1,7 +1,9 @@
|
||||
const Nuxt = require('nuxt')
|
||||
const Nuxt = require('../../')
|
||||
const bodyParser = require('body-parser')
|
||||
const session = require('express-session')
|
||||
const app = require('express')()
|
||||
const host = process.env.HOST || '127.0.0.1'
|
||||
const port = process.env.PORT || '3000'
|
||||
|
||||
// Body parser, to access req.body
|
||||
app.use(bodyParser.json())
|
||||
@ -20,7 +22,7 @@ app.post('/api/login', function (req, res) {
|
||||
req.session.authUser = { username: 'demo' }
|
||||
return res.json({ username: 'demo' })
|
||||
}
|
||||
res.status(401).json({ error: 'Bad credentials' })
|
||||
res.status(401).json({ message: 'Bad credentials' })
|
||||
})
|
||||
|
||||
// POST /api/logout to log out the user and remove it from the req.session
|
||||
@ -29,19 +31,23 @@ app.post('/api/logout', function (req, res) {
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// We instantiate Nuxt.js with the options
|
||||
const isProd = process.env.NODE_ENV === 'production'
|
||||
// Import and Set Nuxt.js options
|
||||
let config = require('./nuxt.config.js')
|
||||
config.dev = !isProd
|
||||
config.dev = !(process.env.NODE_ENV === 'production')
|
||||
|
||||
// Init Nuxt.js
|
||||
const nuxt = new Nuxt(config)
|
||||
// No build in production
|
||||
const promise = (isProd ? Promise.resolve() : nuxt.build())
|
||||
promise.then(() => {
|
||||
app.use(nuxt.render)
|
||||
app.listen(3000)
|
||||
console.log('Server is listening on http://localhost:3000') // eslint-disable-line no-console
|
||||
})
|
||||
.catch((error) => {
|
||||
app.use(nuxt.render)
|
||||
|
||||
// Build only in dev mode
|
||||
if (config.dev) {
|
||||
nuxt.build()
|
||||
.catch((error) => {
|
||||
console.error(error) // eslint-disable-line no-console
|
||||
process.exit(1)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Listen the server
|
||||
app.listen(port, host)
|
||||
console.log('Server listening on ' + host + ':' + port) // eslint-disable-line no-console
|
||||
|
@ -1,69 +1,41 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import axios from 'axios'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
// Polyfill for window.fetch()
|
||||
require('whatwg-fetch')
|
||||
|
||||
const store = new Vuex.Store({
|
||||
|
||||
state: {
|
||||
export const state = {
|
||||
authUser: null
|
||||
},
|
||||
}
|
||||
|
||||
mutations: {
|
||||
export const mutations = {
|
||||
SET_USER: function (state, user) {
|
||||
state.authUser = user
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
nuxtServerInit ({ commit }, { req }) {
|
||||
if (req.session && req.session.authUser) {
|
||||
commit('SET_USER', req.session.authUser)
|
||||
}
|
||||
},
|
||||
|
||||
login ({ commit }, { username, password }) {
|
||||
return fetch('/api/login', {
|
||||
// Send the client cookies to the server
|
||||
credentials: 'same-origin',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
return axios.post('/api/login', {
|
||||
username,
|
||||
password
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.status === 401) {
|
||||
throw new Error('Bad credentials')
|
||||
} else {
|
||||
return res.json()
|
||||
}
|
||||
commit('SET_USER', res.data)
|
||||
})
|
||||
.then((authUser) => {
|
||||
commit('SET_USER', authUser)
|
||||
.catch((error) => {
|
||||
if (error.response.status === 401) {
|
||||
throw new Error('Bad credentials')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
logout ({ commit }) {
|
||||
return fetch('/api/logout', {
|
||||
// Send the client cookies to the server
|
||||
credentials: 'same-origin',
|
||||
method: 'POST'
|
||||
})
|
||||
return axios.post('/api/logout')
|
||||
.then(() => {
|
||||
commit('SET_USER', null)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
export default store
|
||||
}
|
||||
|
40
examples/middleware/components/Visits.vue
Normal file
40
examples/middleware/components/Visits.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="visit in visits"><i>{{ visit.date | hours }}</i> - {{ visit.path }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
visits () {
|
||||
return this.$store.state.visits.slice().reverse()
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
hours (date) {
|
||||
return date.split('T')[1].split('.')[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
ul {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
list-style-type: none;
|
||||
}
|
||||
ul li {
|
||||
padding: 2px 0;
|
||||
}
|
||||
ul li i {
|
||||
color: gray;
|
||||
font-style: normal;
|
||||
}
|
||||
</style>
|
14
examples/middleware/layouts/default.vue
Normal file
14
examples/middleware/layouts/default.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<nuxt/>
|
||||
<visits/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Visits from '~components/Visits'
|
||||
|
||||
export default {
|
||||
components: { Visits }
|
||||
}
|
||||
</script>
|
3
examples/middleware/middleware/user-agent.js
Normal file
3
examples/middleware/middleware/user-agent.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default function (context) {
|
||||
context.userAgent = context.isServer ? context.req.headers['user-agent'] : navigator.userAgent
|
||||
}
|
3
examples/middleware/middleware/visits.js
Normal file
3
examples/middleware/middleware/visits.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default function ({ store, route }) {
|
||||
store.commit('ADD_VISIT', route.path)
|
||||
}
|
5
examples/middleware/nuxt.config.js
Normal file
5
examples/middleware/nuxt.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
router: {
|
||||
middleware: ['visits', 'user-agent']
|
||||
}
|
||||
}
|
11
examples/middleware/package.json
Normal file
11
examples/middleware/package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "nuxt-middleware",
|
||||
"dependencies": {
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start"
|
||||
}
|
||||
}
|
25
examples/middleware/pages/_slug.vue
Normal file
25
examples/middleware/pages/_slug.vue
Normal file
@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>{{ $route.params.slug || 'Home' }}</h1>
|
||||
<pre>{{ userAgent }}</pre>
|
||||
<ul>
|
||||
<li><nuxt-link to="/">Home</nuxt-link></li>
|
||||
<li v-for="slug in slugs"><nuxt-link :to="{ name: 'slug', params: { slug } }">{{ slug }}</nuxt-link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data ({ store, route, userAgent }) {
|
||||
return {
|
||||
userAgent,
|
||||
slugs: [
|
||||
'foo',
|
||||
'bar',
|
||||
'baz'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
12
examples/middleware/store/index.js
Normal file
12
examples/middleware/store/index.js
Normal file
@ -0,0 +1,12 @@
|
||||
export const state = {
|
||||
visits: []
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
ADD_VISIT (state, path) {
|
||||
state.visits.push({
|
||||
path,
|
||||
date: new Date().toJSON()
|
||||
})
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
import Vue from 'vue'
|
||||
import middleware from './middleware'
|
||||
import { app, router<%= (store ? ', store' : '') %> } from './index'
|
||||
import { getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promisify, getLocation, compile } from './utils'
|
||||
import { getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promiseSeries, promisify, getLocation, compile } from './utils'
|
||||
const noopData = () => { return {} }
|
||||
const noopFetch = () => {}
|
||||
let _lastPaths = []
|
||||
@ -51,16 +52,44 @@ function loadAsyncComponents (to, from, next) {
|
||||
})
|
||||
}
|
||||
|
||||
function callMiddleware (Components, context, layout) {
|
||||
// Call middleware
|
||||
let midd = <%= serialize(router.middleware, { isJSON: true }) %>
|
||||
if (layout.middleware) {
|
||||
midd = midd.concat(layout.middleware)
|
||||
}
|
||||
Components.forEach((Component) => {
|
||||
if (Component.options.middleware) {
|
||||
midd = midd.concat(Component.options.middleware)
|
||||
}
|
||||
})
|
||||
midd = midd.map((name) => {
|
||||
if (typeof middleware[name] !== 'function') {
|
||||
this.error({ statusCode: 500, message: 'Unknown middleware ' + name })
|
||||
}
|
||||
return middleware[name]
|
||||
})
|
||||
if (this.$options._nuxt.err) return
|
||||
return promiseSeries(midd, context)
|
||||
}
|
||||
|
||||
function render (to, from, next) {
|
||||
if (this._hashChanged) return next()
|
||||
const _next = function (path) {
|
||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||
nextCalled = true
|
||||
next(path)
|
||||
}
|
||||
const context = getContext({ to<%= (store ? ', store' : '') %>, isClient: true, next: _next.bind(this), error: this.error.bind(this) })
|
||||
let Components = getMatchedComponents(to)
|
||||
this._dateLastError = this.$options._nuxt.dateErr
|
||||
this._hadError = !!this.$options._nuxt.err
|
||||
if (!Components.length) {
|
||||
// Default layout
|
||||
this.setLayout()
|
||||
.then(callMiddleware.bind(this, Components, context))
|
||||
.then(() => {
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.' })
|
||||
return next()
|
||||
})
|
||||
return
|
||||
@ -87,6 +116,7 @@ function render (to, from, next) {
|
||||
let nextCalled = false
|
||||
// Set layout
|
||||
this.setLayout(Components[0].options.layout)
|
||||
.then(callMiddleware.bind(this, Components, context))
|
||||
.then(() => {
|
||||
// Pass validation?
|
||||
let isValid = true
|
||||
@ -99,7 +129,7 @@ function render (to, from, next) {
|
||||
})
|
||||
})
|
||||
if (!isValid) {
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.', url: to.path })
|
||||
this.error({ statusCode: 404, message: 'This page could not be found.' })
|
||||
return next()
|
||||
}
|
||||
return Promise.all(Components.map((Component, i) => {
|
||||
@ -109,12 +139,6 @@ function render (to, from, next) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
let promises = []
|
||||
const _next = function (path) {
|
||||
<%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %>
|
||||
nextCalled = true
|
||||
next(path)
|
||||
}
|
||||
const context = getContext({ to<%= (store ? ', store' : '') %>, isClient: true, next: _next.bind(this), error: this.error.bind(this) })
|
||||
// Validate method
|
||||
if (Component._data && typeof Component._data === 'function') {
|
||||
var promise = promisify(Component._data, context)
|
||||
|
20
lib/app/middleware.js
Normal file
20
lib/app/middleware.js
Normal file
@ -0,0 +1,20 @@
|
||||
<% if (middleware) { %>
|
||||
let files = require.context('~/middleware', false, /^\.\/.*\.js$/)
|
||||
let filenames = files.keys()
|
||||
|
||||
function getModule (filename) {
|
||||
let file = files(filename)
|
||||
return file.default
|
||||
? file.default
|
||||
: file
|
||||
}
|
||||
let middleware = {}
|
||||
|
||||
// Generate the middleware
|
||||
for (let filename of filenames) {
|
||||
let name = filename.replace(/^\.\//, '').replace(/\.js$/, '')
|
||||
middleware[name] = getModule(filename)
|
||||
}
|
||||
|
||||
export default middleware
|
||||
<% } else { %>export default {}<% } %>
|
@ -5,8 +5,9 @@ debug.color = 4 // force blue color
|
||||
import Vue from 'vue'
|
||||
import { stringify } from 'querystring'
|
||||
import { omit } from 'lodash'
|
||||
import middleware from './middleware'
|
||||
import { app, router<%= (store ? ', store' : '') %> } from './index'
|
||||
import { getMatchedComponents, getContext, promisify, urlJoin } from './utils'
|
||||
import { getMatchedComponents, getContext, promiseSeries, promisify, urlJoin } from './utils'
|
||||
|
||||
const isDev = <%= isDev %>
|
||||
const _app = new Vue(app)
|
||||
@ -47,6 +48,7 @@ export default context => {
|
||||
context.error = _app.$options._nuxt.error.bind(_app)
|
||||
|
||||
<%= (isDev ? 'const s = isDev && Date.now()' : '') %>
|
||||
const ctx = getContext(context)
|
||||
let Components = getMatchedComponents(context.route)
|
||||
<% if (store) { %>
|
||||
let promise = (store._actions && store._actions.nuxtServerInit ? store.dispatch('nuxtServerInit', omit(getContext(context), 'redirect', 'error')) : null)
|
||||
@ -71,6 +73,26 @@ export default context => {
|
||||
// Set layout
|
||||
return _app.setLayout(Components.length ? Components[0].options.layout : '')
|
||||
})
|
||||
.then((layout) => {
|
||||
// Call middleware
|
||||
let midd = <%= serialize(router.middleware, { isJSON: true }) %>
|
||||
if (layout.middleware) {
|
||||
midd = midd.concat(layout.middleware)
|
||||
}
|
||||
Components.forEach((Component) => {
|
||||
if (Component.options.middleware) {
|
||||
midd = midd.concat(Component.options.middleware)
|
||||
}
|
||||
})
|
||||
midd = midd.map((name) => {
|
||||
if (typeof middleware[name] !== 'function') {
|
||||
context.nuxt.error = context.error({ statusCode: 500, message: 'Unknown middleware ' + name })
|
||||
}
|
||||
return middleware[name]
|
||||
})
|
||||
if (context.nuxt.error) return
|
||||
return promiseSeries(midd, ctx)
|
||||
})
|
||||
.then(() => {
|
||||
// Call .validate()
|
||||
let isValid = true
|
||||
@ -94,7 +116,6 @@ export default context => {
|
||||
// Call data & fetch hooks on components matched by the route.
|
||||
return Promise.all(Components.map((Component) => {
|
||||
let promises = []
|
||||
const ctx = getContext(context)
|
||||
if (Component.options.data && typeof Component.options.data === 'function') {
|
||||
Component._data = Component.options.data
|
||||
let promise = promisify(Component._data, ctx)
|
||||
@ -114,7 +135,7 @@ export default context => {
|
||||
})
|
||||
.then((res) => {
|
||||
if (!Components.length) {
|
||||
context.nuxt.error = context.error({ statusCode: 404, message: 'This page could not be found.', url: context.route.path })
|
||||
context.nuxt.error = context.error({ statusCode: 404, message: 'This page could not be found.' })
|
||||
<%= (store ? 'context.nuxt.state = store.state' : '') %>
|
||||
return _app
|
||||
}
|
||||
|
@ -2,15 +2,8 @@ import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
Vue.use(Vuex)
|
||||
|
||||
let files
|
||||
let filenames = []
|
||||
|
||||
try {
|
||||
files = require.context('~store', false, /^\.\/.*\.js$/)
|
||||
filenames = files.keys()
|
||||
} catch (e) {
|
||||
console.warn('Nuxt.js store:', e.message)
|
||||
}
|
||||
let files = require.context('~/store', false, /^\.\/.*\.js$/)
|
||||
let filenames = files.keys()
|
||||
|
||||
function getModule (filename) {
|
||||
let file = files(filename)
|
||||
|
@ -40,6 +40,7 @@ export function getContext (context) {
|
||||
ctx.query = ctx.route.query || {}
|
||||
ctx.redirect = function (status, path, query) {
|
||||
if (!status) return
|
||||
ctx._redirected = true
|
||||
// if only 1 or 2 arguments: redirect('/') or redirect('/', { foo: 'bar' })
|
||||
if (typeof status === 'string' && (typeof path === 'undefined' || typeof path === 'object')) {
|
||||
query = path || {}
|
||||
@ -57,6 +58,16 @@ export function getContext (context) {
|
||||
return ctx
|
||||
}
|
||||
|
||||
export function promiseSeries (promises, context) {
|
||||
if (!promises.length || context._redirected) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
return promisify(promises[0], context)
|
||||
.then(() => {
|
||||
return promiseSeries(promises.slice(1), context)
|
||||
})
|
||||
}
|
||||
|
||||
export function promisify (fn, context) {
|
||||
let promise
|
||||
if (fn.length === 2) {
|
||||
|
15
lib/build.js
15
lib/build.js
@ -120,8 +120,8 @@ export function * build () {
|
||||
|
||||
function * buildFiles () {
|
||||
if (this.dev) {
|
||||
debug('Adding webpack middlewares...')
|
||||
createWebpackMiddlewares.call(this)
|
||||
debug('Adding webpack middleware...')
|
||||
createWebpackMiddleware.call(this)
|
||||
webpackWatchAndUpdate.call(this)
|
||||
watchPages.call(this)
|
||||
} else {
|
||||
@ -148,12 +148,17 @@ function * generateRoutesAndFiles () {
|
||||
this.routes = _.uniq(_.map(files, (file) => {
|
||||
return file.replace(/^pages/, '').replace(/\.vue$/, '').replace(/\/index/g, '').replace(/_/g, ':').replace('', '/').replace(/\/{2,}/g, '/')
|
||||
}))
|
||||
if (typeof this.options.router.extendRoutes === 'function') {
|
||||
// let the user extend the routes
|
||||
this.options.router.extendRoutes(this.routes)
|
||||
}
|
||||
// Interpret and move template files to .nuxt/
|
||||
debug('Generating files...')
|
||||
let templatesFiles = [
|
||||
'App.vue',
|
||||
'client.js',
|
||||
'index.js',
|
||||
'middleware.js',
|
||||
'router.js',
|
||||
'server.js',
|
||||
'utils.js',
|
||||
@ -168,11 +173,13 @@ function * generateRoutesAndFiles () {
|
||||
isDev: this.dev,
|
||||
router: {
|
||||
base: this.options.router.base,
|
||||
middleware: this.options.router.middleware,
|
||||
linkActiveClass: this.options.router.linkActiveClass,
|
||||
scrollBehavior: this.options.router.scrollBehavior
|
||||
},
|
||||
env: this.options.env,
|
||||
head: this.options.head,
|
||||
middleware: this.options.middleware,
|
||||
store: this.options.store,
|
||||
css: this.options.css,
|
||||
plugins: this.options.plugins.map((p) => r(this.srcDir, p)),
|
||||
@ -294,7 +301,7 @@ function getWebpackServerConfig () {
|
||||
return serverWebpackConfig.call(this)
|
||||
}
|
||||
|
||||
function createWebpackMiddlewares () {
|
||||
function createWebpackMiddleware () {
|
||||
const clientConfig = getWebpackClientConfig.call(this)
|
||||
// setup on the fly compilation + hot-reload
|
||||
clientConfig.entry.app = _.flatten(['webpack-hot-middleware/client?reload=true', clientConfig.entry.app])
|
||||
@ -303,7 +310,7 @@ function createWebpackMiddlewares () {
|
||||
new webpack.NoEmitOnErrorsPlugin()
|
||||
)
|
||||
const clientCompiler = webpack(clientConfig)
|
||||
// Add the middlewares to the instance context
|
||||
// Add the middleware to the instance context
|
||||
this.webpackDevMiddleware = pify(require('webpack-dev-middleware')(clientCompiler, {
|
||||
publicPath: clientConfig.output.publicPath,
|
||||
stats: {
|
||||
|
@ -76,6 +76,7 @@ export default function () {
|
||||
console.error(`Could not generate the dynamic route ${route}, please add the mapping params in nuxt.config.js (generate.routeParams).`) // eslint-disable-line no-console
|
||||
return process.exit(1)
|
||||
}
|
||||
route = route + '?'
|
||||
const toPath = pathToRegexp.compile(route)
|
||||
routes = routes.concat(routeParams.map((params) => {
|
||||
return toPath(params)
|
||||
|
@ -37,13 +37,16 @@ class Nuxt {
|
||||
},
|
||||
router: {
|
||||
base: '/',
|
||||
middleware: [],
|
||||
linkActiveClass: 'nuxt-link-active',
|
||||
extendRoutes: null,
|
||||
scrollBehavior: null
|
||||
},
|
||||
build: {}
|
||||
}
|
||||
// Sanitization
|
||||
if (options.loading === true) delete options.loading
|
||||
if (options.router && typeof options.router.middleware === 'string') options.router.middleware = [ options.router.middleware ]
|
||||
if (typeof options.transition === 'string') options.transition = { name: options.transition }
|
||||
this.options = _.defaultsDeep(options, defaults)
|
||||
// Env variables
|
||||
@ -54,6 +57,11 @@ class Nuxt {
|
||||
if (fs.existsSync(join(this.srcDir, 'store'))) {
|
||||
this.options.store = true
|
||||
}
|
||||
// If middleware defined, update middleware option to true
|
||||
this.options.middleware = false
|
||||
if (fs.existsSync(join(this.srcDir, 'middleware'))) {
|
||||
this.options.middleware = true
|
||||
}
|
||||
// Template
|
||||
this.appTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'app.html'), 'utf8'), {
|
||||
imports: { serialize }
|
||||
|
@ -22,11 +22,11 @@ export function render (req, res) {
|
||||
const context = getContext(req, res)
|
||||
return co(function * () {
|
||||
if (self.dev) {
|
||||
// Call webpack middlewares only in development
|
||||
// Call webpack middleware only in development
|
||||
yield self.webpackDevMiddleware(req, res)
|
||||
yield self.webpackHotMiddleware(req, res)
|
||||
}
|
||||
// If base in req.url, remove it for the middlewares and vue-router
|
||||
// If base in req.url, remove it for the middleware and vue-router
|
||||
if (self.options.router.base !== '/' && req.url.indexOf(self.options.router.base) === 0) {
|
||||
// Compatibility with base url for dev server
|
||||
req.url = req.url.replace(self.options.router.base, '/')
|
||||
|
Loading…
Reference in New Issue
Block a user