React代码分割:ChunkLoadError:加载块0失败

4
我正在尝试将代码拆分引入到我的项目中,但我无法使其正常工作。我收到的错误消息是:

enter image description here

我有一个单体仓库的设置,其中包含整个正在创建的react库的lib/工作区,以及一个demo/工作区,只是导入该react模块并显示它,用于测试目的。
我认为问题在于这两者如何交互以及块输出的位置或其他一些问题,但我无法弄清楚。
我的文件结构如下:

lib/webpack.config.js

var path = require('path')

module.exports = {
  entry: {
    maps: './src/index.js'
  },
  output: {
    path: __dirname + '/dist',
    filename: 'index.js',
    library: 'Map',
    libraryTarget: 'umd'
  },
  module: {
    rules: [
      {
        test: /\.[s]?css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              modules: {
                  localIdentName: "[name]__[local]___[hash:base64:5]",
                }
            }
          },
          'sass-loader'
        ],
        include: /\.module\.[s]?css$/
      },
      {
        test: /\.[s]?css$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
        exclude: /\.module\.[s]?css$/
      },
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            rootMode: 'upward'
          }
        }
      },
      {
        test: /\.svg$/,
        use: ['@svgr/webpack']
      },
      {
        test: /\.(jpe?g|png)$/i,
        loader: 'file-loader?name=/public/icons/[name].[ext]'
      }
    ]
  },
  resolve: {
    modules: [
      path.resolve(__dirname, 'src'),
      path.resolve(__dirname, '../node_modules')
    ],
    extensions: ['.js', '.jsx']
  },
  externals: {
    // Use external version of React
    react: 'react',
    'react-dom': 'react-dom'
  },
  // NOTE: @claus added options to fix files not being watched
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000
  }
}

文件夹结构

lib/ // In this project we try to use code splitting using React.Lazy()
  package.json
  webpack.config.js
demo/ // Includes the lib module for testing purposes
  package.json
babel.config.js
package.json

demo/package.json

{
  "name": "demo",
  "version": "0.1.0",
  "license": "MIT",
  "dependencies": {
    "maps": "link:../map/"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "ie 11"
    ]
  }
}

1
如果我没理解错的话,你正在lib中使用React.Lazydemo可能有自己的webpack配置。你能分享一下吗? - bamse
1
@bamse demo/ 只是配置为一个简单的 react-scripts 应用程序,没有任何自定义 Webpack 配置。我更新了我的答案,包括 demo/package.json - eivindml
当尝试加载不可用的捆绑块时,会抛出错误。我认为您的“演示”应用程序应该(并且确实)使用代码拆分。我不知道您如何将库拆分成块。您在“lib”中使用了“React.Lazy”吗? - bamse
3个回答

4

当尝试加载不可用的捆绑块时,会引发该错误。

据我了解,代码分割是用于应用程序而不是库的。

对于库使用代码分割意味着你必须将多个块作为 dist 进行传递 - 而不是像你的设置一样只传递单个文件。

    path: __dirname + '/dist',
    filename: 'index.js',

我不确定代码分割对库是否有效,或者有什么好处。
demo 中使用代码分割意味着需要的来自 lib 的部分将会被捆绑到 demo 的块中。 你需要在 demo 中使用 React.lazy ,而不是在 lib 中,并且在构建 demo 时,每个 React.lazy 都将生成一个新的包。 demo 可以访问所有 lib 的源文件(或单个文件 dist),只有需要的部分才会出现在构建的应用程序中。
我猜你在 lib 中使用了 React.lazy ,这会混淆事情。
希望能对你有所帮助!
额外问题/信息:
1.为什么需要代码分割?你的 demo 应用包太大了吗? 2.看一下 webpack 的 tree-shaking 并确保你的 lib 是可摇树的 :) 这样你就可以在 demo 中使用代码分割而不必担心 lib

你正在走上正确的道路!警告是由demo构建引起的。在demo中使用React.lazy将把1.73MiB的捆绑拆分成多个较小的捆绑。我只是想指出这是你在demo中可以控制的事情。 - bamse
Tree-shaking是Webpack为了在生产打包中仅捆绑所需的代码而执行的操作。这意味着它只会从“lib”中选择所需的部分。希望这样说得通。 - bamse
对于初学者来说,您可以忽略 tree-shaking。我认为在上下文中了解它是有意义的,但这也可能会使事情复杂化。要修复错误:请确保在“demo”中使用 React.lazy 而不是在“lib”中使用。 - bamse
看起来这个问题描述了我正在寻找的内容,但似乎不可能实现。https://github.com/webpack/webpack/issues/6818 - eivindml
1
是的!考虑到您的“lib”将用于内置应用程序中,因此您应该探索其他库目标,以便使用它的应用程序只能获取所需内容。鉴于您的情况,这可能不可行 - 有时仅仅是捆绑文件大小的问题 :) - bamse
显示剩余6条评论

0

我曾经遇到过这个问题,我的解决方案是在这个文件中进行以下更改

.erb/configs/webpack.config.renderer.prod.babel.js

更改自:

output: {
    path: path.join(__dirname, '../../src/dist'),
    publicPath: './dist/',
    filename: 'renderer.prod.js',
  },

更改为:

output: {
    path: path.join(__dirname, '../../src/dist'),
    publicPath: '../dist/',
    filename: 'renderer.prod.js',
  },

0
我花了两天的时间寻找解决方案,但我仍然不明白为什么在使用react-script库时它能正常工作。但是一旦我在一个干净的webpack上创建一个库,就会出现错误。在使用react-script时,我可以使用lazy导出组件,但在webpack中会出现错误。此外,从库中导出的内容被下划线标记(如此主题所述:Topic)。
我试图弄清楚构建过程,并检查了babel、webpack和ts的配置。我将附上我的配置,也许对某些人有帮助。

webpack.config.js

{
  mode: 'production',
  entry: path.resolve(__dirname, 'src', 'library', 'index.ts'),
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|woff|woff2)$/i,
        use: [
          {
            loader: 'file-loader',
          },
        ],
      },
      {
        test: /\.(js|jsx|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve:{
    extensions: ['.tsx', '.ts', '.js'],
    preferAbsolute: true,
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    mainFiles: ['index'],
    alias: {},
  },
  output: {
    library: {
      name: 'TestPackage',
      type: 'umd',
    },
    filename: 'index.js',
    chunkFilename: '[id].[contenthash].chunk.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  }
}

babel.config.json

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "loose": true,
        "modules": "umd"
      }
    ],
    "@babel/preset-react",
    "@babel/preset-typescript"
  ],
  "plugins": [
    "@babel/plugin-syntax-dynamic-import"
  ]
}

tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist/",
    "module": "esnext",
    "target": "es5",
    "noImplicitAny": true,
    "jsx": "react-jsx",
    "allowJs": true,
    "moduleResolution": "node",
    "baseUrl": "./",
    "paths": {
      "*": ["./src/*"]
    },
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
  },
  "ts-node": {
    "compilerOptions": {
      "module": "commonjs",
    }
  },
}

导入该库的应用程序是一个普通的react-script,没有任何设置(我认为这并不重要,该库是作为UMD构建的。
有没有解释为什么在webpack上可能无法工作,但在react-script上可以工作?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接