giveme-a-name / my-webpack Goto Github PK
View Code? Open in Web Editor NEWmy webpack demo
my webpack demo
在 CommonJs、AMD、CMD 等旧版本的 JavaScript 模块化方案中,导入导出行为是高度动态,难以预测的;
if (process.env.NODE_ENV === "development") {
// 我们可以在条件判断中进行 require()
// 其实这跟 nodejs 的 require 实现相关
// nodejs require 是在运行时进行依赖模块处理的。它将依赖模块处理成一个 module 对象。
// docs: https://juejin.cn/post/7111928640572489742#heading-13
require("./bar");
exports.foo = "foo";
}
而 ESM 方案则从规范层面规避这一行为,它要求所有的导入导出语句只能出现在模块顶层,且导入导出的模块名必须为字符串常量。
所以,ESM 下模块之间的依赖关系是高度确定的,与运行状态无关,编译工具只需要对 ESM 模块做 AST 等静态分析,在编译阶段判断出哪些模块值是没有被使用过的。
Webpack 中,Tree-shaking 的实现一是先标记出模块导出值中哪些没有被用过,二是使用 Terser 删掉这些没被用到的导出语句。标记过程大致可划分为三个步骤:
其中 Make 阶段和 Seal 阶段是在 Webpack 中进行处理的。我们主要实现的就是这一部分。
// src/index.js
import { add } from "./utils.js";
// src/utils.js
export function add() {}
export function sub() {}
比如上面在没有 tree-shaking 代码,Webpack 会将它打包成类似这样
// src/utils.js
Object.defineProperty(exports, "__esModule", { value: true });
exports.add = add;
exports.sub = sub;
实际上,我们的预期效果是这样
Object.defineProperty(exports, "__esModule", { value: true });
exports.add = add;
sub 变量对应的导出语句就被删除了
我们通过分析 AST 可以分析出在模块依赖和引入变量之间的关系。
我们将该模块导入依赖的变量记录下来,在依赖模块 AST 分析时记录下它到处的变量。
在构建依赖图时进行对依赖模块导出变量和被导入变量进行一一对比。这样可以删除掉依赖。
// src/index.js
import { add } from "./utils.js";
// index.js 的dependency对象如下:
//
// {
// "./utils": {
// path: "/xxx/.utils.js",
// imports: ["add"],
// }
// }
// src/utils.js
export function add() {}
export function sub() {}
// utils 导出的 moduleInfo 新增 exports 信息,记录导出的变量。
// const utils-ModuleInfo = {
// filename: "utils.js",
// dependencies: [],
// ...,
// exports: ["add", "sub"]
// }
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.