webpack 现在依然不能自动支持 tree-shaking,来优化引入的包么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yazoox
V2EX    webpack

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

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

    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     Solana     2636 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 06:30 PVG 14:30 LAX 23:30 JFK 02:30
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86