【问题标题】:webpack code de-duplication not working when using splitChunks cacheGroups commons使用 splitChunks cacheGroups commons 时 webpack 代码重复数据删除不起作用
【发布时间】:2019-02-09 01:00:17
【问题描述】:

我有一个 lerna 项目,其中包含两个相同的包(名为 p1 和 p2)

p1 和 p2 都包含一个 3rd 方包——对于这个测试,我使用了 eosjs@beta,大约 50KB

如果我随后创建一个示例 react 项目并包含 P1,包大小按预期增长了 50KB,但令我惊讶的是,当我添加 p2 时……它又增长了 50KB。

人们会认为因为 p1 和 p2 使用相同的第 3 方库,所以对该库的一个引用将被编译到示例项目中。但事实并非如此。

此处的示例回购:https://github.com/warrick-eosny/sizetest

包的增长如下:

ls 示例/sizetest/build/static/js/ -lah

在我引用 p1 之前

    117K 1.13eeb203.chunk.js     
    1.4K main.2170ea98.chunk.js  
    1.5K runtime~main.229c360f.js  

引用p1后

    165K 1.75baab58.chunk.js  
    3.7K main.36960386.chunk.js  
    1.5K runtime~main.229c360f.js  

引用 p1 和 p2 后

    212K 1.57bb37cb.chunk.js  
    6.4K main.491260eb.chunk.js  
    1.5K runtime~main.229c360f.js  

示例文件夹中的项目是使用以下工具创建的:

npx create-react-app sizetest –typescript

p1 和 p2 包都是使用以下工具创建的:

哟节点打字稿-webpack

为什么示例构建不断增长.. surly webpack 足够聪明,只包含一个引用。

=============== 更新==================

这里的“删除重复代码”部分似乎应该可以解决我的问题: https://developers.google.com/web/fundamentals/performance/optimizing-javascript/code-splitting/#spitting_code_by_multiple_entry_points

但这似乎并没有。

  1. 我在项目文件夹中运行“纱线弹出”,然后添加了建议的配置:https://github.com/warrick-eosny/sizetest/blob/master/examples/sizetest/config/webpack.config.js#L196-L211
  2. 删除了丑陋的部分,以便输出可读
  3. 再次运行构建

这确实会生成一个公共文件,但是当您查看内容时:

grep \@module build/static/js/commons.bd2f73cb.chunk.js

可以看到代码还在重复中

 * @module Serialize
 * @module Numeric
 * @module RPC-Error
 * @module Serialize
 * @module Numeric
 * @module RPC-Error
 * @module API
 * @module JSON-RPC
 * @module API
 * @module JSON-RPC

【问题讨论】:

    标签: javascript npm webpack lerna


    【解决方案1】:

    作为一个概念的 monorepo 和作为一个工具的 Lerna 都不是为了做这种隐含的“改进”。这可能会产生不必要的副作用(例如,如果 P1 和 P2 依赖于不同版本的 eosjs,或者每个包都启动某个包类的自己的实例)。

    反对做你所期望的另一个原因是,monorepo 中的包仍然可以彼此独立部署,因为它们不依赖于包的相同引用。

    据我所知,使用 monorepo 是实现您所需的唯一方法。然而,monorepo 只是在一个地方管理你的代码库。如果您想在两个包中使用相同的 eosjs 引用,请将其移至根级别 package.json,但是您还必须处理一些您可能还没有预料到的其他问题。您可以手动为您自己维护的 monorepo 包执行此操作,或通过提升外部包与 Lerna:https://github.com/lerna/lerna/blob/master/doc/hoist.md

    Yarn Workspaces 是 Lerna 在引擎盖下用来实现提升的,也可能有助于理解。

    Webpack 不知道在 monorepo 中,除非你也以某种方式告诉它。它独立于 Lerna 或 monorepos 工作。

    【讨论】:

    • 当然,但是让我们删除它是一个使用 lerna 的 monorepo 的事实,并说我只是包含了两个使用相同包和版本的 npm 包。能够删除重复项似乎是相当不错的优化。
    • @WarrickFitzGerald Webpack 的链接资源不涵盖您的情况,它旨在防止在您使用代码拆分时在单个包中出现代码重复(例如,如果您想延迟加载网站的某些部分)仅当用户请求命名部分而不是一次加载整个块时。然后您可以防止 Webpack 捆绑一个公共包以打包在每个较小的块中)。你的情况不同。正如我在回答中已经说过的,它仍然可以在 monorepo 和 Lerna 中使用,方法是将通用包移动到根级别 package.json
    • 除此之外,如果你删除了 monorepo 或 lerna 的事实,就没有办法使用公共节点包的单个引用(webpack 应该如何知道哪个引用成为“master”参考,还是应该自行提升?)。如果外部节点packageA 有另一个packageB 作为依赖项,您应该告诉packageA 的维护者,将packageB 移动到peerDependencies 可能是个好主意,这样您就可以将它包含在您的主项目中package.json 一次性解决。
    • 谢谢,经过大量实验,我能够证实您对此的想法。我创建了一个更简单的示例,以防其他人想要一个简单的测试台。 github.com/warrick-eosny/sizetest-hoist
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    相关资源
    最近更新 更多