Skip to content

Commit 402e109

Browse files
committed
update setup to leverage client preloading
1 parent 1c85abc commit 402e109

File tree

7 files changed

+47
-138
lines changed

7 files changed

+47
-138
lines changed

build/setup-dev-server.js

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ const clientConfig = require('./webpack.client.config')
55
const serverConfig = require('./webpack.server.config')
66

77
module.exports = function setupDevServer (app, cb) {
8-
let bundle
9-
let template
8+
let bundle, template, serverManifest, clientManifest
109

1110
// modify client config to work with hot middleware
1211
clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app]
@@ -25,12 +24,17 @@ module.exports = function setupDevServer (app, cb) {
2524
app.use(devMiddleware)
2625
clientCompiler.plugin('done', () => {
2726
const fs = devMiddleware.fileSystem
28-
const filePath = path.join(clientConfig.output.path, 'index.html')
29-
if (fs.existsSync(filePath)) {
30-
template = fs.readFileSync(filePath, 'utf-8')
31-
if (bundle) {
32-
cb(bundle, template)
33-
}
27+
const readFile = file => fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
28+
template = readFile('index.html')
29+
clientManifest = JSON.parse(readFile('vue-ssr-manifest-client.json'))
30+
if (bundle && serverManifest) {
31+
cb(bundle, {
32+
template,
33+
manifest: {
34+
server: serverManifest,
35+
client: clientManifest
36+
}
37+
})
3438
}
3539
})
3640

@@ -46,12 +50,19 @@ module.exports = function setupDevServer (app, cb) {
4650
stats = stats.toJson()
4751
stats.errors.forEach(err => console.error(err))
4852
stats.warnings.forEach(err => console.warn(err))
53+
const readFile = file => mfs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
4954

5055
// read bundle generated by vue-ssr-webpack-plugin
51-
const bundlePath = path.join(serverConfig.output.path, 'vue-ssr-bundle.json')
52-
bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8'))
53-
if (template) {
54-
cb(bundle, template)
56+
bundle = JSON.parse(readFile('vue-ssr-bundle.json'))
57+
serverManifest = JSON.parse(readFile('vue-ssr-manifest-server.json'))
58+
if (template && clientManifest) {
59+
cb(bundle, {
60+
template,
61+
manifest: {
62+
server: serverManifest,
63+
client: clientManifest
64+
}
65+
})
5566
}
5667
})
5768
}

build/webpack.client.config.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const base = require('./webpack.base.config')
44
const vueConfig = require('./vue-loader.config')
55
const HTMLPlugin = require('html-webpack-plugin')
66
const SWPrecachePlugin = require('sw-precache-webpack-plugin')
7-
const VueSSRPlugin = require('vue-ssr-webpack-plugin').client
7+
const VueSSRClientPlugin = require('vue-ssr-webpack-plugin').client
88

99
const config = merge(base, {
1010
entry: './src/entry-client.js',
@@ -36,18 +36,18 @@ const config = merge(base, {
3636
new HTMLPlugin({
3737
template: 'src/index.template.html'
3838
}),
39-
new VueSSRPlugin()
39+
new VueSSRClientPlugin()
4040
]
4141
})
4242

4343
if (process.env.NODE_ENV === 'production') {
4444
config.plugins.push(
4545
// minify JS
46-
// new webpack.optimize.UglifyJsPlugin({
47-
// compress: {
48-
// warnings: false
49-
// }
50-
// }),
46+
new webpack.optimize.UglifyJsPlugin({
47+
compress: {
48+
warnings: false
49+
}
50+
}),
5151
// auto generate service worker
5252
new SWPrecachePlugin({
5353
cacheId: 'vue-hn',

build/webpack.server.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const webpack = require('webpack')
22
const merge = require('webpack-merge')
33
const base = require('./webpack.base.config')
4-
const VueSSRPlugin = require('vue-ssr-webpack-plugin').server
4+
const VueSSRServerPlugin = require('vue-ssr-webpack-plugin').server
55

66
module.exports = merge(base, {
77
target: 'node',
@@ -22,6 +22,6 @@ module.exports = merge(base, {
2222
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
2323
'process.env.VUE_ENV': '"server"'
2424
}),
25-
new VueSSRPlugin()
25+
new VueSSRServerPlugin()
2626
]
2727
})

mapFiles.js

Lines changed: 0 additions & 64 deletions
This file was deleted.

server.js

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,16 @@ const path = require('path')
33
const express = require('express')
44
const favicon = require('serve-favicon')
55
const compression = require('compression')
6-
const createFileMapper = require('./mapFiles')
76
const resolve = file => path.resolve(__dirname, file)
87

9-
const serverStats = require('./dist/server-stats.json')
10-
const clientStats = require('./dist/client-stats.json')
11-
12-
const clientInitialFiles = []
13-
const clientAsyncFiles = []
14-
clientStats.chunks.forEach(chunk => {
15-
chunk.files.forEach(file => {
16-
if (chunk.initial) {
17-
clientInitialFiles.push(file)
18-
} else {
19-
clientAsyncFiles.push(file)
20-
}
21-
})
22-
})
23-
24-
const clientInitialFileLinks = clientInitialFiles.map(file => {
25-
return `<link rel="preload" href="/dist/${file}" as="${ /\.css$/.test(file) ? 'style' : 'script' }">`
26-
}).join('')
27-
288
const isProd = process.env.NODE_ENV === 'production'
299
const serverInfo =
3010
`express/${require('express/package.json').version} ` +
3111
`vue-server-renderer/${require('vue-server-renderer/package.json').version}`
3212

3313
const app = express()
3414

35-
let renderer, mapFiles
15+
let renderer
3616
if (isProd) {
3717
// In production: create server renderer using server bundle and index HTML
3818
// template from real fs.
@@ -41,26 +21,29 @@ if (isProd) {
4121
// src/index.template.html is processed by html-webpack-plugin to inject
4222
// build assets and output as dist/index.html.
4323
const template = fs.readFileSync(resolve('./dist/index.html'), 'utf-8')
44-
mapFiles = createFileMapper(serverStats, clientStats)
45-
renderer = createRenderer(bundle, template)
24+
renderer = createRenderer(bundle, {
25+
template,
26+
manifest: {
27+
server: require('./dist/vue-ssr-manifest-server.json'),
28+
client: require('./dist/vue-ssr-manifest-client.json')
29+
}
30+
})
4631
} else {
47-
mapFiles = () => []
4832
// In development: setup the dev server with watch and hot-reload,
4933
// and create a new renderer on bundle / index template update.
50-
require('./build/setup-dev-server')(app, (bundle, template) => {
51-
renderer = createRenderer(bundle, template)
34+
require('./build/setup-dev-server')(app, (bundle, options) => {
35+
renderer = createRenderer(bundle, options)
5236
})
5337
}
5438

55-
function createRenderer (bundle, template) {
39+
function createRenderer (bundle, options) {
5640
// https://github.com/vuejs/vue/blob/dev/packages/vue-server-renderer/README.md#why-use-bundlerenderer
57-
return require('vue-server-renderer').createBundleRenderer(bundle, {
58-
template,
41+
return require('vue-server-renderer').createBundleRenderer(bundle, Object.assign(options, {
5942
cache: require('lru-cache')({
6043
max: 1000,
6144
maxAge: 1000 * 60 * 15
6245
})
63-
})
46+
}))
6447
}
6548

6649
const serve = (path, cache) => express.static(resolve(path), {
@@ -98,27 +81,6 @@ app.get('*', (req, res) => {
9881
const context = { url: req.url }
9982
renderer.renderToStream(context)
10083
.on('error', errorHandler)
101-
.on('beforeStart', () => {
102-
// load the needed async chunk
103-
const usedFiles = Object.keys(context._evaluatedFiles)
104-
const neededFiles = mapFiles(usedFiles)
105-
context.asyncChunks = neededFiles.map(file => {
106-
return `<script src="/dist/${file}"></script>`
107-
}).join('')
108-
109-
// preload initial chunks
110-
context.head = (context.head || '') + clientInitialFileLinks
111-
112-
// prefetch async chunks
113-
const laterFiles = clientAsyncFiles.map(file => {
114-
if (neededFiles.indexOf(file) < 0) {
115-
return `<link rel="prefetch" href="/dist/${file}" as="script">`
116-
} else {
117-
return ''
118-
}
119-
}).join('')
120-
context.head += laterFiles
121-
})
12284
.on('end', () => console.log(`whole request: ${Date.now() - s}ms`))
12385
.pipe(res)
12486
})

src/entry-client.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ router.onReady(() => {
1616

1717
// service worker
1818
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
19-
// navigator.serviceWorker.register('/service-worker.js')
19+
navigator.serviceWorker.register('/service-worker.js')
2020
}

src/entry-server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default context => {
2626
// which is resolved when the action is complete and store state has been
2727
// updated.
2828
Promise.all(matchedComponents.map(component => {
29-
// return component.preFetch && component.preFetch(store)
29+
return component.preFetch && component.preFetch(store)
3030
})).then(() => {
3131
isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`)
3232
// After all preFetch hooks are resolved, our store is now

0 commit comments

Comments
 (0)