From ac151a41f0ec58e2b50425ab0eaa7b65fe81f708 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 27 Apr 2017 15:50:43 +0430 Subject: [PATCH] Basic vue-server-renderer/client-plugin integration --- lib/build.js | 60 +++++++++++++++++++++++------------- lib/webpack/client.config.js | 5 +++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/lib/build.js b/lib/build.js index 7316939ed7..fdbe87637d 100644 --- a/lib/build.js +++ b/lib/build.js @@ -101,9 +101,11 @@ export function options () { } const serverConfig = getWebpackServerConfig.call(this) 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') - createRenderer.call(this, JSON.parse(bundle)) + const manifest = fs.readFileSync(manifestPath, 'utf8') + createRenderer.call(this, JSON.parse(bundle), JSON.parse(manifest)) addAppTemplate.call(this) } } @@ -137,15 +139,13 @@ export function * build () { function * buildFiles () { if (this.dev) { debug('Adding webpack middleware...') - createWebpackMiddleware.call(this) - webpackWatchAndUpdate.call(this) + const clientCompiler = createWebpackMiddleware.call(this) + webpackWatchAndUpdate.call(this, clientCompiler) watchPages.call(this) } else { debug('Building files...') - yield [ - webpackRunClient.call(this), - webpackRunServer.call(this) - ] + yield webpackRunClient.call(this) + yield webpackRunServer.call(this) addAppTemplate.call(this) } } @@ -407,19 +407,34 @@ function createWebpackMiddleware () { }) } }) + return clientCompiler } -function webpackWatchAndUpdate () { +function webpackWatchAndUpdate (clientCompiler) { const MFS = require('memory-fs') // <- dependencies of webpack - const mfs = new MFS() + const serverFS = new MFS() + const clientFS = clientCompiler.outputFileSystem const serverConfig = getWebpackServerConfig.call(this) const serverCompiler = webpack(serverConfig) - const outputPath = join(serverConfig.output.path, 'server-bundle.json') - serverCompiler.outputFileSystem = mfs - this.webpackServerWatcher = serverCompiler.watch(this.options.watchers.webpack, (err) => { + const bundlePath = join(serverConfig.output.path, 'server-bundle.json') + const manifestPath = join(serverConfig.output.path, 'client-manifest.json') + serverCompiler.outputFileSystem = serverFS + const watchHandler = (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, 'utf-8') + const manifest = clientFS.readFileSync(manifestPath, 'utf-8') + createRenderer.call(this, JSON.parse(bundle), JSON.parse(manifest)) + } + } + this.webpackServerWatcher = serverCompiler.watch(this.options.watchers.webpack, watchHandler) + this.webpackClientWatcher = clientCompiler.watch(this.options.watchers.webpack, watchHandler) } function webpackRunClient () { @@ -444,16 +459,18 @@ function webpackRunServer () { 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, 'server-bundle.json') + const manifestPath = join(serverConfig.output.path, 'client-manifest.json') readFile(bundlePath, 'utf8') - .then((bundle) => { - createRenderer.call(this, JSON.parse(bundle)) - resolve() - }) + .then((bundle) => readFile(manifestPath, 'utf8') + .then(manifest => { + 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 let cacheConfig = false if (this.options.cache) { @@ -464,7 +481,8 @@ function createRenderer (bundle) { })) } this.renderer = createBundleRenderer(bundle, { - cache: cacheConfig + cache: cacheConfig, + clientManifest: manifest }) this.renderToString = pify(this.renderer.renderToString) this.renderToStream = this.renderer.renderToStream diff --git a/lib/webpack/client.config.js b/lib/webpack/client.config.js index c2e53b90a5..92380ad483 100644 --- a/lib/webpack/client.config.js +++ b/lib/webpack/client.config.js @@ -2,6 +2,7 @@ import { each, defaults } from 'lodash' import webpack from 'webpack' +import VueSSRClientPlugin from 'vue-server-renderer/client-plugin' import HTMLPlugin from 'html-webpack-plugin' import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin' import ScriptExtHtmlWebpackPlugin from 'script-ext-html-webpack-plugin' @@ -45,6 +46,9 @@ export default function () { }) // Webpack plugins config.plugins = (config.plugins || []).concat([ + new VueSSRClientPlugin({ + filename: 'client-manifest.json' + }), // Strip comments in Vue code new webpack.DefinePlugin(Object.assign(env, { 'process.env.NODE_ENV': JSON.stringify(this.dev ? 'development' : 'production'), @@ -61,6 +65,7 @@ export default function () { // Extract manifest new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', + minChunks: Infinity, filename: this.options.build.filenames.manifest }), // Generate output HTML