mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-30 23:32:38 +00:00
commit
ded7de0e72
@ -2,8 +2,6 @@ language: node_js
|
|||||||
node_js:
|
node_js:
|
||||||
- "7.2"
|
- "7.2"
|
||||||
- "6.9"
|
- "6.9"
|
||||||
- "5.12"
|
|
||||||
- "4.7"
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi
|
- if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi
|
||||||
install:
|
install:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
build: {
|
build: {
|
||||||
filenames: {
|
filenames: {
|
||||||
|
css: 'styles.[chunkhash].css', // default: common.[chunkhash].css
|
||||||
manifest: 'manifest.[hash].js', // default: manifest.[hash].js
|
manifest: 'manifest.[hash].js', // default: manifest.[hash].js
|
||||||
vendor: 'vendor.[hash].js', // default: vendor.bundle.[hash].js
|
vendor: 'vendor.[hash].js', // default: vendor.bundle.[hash].js
|
||||||
app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js
|
app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import middleware from './middleware'
|
import middleware from './middleware'
|
||||||
import { app, router<%= (store ? ', store' : '') %>, NuxtError } from './index'
|
import { createApp, NuxtError } from './index'
|
||||||
import { applyAsyncData, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promiseSeries, promisify, getLocation, compile } from './utils'
|
import { applyAsyncData, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promiseSeries, promisify, getLocation, compile } from './utils'
|
||||||
const noopData = () => { return {} }
|
const noopData = () => { return {} }
|
||||||
const noopFetch = () => {}
|
const noopFetch = () => {}
|
||||||
let _lastPaths = []
|
let _lastPaths = []
|
||||||
let _lastComponentsFiles = []
|
let _lastComponentsFiles = []
|
||||||
|
|
||||||
|
const { app, router<%= (store ? ', store' : '') %> } = createApp()
|
||||||
|
|
||||||
function mapTransitions(Components, to, from) {
|
function mapTransitions(Components, to, from) {
|
||||||
return Components.map((Component) => {
|
return Components.map((Component) => {
|
||||||
let transition = Component.options.transition
|
let transition = Component.options.transition
|
||||||
|
163
lib/app/index.js
163
lib/app/index.js
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Meta from 'vue-meta'
|
import Meta from 'vue-meta'
|
||||||
import router from './router.js'
|
import { createRouter } from './router.js'
|
||||||
<% if (store) { %>import store from './store.js'<% } %>
|
<% if (store) { %>import { createStore } from './store.js'<% } %>
|
||||||
import NuxtChild from './components/nuxt-child.js'
|
import NuxtChild from './components/nuxt-child.js'
|
||||||
import NuxtLink from './components/nuxt-link.js'
|
import NuxtLink from './components/nuxt-link.js'
|
||||||
import NuxtError from '<%= components.ErrorPage ? components.ErrorPage : "./components/nuxt-error.vue" %>'
|
import NuxtError from '<%= components.ErrorPage ? components.ErrorPage : "./components/nuxt-error.vue" %>'
|
||||||
@ -25,86 +25,97 @@ Vue.use(Meta, {
|
|||||||
tagIDKeyName: 'hid' // the property name that vue-meta uses to determine whether to overwrite or append a tag
|
tagIDKeyName: 'hid' // the property name that vue-meta uses to determine whether to overwrite or append a tag
|
||||||
})
|
})
|
||||||
|
|
||||||
if (process.browser) {
|
|
||||||
<% if (store) { %>
|
|
||||||
// Replace store state before calling plugins
|
|
||||||
if (window.__NUXT__ && window.__NUXT__.state) {
|
|
||||||
store.replaceState(window.__NUXT__.state)
|
|
||||||
}
|
|
||||||
<% } %>
|
|
||||||
// window.onNuxtReady(() => console.log('Ready')) hook
|
|
||||||
// Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading)
|
|
||||||
window._nuxtReadyCbs = []
|
|
||||||
window.onNuxtReady = function (cb) {
|
|
||||||
window._nuxtReadyCbs.push(cb)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// root instance
|
|
||||||
// here we inject the router and store to all child components,
|
|
||||||
// making them available everywhere as `this.$router` and `this.$store`.
|
|
||||||
const defaultTransition = <%=
|
const defaultTransition = <%=
|
||||||
serialize(transition)
|
serialize(transition)
|
||||||
.replace('beforeEnter(', 'function(').replace('enter(', 'function(').replace('afterEnter(', 'function(')
|
.replace('beforeEnter(', 'function(').replace('enter(', 'function(').replace('afterEnter(', 'function(')
|
||||||
.replace('enterCancelled(', 'function(').replace('beforeLeave(', 'function(').replace('leave(', 'function(')
|
.replace('enterCancelled(', 'function(').replace('beforeLeave(', 'function(').replace('leave(', 'function(')
|
||||||
.replace('afterLeave(', 'function(').replace('leaveCancelled(', 'function(')
|
.replace('afterLeave(', 'function(').replace('leaveCancelled(', 'function(')
|
||||||
%>
|
%>
|
||||||
let app = {
|
|
||||||
router,
|
export { NuxtError }
|
||||||
<%= (store ? 'store,' : '') %>
|
|
||||||
_nuxt: {
|
export function createApp (ssrContext) {
|
||||||
defaultTransition: defaultTransition,
|
<% if (store) { %>
|
||||||
transitions: [ defaultTransition ],
|
const store = createStore()
|
||||||
setTransitions (transitions) {
|
<% } %>
|
||||||
if (!Array.isArray(transitions)) {
|
const router = createRouter()
|
||||||
transitions = [ transitions ]
|
|
||||||
}
|
if (process.browser) {
|
||||||
transitions = transitions.map((transition) => {
|
<% if (store) { %>
|
||||||
if (!transition) {
|
// Replace store state before calling plugins
|
||||||
transition = defaultTransition
|
if (window.__NUXT__ && window.__NUXT__.state) {
|
||||||
} else if (typeof transition === 'string') {
|
store.replaceState(window.__NUXT__.state)
|
||||||
transition = Object.assign({}, defaultTransition, { name: transition })
|
|
||||||
} else {
|
|
||||||
transition = Object.assign({}, defaultTransition, transition)
|
|
||||||
}
|
|
||||||
return transition
|
|
||||||
})
|
|
||||||
this.$options._nuxt.transitions = transitions
|
|
||||||
return transitions
|
|
||||||
},
|
|
||||||
err: null,
|
|
||||||
dateErr: null,
|
|
||||||
error (err) {
|
|
||||||
err = err || null
|
|
||||||
if (typeof err === 'string') {
|
|
||||||
err = { statusCode: 500, message: err }
|
|
||||||
}
|
|
||||||
this.$options._nuxt.dateErr = Date.now()
|
|
||||||
this.$options._nuxt.err = err;
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
},
|
<% } %>
|
||||||
...App
|
// window.onNuxtReady(() => console.log('Ready')) hook
|
||||||
}
|
// Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading)
|
||||||
|
window._nuxtReadyCbs = []
|
||||||
|
window.onNuxtReady = function (cb) {
|
||||||
|
window._nuxtReadyCbs.push(cb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// root instance
|
||||||
|
// here we inject the router and store to all child components,
|
||||||
|
// making them available everywhere as `this.$router` and `this.$store`.
|
||||||
|
let app = {
|
||||||
|
router,
|
||||||
|
<%= (store ? 'store,' : '') %>
|
||||||
|
ssrContext,
|
||||||
|
_nuxt: {
|
||||||
|
defaultTransition: defaultTransition,
|
||||||
|
transitions: [ defaultTransition ],
|
||||||
|
setTransitions (transitions) {
|
||||||
|
if (!Array.isArray(transitions)) {
|
||||||
|
transitions = [ transitions ]
|
||||||
|
}
|
||||||
|
transitions = transitions.map((transition) => {
|
||||||
|
if (!transition) {
|
||||||
|
transition = defaultTransition
|
||||||
|
} else if (typeof transition === 'string') {
|
||||||
|
transition = Object.assign({}, defaultTransition, { name: transition })
|
||||||
|
} else {
|
||||||
|
transition = Object.assign({}, defaultTransition, transition)
|
||||||
|
}
|
||||||
|
return transition
|
||||||
|
})
|
||||||
|
this.$options._nuxt.transitions = transitions
|
||||||
|
return transitions
|
||||||
|
},
|
||||||
|
err: null,
|
||||||
|
dateErr: null,
|
||||||
|
error (err) {
|
||||||
|
err = err || null
|
||||||
|
if (typeof err === 'string') {
|
||||||
|
err = { statusCode: 500, message: err }
|
||||||
|
}
|
||||||
|
this.$options._nuxt.dateErr = Date.now()
|
||||||
|
this.$options._nuxt.err = err;
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...App
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Includes & Inject external plugins
|
// Includes & Inject external plugins
|
||||||
<% plugins.forEach(function (plugin) {
|
<% plugins.forEach(function (plugin) {
|
||||||
if (plugin.ssr) { %>
|
if (plugin.ssr) { %>
|
||||||
<%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>')
|
|
||||||
<% if (plugin.injectAs) { %>
|
|
||||||
<%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %>
|
|
||||||
app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %>
|
|
||||||
<% }
|
|
||||||
} else { %>
|
|
||||||
if (process.browser) {
|
|
||||||
<%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>')
|
<%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>')
|
||||||
<% if (plugin.injectAs) { %>
|
<% if (plugin.injectAs) { %>
|
||||||
<%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %>
|
<%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %>
|
||||||
app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %>
|
app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %>
|
||||||
<% } %>
|
<% }
|
||||||
}
|
} else { %>
|
||||||
<% }
|
if (process.browser) {
|
||||||
}) %>
|
<%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>')
|
||||||
|
<% if (plugin.injectAs) { %>
|
||||||
|
<%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %>
|
||||||
|
app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %>
|
||||||
|
<% } %>
|
||||||
|
}
|
||||||
|
<% }
|
||||||
|
}) %>
|
||||||
|
|
||||||
export { app, router<%= (store ? ', store' : '') %>, NuxtError }
|
return { app, router<%= (store ? ', store' : '') %> }
|
||||||
|
}
|
||||||
|
@ -53,12 +53,14 @@ const scrollBehavior = (to, from, savedPosition) => {
|
|||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
export default new Router({
|
export function createRouter () {
|
||||||
mode: '<%= router.mode %>',
|
return new Router({
|
||||||
base: '<%= router.base %>',
|
mode: '<%= router.mode %>',
|
||||||
linkActiveClass: '<%= router.linkActiveClass %>',
|
base: '<%= router.base %>',
|
||||||
scrollBehavior,
|
linkActiveClass: '<%= router.linkActiveClass %>',
|
||||||
routes: [
|
scrollBehavior,
|
||||||
<%= _routes %>
|
routes: [
|
||||||
]
|
<%= _routes %>
|
||||||
})
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -7,11 +7,10 @@ import Vue from 'vue'
|
|||||||
import { stringify } from 'querystring'
|
import { stringify } from 'querystring'
|
||||||
import { omit } from 'lodash'
|
import { omit } from 'lodash'
|
||||||
import middleware from './middleware'
|
import middleware from './middleware'
|
||||||
import { app, router<%= (store ? ', store' : '') %>, NuxtError } from './index'
|
import { createApp, NuxtError } from './index'
|
||||||
import { applyAsyncData, getMatchedComponents, getContext, promiseSeries, promisify, urlJoin } from './utils'
|
import { applyAsyncData, getMatchedComponents, getContext, promiseSeries, promisify, urlJoin } from './utils'
|
||||||
|
|
||||||
const isDev = <%= isDev %>
|
const isDev = <%= isDev %>
|
||||||
const _app = new Vue(app)
|
|
||||||
|
|
||||||
// This exported function will be called by `bundleRenderer`.
|
// This exported function will be called by `bundleRenderer`.
|
||||||
// This is where we perform data-prefetching to determine the
|
// This is where we perform data-prefetching to determine the
|
||||||
@ -19,6 +18,8 @@ const _app = new Vue(app)
|
|||||||
// Since data fetching is async, this function is expected to
|
// Since data fetching is async, this function is expected to
|
||||||
// return a Promise that resolves to the app instance.
|
// return a Promise that resolves to the app instance.
|
||||||
export default context => {
|
export default context => {
|
||||||
|
const { app, router<%= (store ? ', store' : '') %> } = createApp(context)
|
||||||
|
const _app = new Vue(app)
|
||||||
// Add store to the context
|
// Add store to the context
|
||||||
<%= (store ? 'context.store = store' : '') %>
|
<%= (store ? 'context.store = store' : '') %>
|
||||||
// Nuxt object
|
// Nuxt object
|
||||||
|
@ -30,8 +30,11 @@ let storeData = {}
|
|||||||
if (filenames.indexOf('./index.js') !== -1) {
|
if (filenames.indexOf('./index.js') !== -1) {
|
||||||
let mainModule = getModule('./index.js')
|
let mainModule = getModule('./index.js')
|
||||||
if (mainModule.commit) {
|
if (mainModule.commit) {
|
||||||
store = mainModule
|
console.error('[nuxt.js] store/index.js should export raw store options instead of an instance.')
|
||||||
} else {
|
} else {
|
||||||
|
if (mainModule.state && typeof mainModule.state !== 'function') {
|
||||||
|
console.error('[nuxt.js] store state should be a function.')
|
||||||
|
}
|
||||||
storeData = mainModule
|
storeData = mainModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,8 +52,13 @@ if (store == null) {
|
|||||||
name = namePath.pop()
|
name = namePath.pop()
|
||||||
module[name] = getModule(filename)
|
module[name] = getModule(filename)
|
||||||
module[name].namespaced = true
|
module[name].namespaced = true
|
||||||
|
|
||||||
|
if (typeof module[name].state !== 'function') {
|
||||||
|
console.error('[nuxt.js] store module state should be a function.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
store = new Vuex.Store(storeData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default store
|
export function createStore () {
|
||||||
|
return new Vuex.Store(storeData)
|
||||||
|
}
|
||||||
|
61
lib/build.js
61
lib/build.js
@ -47,6 +47,7 @@ const defaults = {
|
|||||||
analyze: false,
|
analyze: false,
|
||||||
publicPath: '/_nuxt/',
|
publicPath: '/_nuxt/',
|
||||||
filenames: {
|
filenames: {
|
||||||
|
css: 'common.[chunkhash].css',
|
||||||
manifest: 'manifest.[hash].js',
|
manifest: 'manifest.[hash].js',
|
||||||
vendor: 'vendor.bundle.[hash].js',
|
vendor: 'vendor.bundle.[hash].js',
|
||||||
app: 'nuxt.bundle.[chunkhash].js'
|
app: 'nuxt.bundle.[chunkhash].js'
|
||||||
@ -101,9 +102,11 @@ export function options () {
|
|||||||
}
|
}
|
||||||
const serverConfig = getWebpackServerConfig.call(this)
|
const serverConfig = getWebpackServerConfig.call(this)
|
||||||
const bundlePath = join(serverConfig.output.path, 'server-bundle.json')
|
const bundlePath = join(serverConfig.output.path, 'server-bundle.json')
|
||||||
if (fs.existsSync(bundlePath)) {
|
const manifestPath = join(serverConfig.output.path, 'client-manifest.json')
|
||||||
|
if (fs.existsSync(bundlePath) && fs.existsSync(manifestPath)) {
|
||||||
const bundle = fs.readFileSync(bundlePath, 'utf8')
|
const bundle = fs.readFileSync(bundlePath, 'utf8')
|
||||||
createRenderer.call(this, JSON.parse(bundle))
|
const manifest = fs.readFileSync(manifestPath, 'utf8')
|
||||||
|
createRenderer.call(this, JSON.parse(bundle), JSON.parse(manifest))
|
||||||
addAppTemplate.call(this)
|
addAppTemplate.call(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,10 +145,8 @@ function * buildFiles () {
|
|||||||
watchPages.call(this)
|
watchPages.call(this)
|
||||||
} else {
|
} else {
|
||||||
debug('Building files...')
|
debug('Building files...')
|
||||||
yield [
|
yield webpackRunClient.call(this)
|
||||||
webpackRunClient.call(this),
|
yield webpackRunServer.call(this)
|
||||||
webpackRunServer.call(this)
|
|
||||||
]
|
|
||||||
addAppTemplate.call(this)
|
addAppTemplate.call(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -386,6 +387,7 @@ function createWebpackMiddleware () {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
const clientCompiler = webpack(clientConfig)
|
const clientCompiler = webpack(clientConfig)
|
||||||
|
this.clientCompiler = clientCompiler
|
||||||
// Add the middleware to the instance context
|
// Add the middleware to the instance context
|
||||||
this.webpackDevMiddleware = pify(require('webpack-dev-middleware')(clientCompiler, {
|
this.webpackDevMiddleware = pify(require('webpack-dev-middleware')(clientCompiler, {
|
||||||
publicPath: clientConfig.output.publicPath,
|
publicPath: clientConfig.output.publicPath,
|
||||||
@ -406,20 +408,35 @@ function createWebpackMiddleware () {
|
|||||||
interpolate: /{{([\s\S]+?)}}/g
|
interpolate: /{{([\s\S]+?)}}/g
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
this.watchHandler()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function webpackWatchAndUpdate () {
|
function webpackWatchAndUpdate () {
|
||||||
const MFS = require('memory-fs') // <- dependencies of webpack
|
const MFS = require('memory-fs') // <- dependencies of webpack
|
||||||
const mfs = new MFS()
|
const serverFS = new MFS()
|
||||||
|
const clientFS = this.clientCompiler.outputFileSystem
|
||||||
const serverConfig = getWebpackServerConfig.call(this)
|
const serverConfig = getWebpackServerConfig.call(this)
|
||||||
const serverCompiler = webpack(serverConfig)
|
const serverCompiler = webpack(serverConfig)
|
||||||
const outputPath = join(serverConfig.output.path, 'server-bundle.json')
|
const bundlePath = join(serverConfig.output.path, 'server-bundle.json')
|
||||||
serverCompiler.outputFileSystem = mfs
|
const manifestPath = join(serverConfig.output.path, 'client-manifest.json')
|
||||||
this.webpackServerWatcher = serverCompiler.watch(this.options.watchers.webpack, (err) => {
|
serverCompiler.outputFileSystem = serverFS
|
||||||
|
const watchHandler = (err) => {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
createRenderer.call(this, JSON.parse(mfs.readFileSync(outputPath, 'utf-8')))
|
const bundleExists = serverFS.existsSync(bundlePath)
|
||||||
})
|
const manifestExists = clientFS.existsSync(manifestPath)
|
||||||
|
if (!bundleExists) {
|
||||||
|
debug('Waiting for server bundle...')
|
||||||
|
} else if (!manifestExists) {
|
||||||
|
debug('Waiting for client manifest...')
|
||||||
|
} else {
|
||||||
|
const bundle = serverFS.readFileSync(bundlePath, 'utf8')
|
||||||
|
const manifest = clientFS.readFileSync(manifestPath, 'utf8')
|
||||||
|
createRenderer.call(this, JSON.parse(bundle), JSON.parse(manifest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.watchHandler = watchHandler
|
||||||
|
this.webpackServerWatcher = serverCompiler.watch(this.options.watchers.webpack, watchHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
function webpackRunClient () {
|
function webpackRunClient () {
|
||||||
@ -444,16 +461,18 @@ function webpackRunServer () {
|
|||||||
console.log('[nuxt:build:server]\n', stats.toString(webpackStats)) // eslint-disable-line no-console
|
console.log('[nuxt:build:server]\n', stats.toString(webpackStats)) // eslint-disable-line no-console
|
||||||
if (stats.hasErrors()) return reject(new Error('Webpack build exited with errors'))
|
if (stats.hasErrors()) return reject(new Error('Webpack build exited with errors'))
|
||||||
const bundlePath = join(serverConfig.output.path, 'server-bundle.json')
|
const bundlePath = join(serverConfig.output.path, 'server-bundle.json')
|
||||||
|
const manifestPath = join(serverConfig.output.path, 'client-manifest.json')
|
||||||
readFile(bundlePath, 'utf8')
|
readFile(bundlePath, 'utf8')
|
||||||
.then((bundle) => {
|
.then(bundle => readFile(manifestPath, 'utf8')
|
||||||
createRenderer.call(this, JSON.parse(bundle))
|
.then(manifest => {
|
||||||
resolve()
|
createRenderer.call(this, JSON.parse(bundle), JSON.parse(manifest))
|
||||||
})
|
resolve()
|
||||||
|
}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRenderer (bundle) {
|
function createRenderer (bundle, manifest) {
|
||||||
// Create bundle renderer to give a fresh context for every request
|
// Create bundle renderer to give a fresh context for every request
|
||||||
let cacheConfig = false
|
let cacheConfig = false
|
||||||
if (this.options.cache) {
|
if (this.options.cache) {
|
||||||
@ -463,9 +482,11 @@ function createRenderer (bundle) {
|
|||||||
maxAge: 1000 * 60 * 15
|
maxAge: 1000 * 60 * 15
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
this.renderer = createBundleRenderer(bundle, {
|
this.renderer = createBundleRenderer(bundle, Object.assign({
|
||||||
cache: cacheConfig
|
cache: cacheConfig,
|
||||||
})
|
clientManifest: manifest,
|
||||||
|
runInNewContext: false
|
||||||
|
}, this.options.ssr))
|
||||||
this.renderToString = pify(this.renderer.renderToString)
|
this.renderToString = pify(this.renderer.renderToString)
|
||||||
this.renderToStream = this.renderer.renderToStream
|
this.renderToStream = this.renderer.renderToStream
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,7 @@ class Nuxt {
|
|||||||
performance: {
|
performance: {
|
||||||
gzip: {
|
gzip: {
|
||||||
threshold: 0
|
threshold: 0
|
||||||
},
|
}
|
||||||
prefetch: true
|
|
||||||
},
|
},
|
||||||
watchers: {
|
watchers: {
|
||||||
webpack: {},
|
webpack: {},
|
||||||
|
@ -93,7 +93,7 @@ export function renderRoute (url, context = {}) {
|
|||||||
// Add url and isSever to the context
|
// Add url and isSever to the context
|
||||||
context.url = url
|
context.url = url
|
||||||
context.isServer = true
|
context.isServer = true
|
||||||
// Call rendertoSting from the bundleRenderer and generate the HTML (will update the context as well)
|
// Call renderToSting from the bundleRenderer and generate the HTML (will update the context as well)
|
||||||
const self = this
|
const self = this
|
||||||
return co(function * () {
|
return co(function * () {
|
||||||
let APP = yield self.renderToString(context)
|
let APP = yield self.renderToString(context)
|
||||||
@ -105,8 +105,9 @@ export function renderRoute (url, context = {}) {
|
|||||||
if (self.options.router.base !== '/') {
|
if (self.options.router.base !== '/') {
|
||||||
HEAD += `<base href="${self.options.router.base}">`
|
HEAD += `<base href="${self.options.router.base}">`
|
||||||
}
|
}
|
||||||
HEAD += context.styles
|
HEAD += context.renderResourceHints() + context.renderStyles()
|
||||||
APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })}</script>`
|
APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })}</script>`
|
||||||
|
APP += context.renderScripts()
|
||||||
const html = self.appTemplate({
|
const html = self.appTemplate({
|
||||||
HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
|
HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
|
||||||
BODY_ATTRS: m.bodyAttrs.text(),
|
BODY_ATTRS: m.bodyAttrs.text(),
|
||||||
@ -127,7 +128,8 @@ export function renderAndGetWindow (url, opts = {}) {
|
|||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (!jsdom) {
|
if (!jsdom) {
|
||||||
try {
|
try {
|
||||||
jsdom = require('jsdom')
|
// https://github.com/tmpvar/jsdom/blob/master/lib/old-api.md
|
||||||
|
jsdom = require('jsdom/lib/old-api')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Fail when calling nuxt.renderAndGetWindow(url)') // eslint-disable-line no-console
|
console.error('Fail when calling nuxt.renderAndGetWindow(url)') // eslint-disable-line no-console
|
||||||
console.error('jsdom module is not installed') // eslint-disable-line no-console
|
console.error('jsdom module is not installed') // eslint-disable-line no-console
|
||||||
@ -136,6 +138,7 @@ export function renderAndGetWindow (url, opts = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let virtualConsole = jsdom.createVirtualConsole().sendTo(console)
|
let virtualConsole = jsdom.createVirtualConsole().sendTo(console)
|
||||||
|
// let virtualConsole = new jsdom.VirtualConsole().sendTo(console)
|
||||||
if (opts.virtualConsole === false) {
|
if (opts.virtualConsole === false) {
|
||||||
virtualConsole = undefined
|
virtualConsole = undefined
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import vueLoaderConfig from './vue-loader.config'
|
|||||||
import { defaults } from 'lodash'
|
import { defaults } from 'lodash'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { isUrl, urlJoin } from '../utils'
|
import { isUrl, urlJoin } from '../utils'
|
||||||
|
import { styleLoader, extractStyles } from './helpers'
|
||||||
|
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -71,15 +73,21 @@ export default function ({ isClient, isServer }) {
|
|||||||
cacheDirectory: !!this.dev
|
cacheDirectory: !!this.dev
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ test: /\.css$/, loader: 'vue-style-loader!css-loader' },
|
{ test: /\.css$/, use: styleLoader.call(this, 'css') },
|
||||||
{ test: /\.less$/, loader: 'vue-style-loader!css-loader!less-loader' },
|
{ test: /\.less$/, use: styleLoader.call(this, 'less', 'less-loader') },
|
||||||
{ test: /\.sass$/, loader: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' },
|
{ test: /\.sass$/, use: styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax') },
|
||||||
{ test: /\.scss$/, loader: 'vue-style-loader!css-loader!sass-loader' },
|
{ test: /\.scss$/, use: styleLoader.call(this, 'sass', 'sass-loader') },
|
||||||
{ test: /\.styl(us)?$/, loader: 'vue-style-loader!css-loader!stylus-loader' }
|
{ test: /\.styl(us)?$/, use: styleLoader.call(this, 'stylus', 'stylus-loader') }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: this.options.build.plugins
|
plugins: this.options.build.plugins
|
||||||
}
|
}
|
||||||
|
// CSS extraction
|
||||||
|
if (extractStyles.call(this)) {
|
||||||
|
config.plugins.push(
|
||||||
|
new ExtractTextPlugin({filename: this.options.build.filenames.css})
|
||||||
|
)
|
||||||
|
}
|
||||||
// Add nuxt build loaders (can be configured in nuxt.config.js)
|
// Add nuxt build loaders (can be configured in nuxt.config.js)
|
||||||
config.module.rules = config.module.rules.concat(this.options.build.loaders)
|
config.module.rules = config.module.rules.concat(this.options.build.loaders)
|
||||||
// Return config
|
// Return config
|
||||||
|
@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
import { each, defaults } from 'lodash'
|
import { each, defaults } from 'lodash'
|
||||||
import webpack from 'webpack'
|
import webpack from 'webpack'
|
||||||
|
import VueSSRClientPlugin from 'vue-server-renderer/client-plugin'
|
||||||
|
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
||||||
import HTMLPlugin from 'html-webpack-plugin'
|
import HTMLPlugin from 'html-webpack-plugin'
|
||||||
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
|
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
|
||||||
import ScriptExtHtmlWebpackPlugin from 'script-ext-html-webpack-plugin'
|
|
||||||
import PreloadWebpackPlugin from 'preload-webpack-plugin'
|
|
||||||
import ProgressBarPlugin from 'progress-bar-webpack-plugin'
|
import ProgressBarPlugin from 'progress-bar-webpack-plugin'
|
||||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
|
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
|
||||||
import OfflinePlugin from 'offline-plugin'
|
import OfflinePlugin from 'offline-plugin'
|
||||||
import base from './base.config.js'
|
import base from './base.config.js'
|
||||||
|
import { extractStyles } from './helpers'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -56,31 +57,33 @@ export default function () {
|
|||||||
// Extract vendor chunks for better caching
|
// Extract vendor chunks for better caching
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
name: 'vendor',
|
name: 'vendor',
|
||||||
filename: this.options.build.filenames.vendor
|
filename: this.options.build.filenames.vendor,
|
||||||
|
minChunks (module) {
|
||||||
|
// A module is extracted into the vendor chunk when...
|
||||||
|
return (
|
||||||
|
// If it's inside node_modules
|
||||||
|
/node_modules/.test(module.context) &&
|
||||||
|
// Do not externalize if the request is a CSS file
|
||||||
|
!/\.css$/.test(module.request)
|
||||||
|
)
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
// Extract manifest
|
// Extract webpack runtime & manifest
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
name: 'manifest',
|
name: 'manifest',
|
||||||
|
minChunks: Infinity,
|
||||||
filename: this.options.build.filenames.manifest
|
filename: this.options.build.filenames.manifest
|
||||||
}),
|
}),
|
||||||
// Generate output HTML
|
// Generate output HTML
|
||||||
new HTMLPlugin({
|
new HTMLPlugin({
|
||||||
template: this.options.appTemplatePath
|
template: this.options.appTemplatePath,
|
||||||
|
inject: false // <- Resources will be injected using vue server renderer
|
||||||
}),
|
}),
|
||||||
// Add defer to scripts
|
// Generate client manifest json
|
||||||
new ScriptExtHtmlWebpackPlugin({
|
new VueSSRClientPlugin({
|
||||||
defaultAttribute: 'defer'
|
filename: 'client-manifest.json'
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
if (!this.dev && this.options.performance.prefetch === true) {
|
|
||||||
// Add prefetch code-splitted routes
|
|
||||||
config.plugins.push(
|
|
||||||
new PreloadWebpackPlugin({
|
|
||||||
rel: 'prefetch'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
// client bundle progress bar
|
// client bundle progress bar
|
||||||
config.plugins.push(
|
config.plugins.push(
|
||||||
new ProgressBarPlugin()
|
new ProgressBarPlugin()
|
||||||
|
15
lib/webpack/helpers.js
Executable file
15
lib/webpack/helpers.js
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
||||||
|
|
||||||
|
export function extractStyles(ext) {
|
||||||
|
return !this.dev && !!this.options.build.extractCSS && this.options.build.extractCSS[ext] !== false
|
||||||
|
}
|
||||||
|
|
||||||
|
export function styleLoader(ext, loader = []) {
|
||||||
|
if (!extractStyles.call(this, ext)) {
|
||||||
|
return ['vue-style-loader', 'css-loader'].concat(loader)
|
||||||
|
}
|
||||||
|
return ExtractTextPlugin.extract({
|
||||||
|
use: ['css-loader?minimize'].concat(loader),
|
||||||
|
fallback: 'vue-style-loader'
|
||||||
|
})
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import webpack from 'webpack'
|
import webpack from 'webpack'
|
||||||
import VueSSRPlugin from 'vue-ssr-webpack-plugin'
|
import VueSSRServerPlugin from 'vue-server-renderer/server-plugin'
|
||||||
import base from './base.config.js'
|
import base from './base.config.js'
|
||||||
import { each, uniq } from 'lodash'
|
import { each, uniq } from 'lodash'
|
||||||
import { existsSync, readFileSync } from 'fs'
|
import { existsSync, readFileSync } from 'fs'
|
||||||
@ -34,7 +34,7 @@ export default function () {
|
|||||||
hints: false
|
hints: false
|
||||||
},
|
},
|
||||||
plugins: (config.plugins || []).concat([
|
plugins: (config.plugins || []).concat([
|
||||||
new VueSSRPlugin({
|
new VueSSRServerPlugin({
|
||||||
filename: 'server-bundle.json'
|
filename: 'server-bundle.json'
|
||||||
}),
|
}),
|
||||||
new webpack.DefinePlugin(Object.assign(env, {
|
new webpack.DefinePlugin(Object.assign(env, {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import { defaults } from 'lodash'
|
import { defaults } from 'lodash'
|
||||||
|
import { extractStyles, styleLoader } from './helpers'
|
||||||
|
|
||||||
export default function ({ isClient }) {
|
export default function ({ isClient }) {
|
||||||
let babelOptions = JSON.stringify(defaults(this.options.build.babel, {
|
let babelOptions = JSON.stringify(defaults(this.options.build.babel, {
|
||||||
@ -8,18 +9,21 @@ export default function ({ isClient }) {
|
|||||||
babelrc: false,
|
babelrc: false,
|
||||||
cacheDirectory: !!this.dev
|
cacheDirectory: !!this.dev
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// https://github.com/vuejs/vue-loader/blob/master/docs/en/configurations
|
||||||
let config = {
|
let config = {
|
||||||
postcss: this.options.build.postcss,
|
postcss: this.options.build.postcss,
|
||||||
loaders: {
|
loaders: {
|
||||||
'js': 'babel-loader?' + babelOptions,
|
'js': 'babel-loader?' + babelOptions,
|
||||||
'css': 'vue-style-loader!css-loader',
|
'css': styleLoader.call(this, 'css'),
|
||||||
'less': 'vue-style-loader!css-loader!less-loader',
|
'less': styleLoader.call(this, 'less', 'less-loader'),
|
||||||
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
|
'sass': styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax'),
|
||||||
'scss': 'vue-style-loader!css-loader!sass-loader',
|
'scss': styleLoader.call(this, 'sass', 'scss-loader'),
|
||||||
'stylus': 'vue-style-loader!css-loader!stylus-loader',
|
'stylus': styleLoader.call(this, 'stylus', 'stylus-loader'),
|
||||||
'styl': 'vue-style-loader!css-loader!stylus-loader'
|
'styl': styleLoader.call(this, 'stylus', 'stylus-loader')
|
||||||
},
|
},
|
||||||
preserveWhitespace: false
|
preserveWhitespace: false,
|
||||||
|
extractCSS: extractStyles.call(this, 'vue')
|
||||||
}
|
}
|
||||||
// Return the config
|
// Return the config
|
||||||
return config
|
return config
|
||||||
|
34
package.json
34
package.json
@ -54,17 +54,18 @@
|
|||||||
"ansi-html": "^0.0.7",
|
"ansi-html": "^0.0.7",
|
||||||
"autoprefixer": "^6.7.7",
|
"autoprefixer": "^6.7.7",
|
||||||
"babel-core": "^6.24.1",
|
"babel-core": "^6.24.1",
|
||||||
"babel-loader": "^6.4.1",
|
"babel-loader": "^7.0.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-vue-app": "^1.2.0",
|
"babel-preset-vue-app": "^1.2.0",
|
||||||
"chokidar": "^1.6.1",
|
"chokidar": "^1.6.1",
|
||||||
"co": "^4.6.0",
|
"co": "^4.6.0",
|
||||||
"compression": "^1.6.2",
|
"compression": "^1.6.2",
|
||||||
"css-loader": "^0.28.0",
|
"css-loader": "^0.28.1",
|
||||||
"debug": "^2.6.3",
|
"debug": "^2.6.6",
|
||||||
|
"extract-text-webpack-plugin": "^2.1.0",
|
||||||
"file-loader": "^0.11.1",
|
"file-loader": "^0.11.1",
|
||||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||||
"fs-extra": "^2.1.2",
|
"fs-extra": "^3.0.0",
|
||||||
"glob": "^7.1.1",
|
"glob": "^7.1.1",
|
||||||
"hash-sum": "^1.0.2",
|
"hash-sum": "^1.0.2",
|
||||||
"html-minifier": "^3.4.3",
|
"html-minifier": "^3.4.3",
|
||||||
@ -79,25 +80,24 @@
|
|||||||
"progress-bar-webpack-plugin": "^1.9.3",
|
"progress-bar-webpack-plugin": "^1.9.3",
|
||||||
"script-ext-html-webpack-plugin": "^1.7.1",
|
"script-ext-html-webpack-plugin": "^1.7.1",
|
||||||
"serialize-javascript": "^1.3.0",
|
"serialize-javascript": "^1.3.0",
|
||||||
"serve-static": "^1.12.1",
|
"serve-static": "^1.12.2",
|
||||||
"url-loader": "^0.5.8",
|
"url-loader": "^0.5.8",
|
||||||
"vue": "~2.2.6",
|
"vue": "~2.3.1",
|
||||||
"vue-loader": "^11.3.4",
|
"vue-loader": "^12.0.2",
|
||||||
"vue-meta": "^0.5.6",
|
"vue-meta": "^0.5.6",
|
||||||
"vue-router": "^2.4.0",
|
"vue-router": "^2.5.3",
|
||||||
"vue-server-renderer": "~2.2.6",
|
"vue-server-renderer": "~2.3.1",
|
||||||
"vue-ssr-html-stream": "^2.2.0",
|
"vue-ssr-html-stream": "^2.2.0",
|
||||||
"vue-ssr-webpack-plugin": "^3.0.0",
|
"vue-template-compiler": "~2.3.1",
|
||||||
"vue-template-compiler": "~2.2.6",
|
"vuex": "^2.3.1",
|
||||||
"vuex": "^2.3.0",
|
|
||||||
"webpack": "^2.4.1",
|
"webpack": "^2.4.1",
|
||||||
"webpack-bundle-analyzer": "^2.4.0",
|
"webpack-bundle-analyzer": "^2.4.0",
|
||||||
"webpack-dev-middleware": "^1.10.1",
|
"webpack-dev-middleware": "^1.10.2",
|
||||||
"webpack-hot-middleware": "^2.18.0"
|
"webpack-hot-middleware": "^2.18.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ava": "^0.19.1",
|
"ava": "^0.19.1",
|
||||||
"babel-eslint": "^7.2.2",
|
"babel-eslint": "^7.2.3",
|
||||||
"babel-plugin-array-includes": "^2.0.3",
|
"babel-plugin-array-includes": "^2.0.3",
|
||||||
"babel-plugin-transform-async-to-generator": "^6.24.1",
|
"babel-plugin-transform-async-to-generator": "^6.24.1",
|
||||||
"babel-plugin-transform-runtime": "^6.23.0",
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
@ -111,10 +111,10 @@
|
|||||||
"eslint-plugin-node": "^4.2.2",
|
"eslint-plugin-node": "^4.2.2",
|
||||||
"eslint-plugin-promise": "^3.5.0",
|
"eslint-plugin-promise": "^3.5.0",
|
||||||
"eslint-plugin-standard": "^3.0.1",
|
"eslint-plugin-standard": "^3.0.1",
|
||||||
"finalhandler": "^1.0.1",
|
"finalhandler": "^1.0.2",
|
||||||
"jsdom": "^9.12.0",
|
"jsdom": "^10.1.0",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"nyc": "^10.2.0",
|
"nyc": "^10.3.0",
|
||||||
"request": "^2.81.0",
|
"request": "^2.81.0",
|
||||||
"request-promise-native": "^1.0.3",
|
"request-promise-native": "^1.0.3",
|
||||||
"webpack-node-externals": "^1.5.4"
|
"webpack-node-externals": "^1.5.4"
|
||||||
|
@ -17,12 +17,11 @@ test.before('Init Nuxt.js', async t => {
|
|||||||
test('Check .nuxt/router.js', t => {
|
test('Check .nuxt/router.js', t => {
|
||||||
return readFile(resolve(__dirname, './fixtures/dynamic-routes/.nuxt/router.js'), 'utf-8')
|
return readFile(resolve(__dirname, './fixtures/dynamic-routes/.nuxt/router.js'), 'utf-8')
|
||||||
.then((routerFile) => {
|
.then((routerFile) => {
|
||||||
routerFile = routerFile.slice(
|
routerFile = routerFile
|
||||||
routerFile.indexOf('routes: ['),
|
.slice(routerFile.indexOf('routes: ['))
|
||||||
-3
|
.replace('routes: [', '[')
|
||||||
)
|
.replace(/ _[0-9A-z]+,/g, ' "",')
|
||||||
.replace('routes: [', '[')
|
routerFile = routerFile.substr(routerFile.indexOf('['), routerFile.lastIndexOf(']') + 1)
|
||||||
.replace(/ _[0-9A-z]+,/g, ' "",')
|
|
||||||
let routes = eval('( ' + routerFile + ')') // eslint-disable-line no-eval
|
let routes = eval('( ' + routerFile + ')') // eslint-disable-line no-eval
|
||||||
// pages/index.vue
|
// pages/index.vue
|
||||||
t.is(routes[0].path, '/')
|
t.is(routes[0].path, '/')
|
||||||
|
@ -37,7 +37,7 @@ test('/ with renderAndGetWindow()', async t => {
|
|||||||
await nuxt.renderAndGetWindow(url('/'))
|
await nuxt.renderAndGetWindow(url('/'))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
t.true(e.message.includes('Could not load the nuxt app'))
|
t.true(e.message.includes('Could not load the nuxt app'))
|
||||||
t.true(e.body.includes('not_defined is not defined'))
|
t.true(e.body.includes('render function or template not defined in component'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
6
test/fixtures/basic/store/foo/bar.js
vendored
6
test/fixtures/basic/store/foo/bar.js
vendored
@ -1,5 +1,7 @@
|
|||||||
export const state = {
|
export const state = () => {
|
||||||
baz: 'Vuex Nested Modules'
|
return {
|
||||||
|
baz: 'Vuex Nested Modules'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
|
2
test/fixtures/with-config/store/index.js
vendored
2
test/fixtures/with-config/store/index.js
vendored
@ -3,7 +3,7 @@ import Vuex from 'vuex'
|
|||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
const store = () => new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
counter: 0
|
counter: 0
|
||||||
},
|
},
|
||||||
|
@ -82,7 +82,7 @@ test('/test/about-bis (added with extendRoutes)', async t => {
|
|||||||
|
|
||||||
test('Check stats.json generated by build.analyze', t => {
|
test('Check stats.json generated by build.analyze', t => {
|
||||||
const stats = require(resolve(__dirname, 'fixtures/with-config/.nuxt/dist/stats.json'))
|
const stats = require(resolve(__dirname, 'fixtures/with-config/.nuxt/dist/stats.json'))
|
||||||
t.is(stats.assets.length, 26)
|
t.is(stats.assets.length, 27)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Close server and ask nuxt to stop listening to file changes
|
// Close server and ask nuxt to stop listening to file changes
|
||||||
|
Loading…
Reference in New Issue
Block a user