对象的 tree-shaking
优化
对于导入对象的 tree-shaking
效果有限,以下实例中通过结构获取对象中的属性可以正常执行 tree-shaking
优化。
rollup 支持的 tree-shaking
优化
esm
模块语法支持情况
js
// ✅ good case 1
import * as maths from './maths.js';
// ✅ good case 2
import { square } from './maths.js';
// ✅ good case 3
const { square: square2 } = await import('./maths.js');
// ✅ good case 4
import('./maths.js').then(({ square }) => console.log(square(10)));
console.log(maths.square(10), square, square2);
js
export const square = x => x * x;
export const double = x => x * 2;
export default { square, double };
js
const square = x => x * x;
var maths = /*#__PURE__*/ Object.freeze({
__proto__: null,
square
});
const { square: square2 } = await Promise.resolve().then(function () {
return maths;
});
Promise.resolve()
.then(function () {
return maths;
})
.then(({ square }) => console.log(square(10)));
console.log(square(10), square, square2);
js
import a from './maths.js';
console.log(a.square(10));
js
const a = await import('./maths.js');
console.log(a.square(10));
js
import('./maths.js').then(a => console.log(a.square(10)));
js
export const square = x => x * x;
export const double = x => x * 2;
export default { square, double };
js
const square = x => x * x;
const double = x => x * 2;
var a = { square, double };
console.log(a.square(10));
js
const a = await import('./maths-BMpjz1lG.js');
console.log(a.square(10));
js
import('./maths-BMpjz1lG.js').then(a => console.log(a.square(10)));
js
const square = x => x * x;
const double = x => x * 2;
var maths = { square, double };
export { maths as default, double, square };
esm 模块支持 tree-shaking
语法小结
综上可以发现,rollup
对于 esm
模块除了对象引用外的其他导入方式均支持 tree-shaking
优化。对象引用暂时只支持 namespace object
引用的 tree-shaking
优化。
commonjs
模块语法支持情况
对于 commonjs
模块的 tree-shaking
优化,相对而言就比较严苛一些。
- 需要配置
strictRequires
为false
或auto
来避免将commonjs
模块进行包装处理。因为strictRequires
为非true
时,插件会尽可能确保转译后的esm
模块具备静态性质,详情可参考 Default Strict Requires To True 文章。 - 需要确保
commonjs
模块中使用exports
语法导出。 - 需要确保使用
import()
方式导入模块的同时使用解构获取导出的属性值。
以下述例子作为说明,index.mjs
作为入口模块:
js
export * from './a.cjs';
js
(async () => {
const { square } = await import('./b.cjs');
console.log(square(10));
})();
js
const square = x => x * x;
const add = (a, b) => a + b;
const sub = (a, b) => a - b;
exports.square = square;
exports.add = add;
exports.sub = sub;
js
import commonjs from '@rollup/plugin-commonjs';
export default {
input: {
index: './index.mjs'
},
output: [
{
dir: 'dist/commonjs/esm',
format: 'es',
entryFileNames: 'output.js'
}
],
treeshake: true,
plugins: [
commonjs({
strictRequires: false
})
]
};
js
(async () => {
const { square } = await import('./b-Co0LKdJH.js').then(function (n) {
return n.b;
});
console.log(square(10));
})();
js
const square = x => x * x;
var square_1 = square;
var b = /*#__PURE__*/ Object.freeze({
__proto__: null,
square: square_1
});
export { b };
对象的深度 tree-shaking
优化
由上述可以发现,不管是处理 esm
模块还是 commonjs
模块,rollup
对于对象引用上的 tree-shaking
优化效果十分有限,暂时只支持针对 esm
模块的 namespace object
引用上的 tree-shaking
优化。同时对于 commonjs
模块的 tree-shaking
优化更为有限,主要原因还是 rollup
对对象的 tree-shaking
优化不够彻底。
feat: implement object tree-shaking PR 的提出就是实现 rollup
对对象的深度 tree-shaking
优化。
这本质上是针对 object
的深度 tree-sharking
优化,针对对象的结构属性获取做更深层次的 tree-shaking
优化。这个 PR 合并也意味对于 commonjs
模块的 tree-shaking
的更深度优化。
TODO: 待补充 object tree-shaking
PR 的实现原理。