V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yazoox
V2EX  ›  webpack

webpack 现在依然不能自动支持 tree-shaking,来优化引入的包么?

  •  
  •   yazoox · 2021-10-29 14:42:16 +08:00 · 1406 次点击
    这是一个创建于 1124 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://www.jianshu.com/p/7994b1fc6dfe

    读到一篇文章,提到了,webpack 如果想在引入一个包的时候,编译只引入的那部分代码,需要 babel 的支持。而且,只对自己的代码有效。如果是第三方的包,还不行,得写一个插件,实现转换。比如,

    import { x } from 'module1';
    
    转换成
    
    import { x } from 'module1/a/bc';
    
    

    要这么麻烦才能够实现 tree-shaking 啊!

    当然这是 3 年前的文章了,现在的 webpack 也进化到了 5.0 的版本了吧?现在还是这样的么?

    5 条回复    2021-10-29 16:43:49 +08:00
    noe132
        1
    noe132  
       2021-10-29 15:05:31 +08:00   ❤️ 3
    你这篇文章基本已经过时了。比如现在 webpack 用的不是 uglyfy plugin ,而是 terser plugin 。

    只要你用到的库是 esm 而且 sideEffects: false ,tree shaking 就会正常工作。参考 material-ui ,代码结构就是这个文章所说的那种格式,不需要任何配置就支持 tree shaking 。

    那种 babel 转换插件是 webpack 支持 tree shaking 之前存在的优化技巧,现在完全不需要这样的东西。

    只有没有提供 esm 的库不支持 tree shaking ,比如 lodash 。这种情况你就必须手动 import 相应函数比如 'lodash/map',或者使用 babel-plugin-lodash ,更好的方法是使用 webpack alias 替换成 lodash-es 等支持 esm 的库。

    推荐阅读最新版本的官方文档
    https://webpack.js.org/guides/tree-shaking/
    wszgrcy
        2
    wszgrcy  
       2021-10-29 15:31:00 +08:00
    楼上基本上都说了.然后我记得还有作用域提升,应该也算摇树的一种吧.
    yyfearth
        3
    yyfearth  
       2021-10-29 15:59:00 +08:00   ❤️ 1
    一楼说的很全了 像 lodash 这种 如果你不用 lodash-es 那就需要用 plugin
    如果 package 提供了 esm 并且提供了 sideEffect flag 的话 就都可以自动 tree-shaking 了
    而且 webpack5 连非纯 esm 的 bundle 都可以做一定的 tree-shaking 了

    但是你用自己内部做的包 很可能就不能自动 tree-shaking (除非特别处理)
    这也是我经历过抱怨和误解最多的时候
    因为要支持 tree-shaking 必须提供 esm 和 sideEffect 的信息
    很多人做内部的包很喜欢把所有的东西用 index 全部导出来 但是有不知道怎么声明 sideEffect
    或者用 webpack 或者其他 bundle 打包成了一个文件 cjs/umd 或者 单个 esm (就是把所有文件合并后导出成一个 esm ) 结果都没办法 tree-shaking 导致整个包全部被 webpack 打包

    作为 library 想支持 tree-shaking
    1. package.json 要提供 module 或者 browser 的 esm 入口 或者 exports
    2. 不打包成一个文件 最好只做 babel 或者 tsc 就够了 最多用 rollup 分组件打包
    3. 声明 sideEffect false 或者 指定需要 sideEffect 的文件
    在使用 library 的时候 webpack 需要用 mode: production 并且启动了 minimize 和 TerserPlugin 才能充分使用 tree-shaking

    虽然现在 webpack 和 esm 已经出来很久了
    但是浏览器和 nodejs 的支持还是不是很完美
    这个只能自己花时间 或者培训团队了
    yyfearth
        4
    yyfearth  
       2021-10-29 16:00:26 +08:00
    @wszgrcy 我记得作用域提升 貌似不是为了 tree-shaking 而是为了 dedup
    另外还有一个很强的功能就是 esm 的 concat 功能 不过和 tree-shaking 没有直接关系
    wszgrcy
        5
    wszgrcy  
       2021-10-29 16:43:49 +08:00
    @yyfearth 对了我突然想到一个东西,但是不知道在哪里遇到过,就是打包为 fesm,也就是单文件 esm,然后如果里面有一个直接的语句,比如 console.log()这样,这句肯定没法被引用,然后再我的记忆中,这种语句如果设置无副作用的话应该是会被抛弃的(记忆中感觉遇到过一次),但是实际上并没有,不知道是不是我记错了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5838 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:11 · PVG 11:11 · LAX 19:11 · JFK 22:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.