webpack treeshaking好像不起作用?

入口文件index.js

import { a } from "./test.js";

console.log(a);

test.js

export const a = 1;
export const b = 2;
console.log("11111111");

test中的b变量没引用,所以要treeshaking掉,test中的console语句也是副作用,我在package.json中设置了 "sideEffects": false, webpack的mode已经设置成production了,为啥test中console语句还是被打包进去了
打包结果

(()=>{"use strict";console.log("11111111"),console.log(1)})();
阅读 2.5k
2 个回答

console.log() 当然应该打包进去,“输出内容” 是软件功能的一部分。不想要的话,在压缩的时候配置 drop_console 就好。

可以用/*#__PURE__*/

test.js文件

export const a = 1;
const b = 1;
/*#__PURE__*/ console.log('11111111')

可以参考官方文档:https://webpack.js.org/guides...

sideEffects is much more effective since it allows to skip whole modules/files and the complete subtree.
usedExports relies on terser to detect side effects in statements. It is a difficult task in JavaScript and not as effective as straightforward sideEffects flag. It also can't skip subtree/dependencies since the spec says that side effects need to be evaluated. While exporting function works fine, React's Higher Order Components (HOC) are problematic in this regard.
...
Terser actually tries to figure it out, but it doesn't know for sure in many cases. This doesn't mean that terser is not doing its job well because it can't figure it out. It's too difficult to determine it reliably in a dynamic language like JavaScript.

But we can help terser by using the /*#__PURE__*/ annotation. It flags a statement as side effect free. So a small change would make it possible to tree-shake the code:

总的来说就是确定某个函数的副作用对于js来说比较困难,对于确定不了是否有副作用的函数,需要你添加一个标记/*#__PURE__*/明确的告诉打包程序,这个函数是没有副作用的。
不只是webpack,rollup也是这么做的 可以参考Vue源码就用了很多无副作用标记

export const mutableCollectionHandlers: ProxyHandler<CollectionTypes> = {
  get: /*#__PURE__*/ createInstrumentationGetter(false, false)
}

export const shallowCollectionHandlers: ProxyHandler<CollectionTypes> = {
  get: /*#__PURE__*/ createInstrumentationGetter(false, true)
}

export const readonlyCollectionHandlers: ProxyHandler<CollectionTypes> = {
  get: /*#__PURE__*/ createInstrumentationGetter(true, false)
}

export const shallowReadonlyCollectionHandlers: ProxyHandler<CollectionTypes> =
  {
    get: /*#__PURE__*/ createInstrumentationGetter(true, true)
  }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题