Import 方式对 Tree-shaking 的影响

最近从小被子那里学了不少 Tree-shaking 的知识,Tree-shaking 译作“摇树优化”,是 DCE(Dead Code Elimination)优化的一种实现。

Webpack 在编译阶段,通过分析模块依赖,对代码中未使用到的对象和 function 进行标注,再通过压缩工具“摇”掉这些多余的代码。

DIY

首先我们使用以下命令,来搭建一套实验环境,加深对 Tree-shaking 的理解。

# 初始化项目目录与 package.json
mkdir demo && cd demo
npm init -y

# 安装 webpack,当前版本 4.35.0
npm i -D webpack webpack-cli

# 创建源码目录和文件
mkdir src
touch src/index.js src/util.js

其中 util.js 文件的内容如下:

function funcA() {
  return "funcA";
}
function funcB() {
  return "funcB";
}
export { funcA, funcB };

index.js 文件的内容如下:

import { funcA } from "./util";

const name = funcA();
console.log(name);

然后我们在项目根目录中,执行 npx webpack 来编译项目代码,得到编译后的代码 dist/main.js 。我们对它进行格式化,能看到以下内容:

!(function(e) {
  // ... 省略
})([
  function(e, t, r) {
    "use strict";
    r.r(t);
    console.log("funcA");
  }
]);

从结果上来看,因为util.js 中的funcB 没有被 index.js import,所以最终编译的代码main.js 中没有 funcB 相关的代码。funcB 被 tree-shaking 掉了。

import * as

接下来,我们改变 index.js 中 import 语句的写法:

import * as util from "./util";

const name = util.funcA();
console.log(name);

发现最终结果同上:funcB 被 tree-shaking 掉了。

由此可见,import * as 的效果和 import {} 解构的效果是一样的:都是先取到 import 的对象,再基于对象上的属性是否被使用来进行标注。

export default {}

接下来,我们修改下 util.js 的内容,在 export 后面加上一个 default 关键字试试:

function funcA() {
  return "funcA";
}
function funcB() {
  return "funcB";
}
export default { funcA, funcB };

由于加上了 default,所以 index.js 文件中对 util 的调用需要加多一级 default 属性的引用:

import * as util from "./util";

const name = util.default.funcA();
console.log(name);

同时,又因为我们的 util.js 中只有一条默认的 export default,所以可以直接写成以下同时去掉 * as 和 default 的写法:

import util from "./util";

const name = util.funcA();
console.log(name);

我们格式化下最终编译的 dist/main.js 发现,虽然 funcB 没有被调用,但是依然被打包进了源码:

!(function(e) {
  // ... 省略
})([
  function(e, n, t) {
    "use strict";
    t.r(n);
    const r = {
      funcA: function() {
        return "funcA";
      },
      funcB: function() {
        return "funcB";
      }
    }.funcA();
    console.log(r);
  }
]);

由此可见,export default 对象被 import 后,挂在 default 上的属性和方法,即使没有被调用,也无法被 tree-shaking。

所以我们在组织模块文件时,应当尽可能避免 export default {A, B, C} 的写法。

补充:Vue SFC 写法对 Tree-shaking 的影响

这个是前端技术群里的讨论,内容太多,我直接贴长图吧。

Vue SFC & Tree-shaking

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券