AndreGeng / AndreGeng.github.io

blog repository
1 stars 0 forks source link

为什么Tree Shaking只对ESM模块生效? #28

Open AndreGeng opened 5 years ago

AndreGeng commented 5 years ago
Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. import and export. The name and concept have been popularized by the ES2015 module bundler rollup.

从webpack对Tree Shaking介绍我们知道它是需要es2015模块“静态化结构”的支持。“静态化结构”指的是什么,为什么commonjs不属于“静态化结构”呢 首先动态化指的是模块的依赖是在运行时动态决定的,而不能够静态的代码分析工具在构建时通过分析代码而得出的,像下面例子这样

const env = process.env.NODE_ENV || 'product';
let hello;
if (env === 'test') { // 1
  hello = require('./test.js');
} else {
  hello = require('./product.js');
}
console.log(hello());

const hello2 = require(`./${env}`); // 2
console.log(`hello2: ${hello2()}`);

代码1处,require语句是可以位于if/else或者某种loop中的,这导致只有运行时才能得出具体的依赖。 代码2处,require语句是可以允许传入变量的,这也导致只有运行时才能拿到具体的代码依赖。

虽然这样的写法我们平时用的其实也不多,但commonjs的确是支持这种用法的,这就是为什么tree shaking只能对静态化的ESM模块生效了。 因为ESM模块是不允许动态import的,比方下面的写法是不正确的

function hello(){
  import { foo } from './foo.js';   // ESM不支持动态引入
}