【问题标题】:Rollup Not Tree Shaking D3.js Correctly, Even With sideEffects Flag Set To False?Rollup 不是 Tree Shaking D3.js 正确,即使 sideEffects 标志设置为 False?
【发布时间】:2023-02-21 01:08:39
【问题描述】:

当使用 rollup v3 将我使用 D3.js v7 库的 npm 项目捆绑到 es6 模块以便在浏览器上使用时,我最终在生成的捆绑包中从 D3.js 中获得了很多额外的不必要代码。即使在 package.json 中将 sideEffects 标志设置为 false,也会发生这种情况,这似乎是几年前在这个 github 问题上讨论时解决这个问题的方法:https://github.com/d3/d3/issues/3076。虽然 treeshaking 肯定会发生,但我的包中仍然有将近 1000 行代码,仅通过导入一个函数(从 d3-selection 中选择)。

除了在 package.json 中将 sideEffects 标志设置为 false 之外,我还需要做什么吗?我也尝试在 rollup.config 中将 moduleSideEffects 设置为 false,但这似乎没有任何额外的效果。

我创建了一个非常简单的示例 npm 项目来重现该问题。它在 github 上:https://github.com/SpechtacularDave/rollupd3treeshake,或者您可以查看下面的示例输入 index.js、package.json 和 rollup.config.js(但如果您想查看输出包,请参阅 repo,因为它几乎有 1000 行长)。

// index.js
import {select} from "d3-selection";
select('#someid');
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';

export default {
    input: 'index.js',
    output: {
        file: 'index.bundle.js',
        format: 'iife'
    },
    treeshake: {
        moduleSideEffects : false
    },
    plugins: [
        resolve(),
    ],
}
// package.json
{
  "name": "rollupd3treeshake",
  "sideEffects": false,
  "version": "1.0.0",
  "type": "module",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "d3-selection": "^3.0.0"
  },
  "devDependencies": {
  "rollup": "^3.10.0",
  "@rollup/plugin-node-resolve": "^15.0.1"
}
}

任何人都可以提供任何建议,或者让我知道我是否误解了什么?谢谢。

【问题讨论】:

  • "sideEffects": false 是实现者需要添加的内容。如果你查找node_modules/d3-selection.package.json,你会找到它。我能够看到将 treeshake: { moduleSideEffects : false } 添加到我的汇总配置中的效果,但它微不足道(使用 terser 插件大约 5%)
  • 啊,谢谢你消除了我的误会。有趣的是,如果我从 d3 包中删除 sideEffects 标志条目,我会得到相同数量的输出。这似乎表明它没有影响任何东西(至少在我的简单示例中)。所以我的问题仍然存在,为什么 rollup 包括所有这些不必要的代码?
  • 当我使用 d3 时,Rollup 抱怨循环依赖。作者似乎并不关心它。即使仅在 d3-selection 中,依赖项也很难跟踪,我不会感到惊讶。

标签: npm d3.js rollupjs tree-shaking


【解决方案1】:

要回答我自己的问题,事实证明我对 treeshaking 能够完成的事情有误解。正如 github 问题上的 curran 能够向我解释的那样,treeshaking 仅使用 es6 导入和导出语句,因此它不知道我的代码是否在我实例化的选择上调用任何其他方法。所以我认为在我的示例中不必要的副作用代码实际上都是必要的。

【讨论】:

    猜你喜欢
    • 2017-10-23
    • 2021-07-28
    • 2020-01-30
    • 1970-01-01
    • 2019-09-25
    • 2018-11-01
    • 2014-08-11
    • 2015-03-13
    • 2021-12-29
    相关资源
    最近更新 更多