vue
vue copied to clipboard
SSR with webpack5, run renderToString() report "cannot find module ''../js/xxx.js" when use import() to lazy load components in router configs.
Version
2.7.14
Reproduction link
Steps to reproduce
step 1: write a simple vue-router use cases:
import Vue from 'vue';
import VueRouter from "vue-router";
Vue.use(VueRouter);
export default function () {
const router = new VueRouter({
mode: 'history',
base: '/',
routes: [
{
path: '/',
redirect: '/index'
}, {
path: '/index',
component: () => import(
/* webpackChunkName: "index" */
'@/pages/index.vue'
)
}, {
path: '/about',
component: () => import(
/* webpackChunkName: "about" */
'@/pages/about.vue'
)
}],
});
return router;
}
Step 2: configuration vue.config.js for server bundle of SSR Mode:
const { defineConfig } = require('@vue/cli-service')
const nodeExternals = require('webpack-node-externals');
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin');
module.exports = defineConfig({
productionSourceMap: false,
css: {
extract: false,
},
transpileDependencies: true,
configureWebpack: {
entry: '@/enter-server.js',
target: 'node',
output: {
library: {
type: 'commonjs2'
},
libraryTarget: 'commonjs2',
},
externals: nodeExternals({
allowlist: [/\.css$/],
}),
optimization: {
splitChunks: { chunks: 'all' },
},
plugins: [
new VueSSRServerPlugin(),
],
}
})
Step 3: write a render test case:
const { createBundleRenderer } = require('vue-server-renderer');
const serverBundle = require('./dist/vue-ssr-server-bundle.json');
const createRenderer = (bundle, options = {}) => {
return createBundleRenderer(bundle, Object.assign(options, {
runInNewContext: false
}));
};
let renderer = createRenderer(serverBundle);
const ctx = {
route: { path: '/index' },
};
renderer.renderToString(ctx, (err, html) => {
if (err) {
return console.log(err);
}
console.log(html);
});
What is expected?
run command: npm run build
, and it will emit some errors:
[vue-router] Failed to resolve async component default: Error: Cannot find module '../js/index.5c9c2de1.js'
What is actually happening?
In Webpack5, when the output.target is "node". it will use the installChunk(require("../" + __webpack_require__.u(chunkId)));
to load the all async modules. and "vue-server-renderer/server-plugin
" will put all modules in .json file.
The reason it on the "../". while renderToString()
was executed.
cause cannot resolve and async components bundle with prefix ”.../“ in evaluateModule()
.
finally, i am apologize for my pool english.
same issue
try add specific filename to webpack.output, like this:
output: {
libraryTarget: "commonjs2",
filename: "server-bundle.js",
}