{"record":{"id":"ff8f3cb6d019f882","repo":"vuejs/vue","slug":"server-side-bundle-should-have-one-single-entry-fi","errorCode":null,"errorMessage":"Server-side bundle should have one single entry file. Avoid using CommonsChunkPlugin in the server config.","messagePattern":"Server-side bundle should have one single entry file\\. Avoid using CommonsChunkPlugin in the server config\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server-renderer/src/webpack-plugin/server.ts","lineNumber":31,"sourceCode":"\n  apply(compiler) {\n    validate(compiler)\n\n    const stage = 'PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER'\n    onEmit(compiler, 'vue-server-plugin', stage, (compilation, cb) => {\n      const stats = compilation.getStats().toJson()\n      const entryName = Object.keys(stats.entrypoints)[0]\n      const entryInfo = stats.entrypoints[entryName]\n\n      if (!entryInfo) {\n        // #5553\n        return cb()\n      }\n\n      const entryAssets = entryInfo.assets.map(getAssetName).filter(isJS)\n\n      if (entryAssets.length > 1) {\n        throw new Error(\n          `Server-side bundle should have one single entry file. ` +\n            `Avoid using CommonsChunkPlugin in the server config.`\n        )\n      }\n\n      const entry = entryAssets[0]\n      if (!entry || typeof entry !== 'string') {\n        throw new Error(\n          `Entry \"${entryName}\" not found. Did you specify the correct entry option?`\n        )\n      }\n\n      const bundle = {\n        entry,\n        files: {},\n        maps: {}\n      }\n","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/vuejs/vue/blob/9e88707940088cb1f4cd7dd210c9168a50dc347c/packages/server-renderer/src/webpack-plugin/server.ts#L13-L49","documentation":"Thrown by VueSSRServerPlugin during webpack emit when the server bundle's entry point has more than one JS asset. SSR requires a single self-contained entry file because the bundle runner evaluates one entry module; multiple chunks (e.g. a common/vendor chunk split out by CommonsChunkPlugin or splitChunks) break the direct-mode runner. The plugin filters entryInfo.assets to JS files and checks the count.","triggerScenarios":"Webpack server config uses optimization.splitChunks, CommonsChunkPlugin, or any code-splitting that produces a vendor chunk alongside the entry chunk. The entry then has 2+ JS assets after filtering, triggering the guard.","commonSituations":"Reusing the client webpack config (which has splitChunks for caching) for the server build. Adding CommonsChunkPlugin without disabling it for the server target. Webpack 5 splitChunks default config inherited into server build.","solutions":["Disable code splitting for the server build: set optimization.splitChunks = false (webpack 5) or remove CommonsChunkPlugin (webpack 4).","Use a server-specific webpack config that does not split chunks: target: 'node', output.libraryTarget: 'commonjs2'.","Externalize node_modules (externals: nodeExternals()) instead of splitting them into chunks.","Verify after rebuild that the server bundle manifest lists a single entry file."],"exampleFix":"// before — splitChunks inherited from client config\nmodule.exports = {\n  // ...\n  optimization: { splitChunks: { chunks: 'all' } }\n}\n\n// after — disable splitting for SSR\nmodule.exports = {\n  target: 'node',\n  output: { libraryTarget: 'commonjs2', filename: '[name].js' },\n  optimization: { splitChunks: false },\n  externals: require('webpack-node-externals')()\n}","handlingStrategy":"validation","validationCode":"// Validate webpack server config before running the build.\nfunction assertServerWebpackConfig(config: any): void {\n  if (config.target !== 'node') console.warn('server config target should be node')\n  if (config.optimization && config.optimization.splitChunks && config.optimization.splitChunks !== false) {\n    throw new Error(\n      'Server webpack config must disable optimization.splitChunks to avoid multiple entry assets.'\n    )\n  }\n  const commons = (config.plugins || []).find((p: any) => p.constructor && p.constructor.name === 'CommonsChunkPlugin')\n  if (commons) throw new Error('Remove CommonsChunkPlugin from the server webpack config.')\n}","typeGuard":"function serverConfigHasSingleEntry(config: any): boolean {\n  return !config.optimization?.splitChunks || config.optimization.splitChunks === false\n}","tryCatchPattern":"// The error throws during webpack emit (inside the plugin's onEmit hook).\n// Wrap the webpack build callback:\ncompiler.run((err, stats) => {\n  if (err && err.message.includes('should have one single entry file')) {\n    console.error('Fix: set optimization.splitChunks = false in the server config')\n  }\n})","preventionTips":["Maintain a separate webpack config for the server build with target: 'node' and splitChunks: false.","Externalize node_modules with webpack-node-externals instead of splitting them.","Never reuse the client webpack config verbatim for the server build.","Add a CI assertion that the emitted server bundle has exactly one JS entry asset."],"tags":["ssr","webpack","bundle","splitchunks","commonschunkplugin"],"analyzedSha":"9e88707940088cb1f4cd7dd210c9168a50dc347c","analyzedAt":"2026-08-11T22:22:01.295Z","schemaVersion":2},"datasetVersion":"2026-08-12T04:17:13.124Z"}