You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack代码分割后页面无内容:Chunk未加载问题排查

解决Webpack代码分割后React应用无法加载的问题

我折腾了一整天才搞定这个坑:本来想通过Webpack把单一的bundle.js拆分成多个chunk优化加载速度,结果拆分后React应用完全不显示,控制台只提示index.ejs已经正常加载,但页面就是空白。之前用单个bundle.js的时候一切都好好的,当时index.ejs里直接用<script src="/views/bundle.js"></script>引入脚本就行。

初始的webpack.config.js配置

module.exports = {
 devServer: { historyApiFallback: true },
 entry: {
  index: ["./src/index.js"],
  vendor: [ "react", "react-dom", "react-redux", "react-router", "react-router-dom", "redux" ]
 },
 output: {
  path: __dirname + '/public/views',
  filename: "[name].js",
  publicPath: "/views/"
 },
 module: {
  loaders: [
   { test: /\.js$/, loader: "babel-loader", exclude: [/node_modules/, /pdfmake.js$/] },
   { test: /\.json$/, loader: "json-loader" }
  ]
 },
 plugins: [
  new webpack.optimize.CommonsChunkPlugin({ name: "vendor", filename: "vendor.js", minChunks: Infinity }),
  new webpack.optimize.CommonsChunkPlugin({ name: "meta", chunks: ["vendor"], filename: "meta.js" }),
  new webpack.NamedModulesPlugin(),
  new HtmlWebpackPlugin({ title: "Deals", filename: __dirname + "/views/index.ejs", template: __dirname + "/views/template.ejs", inject: false }),
  new PreloadWebpackPlugin({ rel: "preload", as: "script", include: "all" }),
  new webpack.optimize.OccurrenceOrderPlugin(),
 ]
};

生成的简化版index.ejs

可以看到,预加载的chunk标签确实生成了,但没有实际的script标签引入这些chunk文件:

<!DOCTYPE html>
<html lang="en">
<head>
 <link href="/pace.css" rel="stylesheet" />
 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=yes">
 <meta charset="utf-8">
 <link rel="stylesheet" href="/style.css">
 <link rel="canonical" href="http://verygoodprof.fr/" />
 <link rel="preload" as="script" href="/views/index.js">
 <link rel="preload" as="script" href="/views/vendor.js">
 <link rel="preload" as="script" href="/views/meta.js">
</head>
<body>
 <noscript>
  <a href="http://enable-javascript.com/">Javascript must me enabled to use this site.</a>
 </noscript>
 <div class="text-center root" id="root">
 </div>
</body>
</html>

修改后的webpack.config.js配置(已解决问题)

感谢@margaretkru的指点,调整后的配置如下:

module.exports = {
 devServer: { historyApiFallback: true },
 entry: {
  app:"./src/index.js",
  vendor: [ "axios", "jquery", "react", "react-dom", "react-redux", "react-router", "react-router-dom", "redux" ]
 },
 output: {
  path: __dirname + '/public/views',
  filename: "[name].js",
  publicPath: "/views/"
 },
 module: {
  loaders: [
   { test: /\.js$/, loader: "babel-loader", exclude: [/node_modules/, /pdfmake.js$/] },
   { test: /\.json$/, loader: "json-loader" }
  ]
 },
 plugins: [
  new webpack.NamedModulesPlugin(),
  new HtmlWebpackPlugin({ filename: __dirname + "/views/index.ejs", template: __dirname + "/views/template.ejs", inject: 'body', chunks: ['vendor', 'app'], chunksSortMode: 'manual' }),
  new PreloadWebpackPlugin({ rel: "preload", include: ["vendor", "app"] }),
  new webpack.optimize.OccurrenceOrderPlugin(),
  new webpack.optimize.CommonsChunkPlugin({ name: "vendor", minChunks: Infinity })
 ]
};

核心问题分析

一开始我以为是脚本加载顺序的问题,但实际上关键在于:只通过PreloadWebpackPlugin添加了预加载标签,但没有让HtmlWebpackPlugin自动注入实际的script标签。

把HtmlWebpackPlugin的inject参数从false改为'body',同时指定chunks: ['vendor', 'app']和chunksSortMode: 'manual'后,插件会自动在index.ejs的body末尾注入<script src="/views/vendor.js"></script>和<script src="/views/app.js"></script>标签,浏览器才会真正加载并执行这些chunk文件,React应用也就正常显示了。

内容的提问来源于stack exchange,提问作者Louis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:31:24