我在使用webpack搭建一个vue服务端渲染的工程,出现了一个问题,我搭建的是多页面开发环境,admin和project两个页面,当我使用webpack打包的时候vue-server-renderer中间件的createRenderer方法返回的html中自动注入了包含admin和project两个页面的js和css,不知道是为什么。麻烦给予帮助,非常感谢。
页面目录:
app.js
require("@babel/register")
const Koa = require('koa')
const Router = require('koa-router')
const { routerFile } = require('./server-utils')
const { createRenderer } = require('vue-server-renderer')
const serve = require('koa-static')
const path = require('path')
const isProd = process.env.NODE_ENV === 'production' ? 'production' : 'development'
const app = new Koa()
const router = new Router()
app.use(serve(path.join(__dirname, '/dist')))
if(isProd === 'production'){
const clientManifest = require('./dist/vue-ssr-client-manifest.json')
render(clientManifest)
}else{
const setUpDevServer = require('./build/setup-dev-server')
setUpDevServer(app, async (clientManifest) => {
render(clientManifest)
})
}
function render(clientManifest){
const entryRouter = routerFile()
entryRouter.forEach(item => {
(function(item){
const server = require(item.appFlile)
router.get(`/${item.router}`, async ctx => {
const { app, template } = await server.default(ctx)
const renderer = createRenderer({
runInNewContext: false,
clientManifest,
template
})
const html = await renderer.renderToString(app, {})
ctx.body = html
})
})(item)
})
}
app.use(router.routes()).use(router.allowedMethods())
app.listen(8080)
server-utils.js
const glob = require('glob')
const path = require('path')
function routerFile(){
const file = path.resolve(__dirname, `pages/*`)
const entryObject = glob.sync(file).reduce((entries, entry) => {
let basename = path.basename(entry)
const appFlile = `./dist/${basename}-server-bundle.js`
if(basename.indexOf('.')){
basename = basename.replace(/\./g, '/')
}
entries.push({
router: basename,
appFlile
})
return entries;
}, [])
return entryObject
}
module.exports = {
routerFile
}
setup-dev-server.js
const webpack = require('webpack')
const koa2Connect = require('koa2-connect');
const webpackDevMiddleware = require("webpack-dev-middleware")
const webpackHotMiddleware = require("webpack-hot-middleware")
const webpackConf = require('./webpack.base.conf')
const webpackClientConf = require('./webpack.client.conf')
const webpackServerConf = require('./webpack.server.conf')
const path = require('path')
const readFile = (fs, file) => {
try {
return fs.readFileSync(path.join(webpackConf.output.path, file), 'utf-8')
} catch (e) {
console.log("[readFile]", e)
}
}
module.exports = async function setupDevServer(app, cb){
const compilerClient = webpack(webpackClientConf)
const compilerServer = webpack(webpackServerConf)
const devMiddleware = webpackDevMiddleware(compilerClient, {
noInfo: true,
publicPath: webpackConf.output.publicPath,
stats: {
colors: true
}
})
app.use(koa2Connect(devMiddleware));
app.use(koa2Connect(webpackHotMiddleware(compilerClient, {
log: false,
noInfo: true,
quiet: true,
heartbeat: 10 * 1000
})));
compilerClient.hooks.done.tap('done', (stats) => {
stats = stats.toJson()
stats.errors.forEach(err => console.error(err))
stats.warnings.forEach(err => console.warn(err))
if (stats.errors.length) return
const clientManifest = JSON.parse(readFile(
devMiddleware.fileSystem,
'vue-ssr-client-manifest.json'
))
cb(clientManifest)
})
compilerServer.watch({}, (err, stats) => {
if (err) {
reject(err)
}
stats = stats.toJson()
stats.errors.forEach(err => console.error(err))
stats.warnings.forEach(err => console.warn(err))
})
}
webpack.client.conf.js
const webpack = require('webpack');
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
const { getEntryPoint } = require('./entry')
const entryObj = getEntryPoint('index')
let entry = null
if(baseWebpackConfig.mode === 'production'){
entry = entryObj
}else{
entry = Object.keys(entryObj).reduce((obj, cur) => {
const hmr = `webpack-hot-middleware/client?name=${cur}&reload=true&timeout=20000`;
obj[cur] = []
obj[cur].push(entryObj[cur], hmr)
return obj
}, {})
// 小记:hmr文件 必须和入口文件放在一起哦!
}
console.log("entry::::::::::::", entry)
const clientConf = merge(baseWebpackConfig, {
entry,
optimization: {
splitChunks: {
chunks: 'all',
minChunks: 2,
name: 'manifest'
}
},
devtool: 'source-map',
plugins: [
new VueSSRClientPlugin(),
new webpack.HotModuleReplacementPlugin()
]
})
module.exports = clientConf
webpack.server.conf.js
const path = require('path')
const merge = require('webpack-merge')
const nodeExternals = require('webpack-node-externals')
const baseConfig = require('./webpack.base.conf.js')
const { getEntryPoint } = require('./entry')
const entry = getEntryPoint('index.server')
const serverConf = merge(baseConfig, {
entry,
target: 'node',
output: {
path: path.join(__dirname, '../dist'),
filename: '[name]-server-bundle.js',
libraryTarget: 'commonjs2'
},
externals: nodeExternals({ // 不打包node_modules依赖项 whitelist 白名单
whitelist: /\.css$/
})
})
module.exports = serverConf
entry.js
const glob = require('glob')
const path = require('path')
const getEntryPoint = function(fileName){
const file = path.resolve(__dirname, `../pages/*`)
const entryObject = glob.sync(file).reduce((entries, entry) => {
const basename = path.basename(entry)
entries[basename] = `${entry}/${fileName}.js`
return entries;
}, {})
return entryObject
}
module.exports = {
getEntryPoint
}
最后我启动服务以后 通过http://localhost:8080/project访问project页面,给我返回的HTML是这样的 包含了admin的js和css
求大神给予帮助。非常非常非常感谢。