UNPKG

1.79 kBJavaScriptView Raw
1import { validate, isJS, onEmit } from './util'
2
3export default class VueSSRServerPlugin {
4 constructor (options = {}) {
5 this.options = Object.assign({
6 filename: 'vue-ssr-server-bundle.json'
7 }, options)
8 }
9
10 apply (compiler) {
11 validate(compiler)
12
13 onEmit(compiler, 'vue-server-plugin', (compilation, cb) => {
14 const stats = compilation.getStats().toJson()
15 const entryName = Object.keys(stats.entrypoints)[0]
16 const entryInfo = stats.entrypoints[entryName]
17
18 if (!entryInfo) {
19 // #5553
20 return cb()
21 }
22
23 const entryAssets = entryInfo.assets.filter(isJS)
24
25 if (entryAssets.length > 1) {
26 throw new Error(
27 `Server-side bundle should have one single entry file. ` +
28 `Avoid using CommonsChunkPlugin in the server config.`
29 )
30 }
31
32 const entry = entryAssets[0]
33 if (!entry || typeof entry !== 'string') {
34 throw new Error(
35 `Entry "${entryName}" not found. Did you specify the correct entry option?`
36 )
37 }
38
39 const bundle = {
40 entry,
41 files: {},
42 maps: {}
43 }
44
45 stats.assets.forEach(asset => {
46 if (isJS(asset.name)) {
47 bundle.files[asset.name] = compilation.assets[asset.name].source()
48 } else if (asset.name.match(/\.js\.map$/)) {
49 bundle.maps[asset.name.replace(/\.map$/, '')] = JSON.parse(compilation.assets[asset.name].source())
50 }
51 // do not emit anything else for server
52 delete compilation.assets[asset.name]
53 })
54
55 const json = JSON.stringify(bundle, null, 2)
56 const filename = this.options.filename
57
58 compilation.assets[filename] = {
59 source: () => json,
60 size: () => json.length
61 }
62
63 cb()
64 })
65 }
66}