Webpack代码拆分为异步加载库中的组件

时间:2018-01-11 20:22:50

标签: reactjs webpack

我们开发了一个供内部使用的React组件库。该库使用webpack将所有内容捆绑到bundle.js中。该库作为NPM模块公开,供我们的应用程序使用,到目前为止,它已经运行良好。

最近我们添加了一个Grid组件,它具有一些非常大的外部依赖关系。尽管我们的一些应用程序不需要库中的这个组件,但我们决定将它包含在最终的包中。这可以使包大小产生巨大差异,因此我遵循Webpack的code splitting guide来使用动态导入来打破Grid组件。对于将此库安装为NPM模块的应用程序,组件库包现在在node_modules中显示如下:

├── node_modules/                 
│   ├── [our component library]/                 
│   │   ├── Grid.js # Asynchronously loaded Grid component
│   │   ├── bundle.js # Main bundle
│   │   └── ... other files in component library bundle

在构建应用程序时(也使用Webpack),Grid组件似乎不会作为自己的文件包含在最终的包中。事实上,它并没有包括在内:

├── dist/                 
│   ├── main.js # App bundle
│   ├── vendor.js # Vendor bundle created with CommonChunksPlugin
│   └── ... other files in application bundle but no Grid.js

当尝试在使用异步加载的Grid组件的浏览器中加载页面时,Webpack会返回以下错误:

Error: Loading chunk 0 failed.
  at HTMLScriptElement.onScriptComplete (bundle.js:757)

基本上,这表示无法找到网格组件块。我究竟做错了什么?甚至可以像这样编译拆分React组件库吗?

3 个答案:

答案 0 :(得分:0)

我使用https://webpack.js.org/guides/code-splitting/#dynamic-imports import()和require.ensure语法进行动态导入。两者都运作良好。检查我的这个项目是好例子https://github.com/croraf/myboiler

这个项目也是一个例子:https://github.com/croraf/nutrients-calculator。但我复杂的动态导入部分。检查https://github.com/croraf/nutrients-calculator/blob/master/frontend/src/App.jshttps://github.com/croraf/nutrients-calculator/blob/master/frontend/src/routes/util/DynamicRoute.js个文件。

答案 1 :(得分:0)

我们决定采取不同的方式。我们将其拆分为自己的npm模块,而不是将Grid组件包含在其余的组件中。我仍然看到动态导入库中的反应组件的用例,但我们认为这是解决我们问题的更好方法。有了这个解决方案,唯一真正的缺点是,如果需要使用Grid组件和我们的标准组件库,应用程序现在需要添加2 npm模块而不是一个。由于我们的应用程序使用webpack +动态导入进行路由代码分割,因此Grid代码仅捆绑到需要它的路由中。

答案 2 :(得分:0)

一个可能的原因是 babel 将您的代码从 import("..") 转译为 require。检查转译的文件以确认这一点。 如果是这种情况并且您正在使用 preset,您可以添加它以禁用此行为:

  "@babel/preset-env",
  {
    **"modules": false,**
    "targets": {
      "esmodules": true
    }
  }
],