什么是tree-shaking
tree-shaking, 直译摇树, 是利用es module的静态分析, 可删除掉无用代码, 从而减少代码体积.tree-shaking在rollup和webpack里都有实现
参考: rollup官网文档
如何使用tree-shaking
sdk开发者对外提供三个api: fnA, fnB, fnC, 其中fnA和fnB都调用了fnC
/**
* @description 这是函数A
*/
export async function fnA(str: string): Promise<string> {
return `AAAAAA` + fnC(str)
}
/**
* @description 这是函数B
*/
export function fnB(str: string): Promise<string> {
return Promise.resolve(`BBBBBB` + fnC(str))
}
/**
* @description 这是函数C
*/
export function fnC(str: string): string {
return `CCCCCC` + str
}
例子一
sdk使用者只引用了fnA
import * as sdk from './sdk'
var useApis = {
fnA: sdk.fnA
}
useApis.fnA('test')
查看构建后的代码
/**
* @description 这是函数A
*/
async function fnA(str) {
return `AAAAAA` + fnC(str);
}
/**
* @description 这是函数C
*/
function fnC(str) {
return `CCCCCC` + str;
}
var useApis = {
fnA: fnA
};
useApis.fnA('test');
可以看到函数B相关的源码被tree-shaking掉了, 摇树成功

此使用sdk的方式等同于
import { fnA } from './sdk'
var useApis = {
fnA,
}
useApis.fnA('test')
如下是构建后的代码, 也是成功的删除了fnB相关的源码
/**
* @description 这是函数A
*/
async function fnA(str) {
return `AAAAAA` + fnC(str);
}
/**
* @description 这是函数C
*/
function fnC(str) {
return `CCCCCC` + str;
}
var useApis = {
fnA,
};
useApis.fnA('test');
例子二
sdk使用者引用了全部的api, 只调用了fnA
import * as sdk from './sdk'
var useApis = {
...sdk
}
useApis.fnA('test')
查看构建后的代码
/**
* @description 这是函数A
*/
async function fnA(str) {
return `AAAAAA` + fnC(str);
}
/**
* @description 这是函数B
*/
function fnB(str) {
return Promise.resolve(`BBBBBB` + fnC(str));
}
/**
* @description 这是函数C
*/
function fnC(str) {
return `CCCCCC` + str;
}
var sdk = /*#__PURE__*/Object.freeze({
__proto__: null,
fnA: fnA,
fnB: fnB,
fnC: fnC
});
var useApis = {
...sdk
};
useApis.fnA('test');
中包含了所有函数的源码, 因为是静态分析, 不能判断哪个函数是否被调用, 摇树失效
例子三
sdk开发者对外提供一个默认对象, 包含全部的api
/**
* @description 这是函数A
*/
async function fnA(str: string): Promise<string> {
return `AAAAAA` + fnC(str)
}
/**
* @description 这是函数B
*/
function fnB(str: string): Promise<string> {
return Promise.resolve(`BBBBBB` + fnC(str))
}
/**
* @description 这是函数C
*/
function fnC(str: string): string {
return `CCCCCC` + str
}
export default {
fnA,
fnB,
fnC,
}
sdk使用者引用了全部的api, 只调用了fnA
import sdk from './sdk'
const { fnA } = sdk
var useApis = {
fnA
}
useApis.fnA('test')
查看构建后的代码
/**
* @description 这是函数A
*/
async function fnA(str) {
return `AAAAAA` + fnC(str);
}
/**
* @description 这是函数B
*/
function fnB(str) {
return Promise.resolve(`BBBBBB` + fnC(str));
}
/**
* @description 这是函数C
*/
function fnC(str) {
return `CCCCCC` + str;
}
var sdk = {
fnA,
fnB,
fnC,
};
const { fnA: fnA$1 } = sdk;
var useApis = {
fnA: fnA$1
};
useApis.fnA('test');
显然这也不是我们想要的效果
![]()