简体   繁体   English

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

[英]Webpack - Prevent file duplication with webpack code splitting & react-loadable

We've recently been looking at implementing code splitting into our complex web application to reduce the main bundle size. 最近,我们一直在考虑将代码拆分到我们的复杂Web应用程序中以减小主捆绑包的大小。 The main part that we're focussing on is dynamic imports using webpack & react-loadable. 我们关注的主要部分是使用webpack和react-loadable的动态导入。

I've come across something I deem to be quite a big problem, take this example: 我遇到了一些我认为是很大的问题,请举以下示例:

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>
);

where FirstChild.jsx & SecondChild.jsx both import the same service: 其中FirstChild.jsx和SecondChild.jsx都导入相同的服务:

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

When bundling this with webpack, we end up with 3 files: 将其与webpack捆绑在一起时,我们最终得到3个文件:

  • Main bundle (which includes the parent component) 主捆绑包(包括父组件)
  • FirstChild bundle (which includes MyService ) FirstChild捆绑包(包括MyService
  • SecondChild bundle (which also includes MyService ) SecondChild捆绑包(还包括MyService

At this point I see a problem - we have duplicates of MyService between both files. 此时,我看到一个问题-我们在两个文件之间都有MyService重复项。 For some small apps this might not be a problem (or if the service was specifically just helper methods) but if we're using our service to store some data across the lifetime of the app, we would end up with two object references of this service, therefore defeating it's point entirely. 对于某些小型应用程序,这可能不是问题(或者如果该服务仅是辅助方法),但是如果我们使用服务在应用程序的整个生命周期中存储一些数据,则最终会得到两个对象引用服务,因此完全没有意义。

I understand that the service here could be moved 'top-level' to the ParentComponent and possibly passed as a prop to each component but it seems like it destroys the architecture that webpack has in place in the first place - to be able to import whatever we need wherever we need and it creating just one reference. 我知道这里的服务可以“顶层”移动到ParentComponent并可能作为道具传递给每个组件,但似乎它破坏了webpack最初的架构-能够导入任何内容我们需要我们所需要的任何地方,它仅创建一个参考。 It also could be problematic if you have lots of nested components which all need to import various services and other components. 如果您有很多嵌套的组件,而这些组件都需要导入各种服务和其他组件,那么这也可能会带来问题。

Obviously this example is simple but implementing this into a massive app which has a very complex architecture could immediately run us into problems. 显然,该示例很简单,但是将其实现为具有复杂架构的大型应用程序可能会立即使我们陷入困境。

Any thoughts on this? 有什么想法吗? Thanks! 谢谢!

Going to answer my own question on this one. 要回答我关于这个问题的问题。

Discovered that: 发现:

  • It doesn't matter that MyService.js ends up in the output of each chunk. MyService.js最终出现在每个块的输出中都没关系。 Webpack is clever enough to only load the first instance of MyService that it finds and uses just one reference for that. Webpack非常聪明,仅加载它找到的MyService的第一个实例,并仅为此使用一个引用。 Meaning that if FirstChild loads MyService first, then SecondChild will also use the same MyService that was loaded by FirstChild and it's copy of MyService will just be ignored. 这意味着,如果FirstChild负荷MyService ,然后再SecondChild也将采用相同MyService ,是由加载FirstChild和它的副本MyService只会被忽略。
  • Files imports inside dynamic imports can be split manually by adding small Webpack config & regex filename matching (thanks @AndriiGolubenko for pointing me in the right direction), we just end up with strange folder structures & file names. 可以通过添加小的Webpack配置和regex文件名匹配来手动拆分动态导入中的文件导入(感谢@AndriiGolubenko指出正确的方向),我们最终得到的是奇怪的文件夹结构和文件名。 For eg the code for MyService.js in this case might end up in a chunk like services~FirstChild/SecondChild/SecondChild.js - which doesn't make very nice for debugging but I assume it's the way Webpack references it's imports. 例如,在这种情况下, MyService.js的代码可能会以大块结尾,例如services~FirstChild/SecondChild/SecondChild.js调试起来不太好,但我认为这是Webpack引用导入的方式。

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

Please let me know if any of that is wrong or you find other interesting points about code splitting + webpack. 如果有任何错误,请让我知道,或者您发现有关代码拆分+ Webpack的其他有趣之处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM