mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-16 19:04:48 +00:00
82 lines
2.2 KiB
TypeScript
82 lines
2.2 KiB
TypeScript
|
|
import { Compilation } from 'webpack'
|
|
import { validate, isJS, extractQueryPartJS } from './util'
|
|
|
|
export default class VueSSRServerPlugin {
|
|
options: {
|
|
filename?: string
|
|
}
|
|
|
|
constructor (options = {}) {
|
|
this.options = Object.assign({
|
|
filename: null
|
|
}, options)
|
|
}
|
|
|
|
apply (compiler) {
|
|
validate(compiler)
|
|
compiler.hooks.make.tap('VueSSRServerPlugin', (compilation: any) => {
|
|
compilation.hooks.processAssets.tapAsync({
|
|
name: 'VueSSRServerPlugin',
|
|
stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
|
|
}, (assets, cb) => {
|
|
const stats = compilation.getStats().toJson()
|
|
const [entryName] = Object.keys(stats.entrypoints)
|
|
const entryInfo = stats.entrypoints[entryName]
|
|
|
|
if (!entryInfo) {
|
|
// #5553
|
|
return cb()
|
|
}
|
|
|
|
const entryAssets = entryInfo.assets.filter(asset => isJS(asset.name))
|
|
|
|
if (entryAssets.length > 1) {
|
|
throw new Error(
|
|
'Server-side bundle should have one single entry file. ' +
|
|
'Avoid using CommonsChunkPlugin in the server config.'
|
|
)
|
|
}
|
|
|
|
const [entry] = entryAssets
|
|
if (!entry || typeof entry.name !== 'string') {
|
|
throw new Error(
|
|
`Entry "${entryName}" not found. Did you specify the correct entry option?`
|
|
)
|
|
}
|
|
|
|
const bundle = {
|
|
entry: entry.name,
|
|
files: {},
|
|
maps: {}
|
|
}
|
|
|
|
stats.assets.forEach((asset) => {
|
|
if (isJS(asset.name)) {
|
|
const queryPart = extractQueryPartJS(asset.name)
|
|
if (queryPart !== undefined) {
|
|
bundle.files[asset.name] = asset.name.replace(queryPart, '')
|
|
} else {
|
|
bundle.files[asset.name] = asset.name
|
|
}
|
|
} else if (asset.name.match(/\.js\.map$/)) {
|
|
bundle.maps[asset.name.replace(/\.map$/, '')] = asset.name
|
|
} else {
|
|
// Do not emit non-js assets for server
|
|
delete assets[asset.name]
|
|
}
|
|
})
|
|
|
|
const src = JSON.stringify(bundle, null, 2)
|
|
|
|
assets[this.options.filename] = {
|
|
source: () => src,
|
|
size: () => src.length
|
|
}
|
|
|
|
cb()
|
|
})
|
|
})
|
|
}
|
|
}
|