【问题标题】:Why doesn't Rollup.js treeshake my library为什么 Rollup.js 不摇动我的库
【发布时间】:2017-05-17 20:15:45
【问题描述】:

我有一个实用程序库:goodcore 我在另一个项目中使用。它工作正常,但是当我使用Rollup 捆绑和treeshake 它时,它总是包含整个goodcore 库,即使我只使用它的一小部分没有链接到某些包含的文件。

两个项目都是 Typescript 并使用 ES2015 模块加载。

我使用以下方式引用了 goodcore 库:

import { Arr, Pool, Range2, Timer, Util, Vec2 } from "goodcore";

goodcore 中的 index.js 看起来像:

export { Vec2 as Vec2 } from "./struct/Vec2";
export { Range2 as Range2 } from "./struct/Range2";
export { Rect as Rect } from "./struct/Rect";
export { List as List } from "./struct/List";
export { Dictionary as Dictionary } from "./struct/Dictionary";
export { Stack as Stack } from "./struct/Stack";
export { Tree as Tree } from "./struct/Tree";
export { Calc as Calc } from "./Calc";
export { Dom as Dom } from "./Dom";
export { Arr as Arr } from "./Arr";
export { Obj as Obj } from "./Obj";
export { Util as Util } from "./Util";
export { Timer as Timer } from "./Timer";
export { Uri as Uri } from "./Uri";
export { Poolable as Poolable } from "./standard/mixins/Poolable";
export { Initable as Initable } from "./standard/mixins/Initable";
export { Pool as Pool } from "./standard/Pool";
export { Integrate as Integrate } from "./Integration";
export { MocData as MocData } from "./MocData";
export { Cache as Cache } from "./standard/Cache";
export { KeyValuePair as KeyValuePair } from "./struct/KeyValuePair";
//# sourceMappingURL=index.js.map

我最终还是得到了来自 goodcore 的所有东西,比如 Tree,包含在我的另一个项目的汇总构建中,而我的印象是 treeshaking 应该删除未使用/引用的东西。

另一个项目的汇总配置如下所示:

var packageJson = require("./package.json");
import resolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';
export default {
    entry: 'src/lib/index.ts',
    targets: [
            { dest: 'dist/' + packageJson.name + '.umd.js', format: 'umd' },
            { dest: 'dist/' + packageJson.name + '.es.js', format: 'es' },
            { dest: 'dist/' + packageJson.name + '.iife.js', format: 'iife' }
    ],
    moduleName: packageJson.name,
    external: ['ts-md5/dist/md5'],
    sourceMap: true,
    globals: {
    },
    treeshake: true,
    plugins: [
        typescript({
            typescript: require('typescript')
        }),
        resolve({ module: true, jsnext: false, main: true, modulesOnly: true })
    ]
}

我做错了什么?

【问题讨论】:

    标签: typescript rollupjs tree-shaking


    【解决方案1】:

    为确保正确性,Rollup 将包含任何看起来可能有副作用的代码——举个简单的例子,即使foo 没有,这个包也会导致 'hello from foo.js' 被记录由main.js导入:

    /*--- main.js ---*/
    import './foo.js';
    
    /*--- foo.js  ---*/
    export function unused () {
      // this will be omitted...
    }
    
    // but this will be included, because it has an effect on the world
    console.log('hello from foo.js');
    

    在 goodcore 的情况下,一切在 Rollup 看来,好像它可能有副作用。例如,Calc 是调用_Calc() 的结果,并且由于很难确定_Calc() 是否有效果,因此无论捆绑包是否使用Calc,都必须包含它。你可以see this in the REPL

    不幸的是,使此代码可摇晃可能会涉及对设计进行相当大的更改。 TypeScript 也有可能引入了不可摇树结构。

    【讨论】:

    • 哦,谢谢!我可以删除 _Calc 的东西,因为它只能在注入 iframe 等时将其用作工厂。经过一些测试后,我注意到它不仅是 _Calc,而且还有它的静态属性。这意味着我必须删除对 Calc 的分配以及所有静态函数。 :( 有解决办法吗?
    • 是的——不要将定义包装在 IIFE 中(see gist——不幸的是,我不会让我直接链接到 REPL)。问题在于 TypeScript 生成的代码,这就是我所说的“不可摇树结构”。
    • 供未来用户使用。它可以通过严格避免任何类中的静态属性或函数来解决。如果您需要它作为一种全局变量,而不是将该状态放入一个单独的类中,则该类将始终包含在内,但其余部分可用于 treeshakeable。
    猜你喜欢
    • 2020-05-15
    • 2022-11-12
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    相关资源
    最近更新 更多