Webpack 根据 chunk 加载不同的模块

Posted

技术标签:

【中文标题】Webpack 根据 chunk 加载不同的模块【英文标题】:Webpack load different modules based on chunk 【发布时间】:2019-11-03 13:49:22 【问题描述】:

是否可以让 webpack 根据一些上下文信息加载另一个模块?

例如,我的 React 应用程序有两个版本:桌面版和移动版

在我的 index.js 中,我决定加载哪个应用程序:

if (isMobile()) 
   loadMobile().then((default: App) => render(App))

现在我想重用一些模块,但有些我想覆盖它。所以默认情况下它应该加载 index.js,但是如果上下文 isMobileindex.js 旁边存在一个 mobile.js 文件,它应该加载 mobile 变体。

components/
  Button/
    index.js
    mobile.js

在移动环境中,webpack 应该加载 mobile.js 而不是 index.js

我找不到任何可以用来解决它的东西,有什么想法吗?


PS:我已经在 github 上创建了一个 issue,它也展示了这个问题以及我想要更好地实现的目标:

https://github.com/webpack/enhanced-resolve/issues/180

【问题讨论】:

【参考方案1】:

您可以使用动态加载功能和动态导入语法来解决这个问题。

    安装 Babel 插件plugin-syntax-dynamic-import:

    npm install --save-dev @babel/plugin-syntax-dynamic-import
    

    并在.babelrc中使用它

    
      "plugins": ["@babel/plugin-syntax-dynamic-import"]
    
    

    您需要创建一个名为load 的组件,其内容如下 代码:

        export default const load = (platform="index") => componentName => 
        import(`components/$componentName/$platform.js`);
    

    然后使用带有加载功能的动态导入,如下所示 代码:

        const  Button  = await import("components/Loader.jsx").then(load => 
          load($platform)($componentName)
        )
    

这些文章可能会对您有所帮助:

https://medium.com/front-end-weekly/webpack-and-dynamic-imports-doing-it-right-72549ff49234

https://blog.jscrambler.com/how-to-make-your-app-faster-with-webpack-dynamic-imports/

https://webpack.js.org/guides/code-splitting/#dynamic-imports

【讨论】:

感谢您努力写下来,但它没有回答我最初的问题。这种方法的问题是所有模块都是动态加载的,所以你必须使用 Promises。我最初的问题已经在使用动态加载方法,我只是在寻找一种将 mobile.js 文件而不是 index.js 包含到 mobile.bundle.js 和默认(index.js)文件到 desktop.bundle.js 好的,这篇文章怎么样:remarkablemark.org/blog/2017/02/25/webpack-ignore-module。这个可以解决这个问题。您将拥有 2 个构建,在每个构建上,您都可以删除不必要的一个。 这正是我想要避免的。【参考方案2】:

有两种不同的方法可以实现这一目标。

    为移动设备和桌面设备分别创建 2 个入口点 1,以便 webpack 生成 2 个包。您只能从 html 加载所需的包。 如果你 require/importloadMobile() 中的 Mobile 代码,webpack 会自动将代码拆分为 2 个包。仅在必要时才加载移动捆绑包。

【讨论】:

【参考方案3】:

我猜你必须创建两个构建:一个使用默认 resolve.mainFiles,一个使用

resolve: 
    mainFiles: ['mobile', 'index']

您需要决定在 html 中加载哪个包。或者创建两个不同的 html 文件并将 isMobile 逻辑移动到网络服务器配置,以便它决定返回哪个 html 给用户。

两个版本之间的某些块可能相同。但很有可能你最终会得到两个不同的应用程序。您可以使用DllPlugin 减少两个应用程序之间的构建代码重复。

【讨论】:

以上是关于Webpack 根据 chunk 加载不同的模块的主要内容,如果未能解决你的问题,请参考以下文章

定位解析一个因脚本劫持导致webpack动态加载异常的问题

webpack配置之代码优化

webpack分片chunk加载原理

webpack原理篇(五十六):webpack流程:模块构建和chunk生成阶段

Webpack CommonsChunkPlugin 理解

webpack常见问题