使用 rollup 摇树

Luo*_*ize 5 javascript rollup tree-shaking

我有一个项目,我在其中使用 Rollup(生成 bundle.esm.js 文件)捆绑了一个组件库。这些组件然后在另一个项目中使用,该项目生成使用这些组件的网页 - 每个页面使用不同的组件。问题是,整个组件库总是与不同的页面包捆绑在一起,无论我使用的是哪个组件,都不必要地增加了包的大小。

这是我的汇总设置:

import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import pkg from './package.json';

const extensions = [
  '.js', '.jsx', '.ts', '.tsx',
];
export default [
  {
    input: './src/base/index.ts',
    plugins: [
      peerDepsExternal(),
      resolve({ extensions }),
      babel({
        exclude: 'node_modules/**',
        extensions,
      }),
      commonjs(),
    ],
    output: [
      { file: pkg.main, format: 'cjs', sourcemap: true },
      { file: pkg.module, format: 'es', sourcemap: true },
    ],
    watch: {
      clearScreen: false,
    },
  },
];
Run Code Online (Sandbox Code Playgroud)

我在 webpack 中也将“模块”设置为 false。

Jua*_*dez 11

由于您不知道采用者存储库将需要组件库 (CL) 的哪些组件,因此您需要导出所有内容,但采用者可以在进行自己的构建时对您的 CL 执行树摇动(并且只需包含他们真正需要的内容)。

简而言之,你必须让你的 CL,tree-shakable。为了实现这一目标,在您的 CL 存储库上您必须:

  • 使用支持 tree-shaking 的捆绑器(rollup、webpack 等)

  • 为 es/esm 类型的模块创建构建,而不是 commonJS/cjs 等。

  • 确保没有通常用作插件的转译器/编译器(babel、tsconfig 等),将您的 ES 模块语法转换为另一种模块语法。默认情况下,流行的 Babel 预设@babel/preset-env的行为可能会违反此规则,请参阅文档了解更多详细信息。

//对我有用的babelrc.json示例

[
  "@babel/preset-env",
  {
    "targets": ">0.2%, not dead, not op_mini all"
  }
],
Run Code Online (Sandbox Code Playgroud)
  • 在代码库中,您始终必须使用import/export(no require) 语法,并仅专门导入您需要的内容。

    import arrayUtils from "array-utils";//错误的

    import { unique, implode, explode } from "array-utils";//好的

  • 在 package.json 上配置sideEffects 。

    "sideEffects": ["**/*.css"], //示例1

    "sideEffects": false, //示例2

  • 不要创建单捆绑文件,但在构建过程后将文件分开(官方文档没有这么说,但这是对我有用的唯一解决方案)

// rollup.config.js示例

const config = [
    {
        input: 'src/index.ts',
        output: [
            {
                format: 'esm', // set ES modules
                dir: 'lib', // indicate not create a single-file
                preserveModules: true, // indicate not create a single-file
                preserveModulesRoot: 'src', // optional but useful to create a more plain folder structure
                sourcemap: true, //optional
            },
        ],
        ... }]
Run Code Online (Sandbox Code Playgroud)
  • 此外,您可能需要更改模块入口点,以便采用者可以直接访问您导出所有内容的正确index.js文件:

// package.json示例

   {
    ...
    "module": "lib/index.js", //set the entrypoint file
   }
Run Code Online (Sandbox Code Playgroud)

注意:请记住,tree-shaking 是由采用者存储库执行的,该存储库具有支持 tree-shaking 的构建过程(例如:CRA 存储库),并且通常 tree-shaking 仅在prod模式 ( ) 上执行,在devnpm run build模式下不执行。因此,请务必正确测试这是否有效。

  • 这个答案值得接受。干得好,胡安玛。 (2认同)

小智 9

您需要做一些事情才能从双方(构建的包和使用它的项目)获得可摇树的代码。

从您的代码片段中,我看到您没有preserveModules: true在汇总配置文件中添加标志以防止构建输出捆绑。Webpack 无法对捆绑文件进行 Treeshake仅供参考

export default {
  ...
  preserveModules: true,
  ...
}

Run Code Online (Sandbox Code Playgroud)

在使用它的项目方面,您必须sideEffectspackage.json- 阅读文档中指定以了解如何配置它们。除此之外,optimizationwebpack 中必须有,也请阅读此处的sideEffects: true文档。

希望这可以帮助!