Webpack-通过webpack代码拆分和react-loadable防止文件重复

时间:2019-05-08 14:07:15

标签: reactjs webpack dynamic-loading code-splitting react-loadable

我们最近一直在考虑在复杂的Web应用程序中实现code splitting,以减小主捆绑包的大小。我们关注的主要部分是使用webpack和react-loadable的动态导入。

我遇到了一个我认为是一个很大的问题,举个例子:

const FirstChild = Loadable({
    loader: () => import('some/file/path/FirstChild.jsx') 
});
const SecondChild = Loadable({
    loader: () => import('some/file/path/SecondChild.jsx') 
});
const ParentComponent = () => (
    <div>
        <FirstChild />
        <SecondChild />
    </div>
);

其中FirstChild.jsx和SecondChild.jsx都导入相同的服务:

import MyService from 'some/file/path/my.service.js';

将其与webpack捆绑在一起时,我们最终得到3个文件:

  • 主捆绑包(包括父组件)
  • FirstChild捆绑包(其中包括MyService
  • SecondChild捆绑包(还包括MyService

这时我看到一个问题-两个文件之间有MyService的重复项。对于某些小型应用程序,这可能不是问题(或者如果该服务仅是辅助方法),但是如果我们使用服务在应用程序的整个生命周期中存储一些数据,则最终会得到两个对象引用服务,因此完全没有意义。

我知道这里的服务可能会被“顶级”移动到ParentComponent并可能作为道具传递给每个组件,但似乎破坏了webpack最初的架构-能够在任何需要的地方导入我们需要的任何东西,并且仅创建一个引用。如果您有很多嵌套的组件,而这些组件都需要导入各种服务和其他组件,那么这也可能会引起问题。

显然,该示例很简单,但是将其实现为具有复杂架构的大型应用程序可能会立即使我们陷入问题。

对此有何想法?谢谢!

1 个答案:

答案 0 :(得分:0)

要回答我关于这个问题的问题。

发现:

  • MyService.js最终出现在每个块的输出中都没关系。 Webpack非常聪明,仅加载它发现的MyService的第一个实例,并为此仅使用一个引用。意味着如果FirstChild首先加载MyService,那么SecondChild还将使用MyService加载的相同FirstChild,它是MyService的副本只会被忽略。
  • 动态导入中的文件导入可以通过添加小的Webpack配置和regex文件名匹配来手动拆分(感谢@AndriiGolubenko指出正确的方向),我们最终得到的是奇怪的文件夹结构和文件名。例如,在这种情况下,MyService.js的代码可能会以services~FirstChild/SecondChild/SecondChild.js之类的代码结尾-调试起来不太好,但我认为这是Webpack引用导入的方式。

    optimization: {
        splitChunks: {
           cacheGroups: {
                services: {
                    test: /\.service.js$/,
                    enforce: true
                }
            }
        }
    },

请让我知道是否有任何错误,或者您发现有关代码拆分+ Webpack的其他有趣观点。