diff --git a/lib/app/App.vue b/lib/app/App.vue index 15f9e34e26..f1a3546e4d 100644 --- a/lib/app/App.vue +++ b/lib/app/App.vue @@ -12,7 +12,7 @@ let layouts = { <% var layoutsKeys = Object.keys(layouts); layoutsKeys.forEach(function (key, i) { %> - "_<%= key %>": process.browser ? () => System.import('<%= layouts[key] %>') : require('<%= layouts[key] %>')<%= (i + 1) < layoutsKeys.length ? ',' : '' %> + "_<%= key %>": () => import('<%= layouts[key] %>')<%= (i + 1) < layoutsKeys.length ? ',' : '' %> <% }) %> } diff --git a/lib/app/router.js b/lib/app/router.js index 7c6c544a88..17cc6fb5f9 100644 --- a/lib/app/router.js +++ b/lib/app/router.js @@ -23,7 +23,7 @@ function recursiveRoutes(routes, tab, components) { var _components = [] var _routes = recursiveRoutes(router.routes, '\t\t', _components) uniqBy(_components, '_name').forEach((route) => { %> -const <%= route._name %> = process.browser ? () => System.import('<%= route.component %>') : require('<%= route.component %>') +const <%= route._name %> = () => import('<%= route.component %>') <% }) %> <% if (router.scrollBehavior) { %> diff --git a/lib/app/server.js b/lib/app/server.js index 16965bf96a..1c03a41071 100644 --- a/lib/app/server.js +++ b/lib/app/server.js @@ -8,7 +8,7 @@ import { stringify } from 'querystring' import { omit } from 'lodash' import middleware from './middleware' import { app, router<%= (store ? ', store' : '') %>, NuxtError } from './index' -import { getMatchedComponents, getContext, promiseSeries, promisify, urlJoin } from './utils' +import { getContext, promiseSeries, promisify, urlJoin } from './utils' const isDev = <%= isDev %> const _app = new Vue(app) @@ -51,14 +51,22 @@ export default context => { <%= (isDev ? 'const s = isDev && Date.now()' : '') %> let 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) - if (!(promise instanceof Promise)) promise = Promise.resolve() - <% } else { %> - let promise = Promise.resolve() - <% } %> - return promise + let Components = [] + return new Promise((resolve) => { + // Wait for the lazy-routes are loaded + router.onReady(resolve) + }) + .then(() => { + Components = router.getMatchedComponents() + // nuxtServerInit + <% if (store) { %> + let promise = (store._actions && store._actions.nuxtServerInit ? store.dispatch('nuxtServerInit', omit(getContext(context), 'redirect', 'error')) : null) + if (!(promise instanceof Promise)) promise = Promise.resolve() + <% } else { %> + let promise = Promise.resolve() + <% } %> + return promise + }) .then(() => { // Sanitize Components Components = Components.map((Component) => { @@ -89,7 +97,7 @@ export default context => { if (typeof layout === 'function') { layout = layout(ctx) } - return _app.setLayout(layout) + return _app.loadLayout(layout).then(() => _app.setLayout(layout)) }) .then((layout) => { // Call middleware (layout + pages) diff --git a/lib/build.js b/lib/build.js index 5391e01253..570cb3d52a 100644 --- a/lib/build.js +++ b/lib/build.js @@ -99,10 +99,10 @@ export function options () { colors: true } const serverConfig = getWebpackServerConfig.call(this) - const bundlePath = join(serverConfig.output.path, serverConfig.output.filename) + const bundlePath = join(serverConfig.output.path, 'server-bundle.json') if (fs.existsSync(bundlePath)) { const bundle = fs.readFileSync(bundlePath, 'utf8') - createRenderer.call(this, bundle) + createRenderer.call(this, JSON.parse(bundle)) addAppTemplate.call(this) } } @@ -413,11 +413,11 @@ function webpackWatchAndUpdate () { const mfs = new MFS() const serverConfig = getWebpackServerConfig.call(this) const serverCompiler = webpack(serverConfig) - const outputPath = join(serverConfig.output.path, serverConfig.output.filename) + const outputPath = join(serverConfig.output.path, 'server-bundle.json') serverCompiler.outputFileSystem = mfs this.webpackServerWatcher = serverCompiler.watch({}, (err) => { if (err) throw err - createRenderer.call(this, mfs.readFileSync(outputPath, 'utf-8')) + createRenderer.call(this, JSON.parse(mfs.readFileSync(outputPath, 'utf-8'))) }) } @@ -442,10 +442,10 @@ function webpackRunServer () { if (err) return reject(err) 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')) - const bundlePath = join(serverConfig.output.path, serverConfig.output.filename) + const bundlePath = join(serverConfig.output.path, 'server-bundle.json') readFile(bundlePath, 'utf8') .then((bundle) => { - createRenderer.call(this, bundle) + createRenderer.call(this, JSON.parse(bundle)) resolve() }) }) diff --git a/lib/nuxt.js b/lib/nuxt.js index 611d6ab347..51f1431301 100644 --- a/lib/nuxt.js +++ b/lib/nuxt.js @@ -42,7 +42,7 @@ class Nuxt { }, performance: { gzip: true, - prefetch: true + prefetch: false }, build: {} } diff --git a/lib/render.js b/lib/render.js index 0bc8c6fe58..388eff083c 100644 --- a/lib/render.js +++ b/lib/render.js @@ -100,6 +100,7 @@ export function renderRoute (url, context = {}) { if (self.options.router.base !== '/') { HEAD += `` } + HEAD += context.styles APP += `` const html = self.appTemplate({ HTML_ATTRS: 'n-head-ssr ' + m.htmlAttrs.text(), diff --git a/lib/webpack/base.config.js b/lib/webpack/base.config.js index b4832f6b73..1d435679ab 100644 --- a/lib/webpack/base.config.js +++ b/lib/webpack/base.config.js @@ -16,7 +16,7 @@ import { isUrl, urlJoin } from '../utils' export default function ({ isClient, isServer }) { const nodeModulesDir = join(__dirname, '..', 'node_modules') let config = { - devtool: 'source-map', + devtool: (this.dev ? 'cheap-module-eval-source-map' : false), entry: { vendor: ['vue', 'vue-router', 'vue-meta'] }, @@ -24,6 +24,7 @@ export default function ({ isClient, isServer }) { publicPath: (isUrl(this.options.build.publicPath) ? this.options.build.publicPath : urlJoin(this.options.router.base, this.options.build.publicPath)) }, performance: { + maxEntrypointSize: 300000, hints: (this.dev ? false : 'warning') }, resolve: { diff --git a/lib/webpack/client.config.js b/lib/webpack/client.config.js index 0cb8066080..6b84f5f6d2 100644 --- a/lib/webpack/client.config.js +++ b/lib/webpack/client.config.js @@ -5,7 +5,6 @@ import webpack from 'webpack' import HTMLPlugin from 'html-webpack-plugin' import ScriptExtHtmlWebpackPlugin from 'script-ext-html-webpack-plugin' import PreloadWebpackPlugin from 'preload-webpack-plugin' -import ExtractTextPlugin from 'extract-text-webpack-plugin' import ProgressBarPlugin from 'progress-bar-webpack-plugin' import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' import base from './base.config.js' @@ -82,15 +81,6 @@ export default function () { // Production client build if (!this.dev) { config.plugins.push( - // Use ExtractTextPlugin to extract CSS into a single file - new ExtractTextPlugin({ - filename: this.options.build.filenames.css, - allChunks: true - }), - // This is needed in webpack 2 for minifying CSS - new webpack.LoaderOptionsPlugin({ - minimize: true - }), // Minify JS new webpack.optimize.UglifyJsPlugin({ compress: { diff --git a/lib/webpack/server.config.js b/lib/webpack/server.config.js index bcbbce1092..4486e2c3ff 100644 --- a/lib/webpack/server.config.js +++ b/lib/webpack/server.config.js @@ -1,6 +1,7 @@ 'use strict' import webpack from 'webpack' +import VueSSRPlugin from 'vue-ssr-webpack-plugin' import base from './base.config.js' import { each, uniq } from 'lodash' import { existsSync, readFileSync } from 'fs' @@ -22,7 +23,7 @@ export default function () { config = Object.assign(config, { target: 'node', - devtool: false, + devtool: 'source-map', entry: resolve(this.dir, '.nuxt', 'server.js'), output: Object.assign({}, config.output, { path: resolve(this.dir, '.nuxt', 'dist'), @@ -30,6 +31,9 @@ export default function () { libraryTarget: 'commonjs2' }), plugins: (config.plugins || []).concat([ + new VueSSRPlugin({ + filename: 'server-bundle.json' + }), new webpack.DefinePlugin(Object.assign(env, { 'process.env.NODE_ENV': JSON.stringify(this.dev ? 'development' : 'production'), 'process.BROWSER_BUILD': false, // deprecated diff --git a/lib/webpack/vue-loader.config.js b/lib/webpack/vue-loader.config.js index e755a1fc96..7cb37d9444 100644 --- a/lib/webpack/vue-loader.config.js +++ b/lib/webpack/vue-loader.config.js @@ -19,17 +19,6 @@ export default function ({ isClient }) { }, preserveWhitespace: false } - - if (!this.dev && isClient) { - // Use ExtractTextPlugin to extract CSS into a single file - const ExtractTextPlugin = require('extract-text-webpack-plugin') - config.loaders.css = ExtractTextPlugin.extract({ loader: 'css-loader' }) - config.loaders.scss = ExtractTextPlugin.extract({ loader: 'css-loader!sass-loader', fallbackLoader: 'vue-style-loader' }) - config.loaders.sass = ExtractTextPlugin.extract({ loader: 'css-loader!sass-loader?indentedSyntax', fallbackLoader: 'vue-style-loader' }) - config.loaders.stylus = ExtractTextPlugin.extract({ loader: 'css-loader!stylus-loader', fallbackLoader: 'vue-style-loader' }) - config.loaders.less = ExtractTextPlugin.extract({ loader: 'css-loader!less-loader', fallbackLoader: 'vue-style-loader' }) - } - // Return the config return config } diff --git a/package.json b/package.json index 000add43d1..cd4f151cae 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "compression": "^1.6.2", "css-loader": "^0.27.3", "debug": "^2.6.3", - "extract-text-webpack-plugin": "2.1.0", "file-loader": "^0.10.1", "fs-extra": "^2.1.2", "glob": "^7.1.1", @@ -86,6 +85,7 @@ "vue-router": "^2.3.0", "vue-server-renderer": "^2.2.4", "vue-ssr-html-stream": "^2.2.0", + "vue-ssr-webpack-plugin": "^1.0.2", "vue-template-compiler": "^2.2.4", "vuex": "^2.2.1", "webpack": "^2.2.1",