Hvigor
hvigor是一款基于TS实现的 构建任务编排工具,主要提供任务管理机制,包括任务注册编排、工程模型管理、配置管理等关键能力,更符合node生态开发者开发习惯
它不负责实际的打包,实际打包的工作是通过rollup来做的。
rollup
一个用于 JavaScript 的 模块打包工具,它将小的代码片段编译成更大、更复杂的代码
rollup打包工具在前端很早就有了,与它齐名的还有webpack,webpack主要用于打包web应用。
rollup基于ESM模块打包,能同时处理Nodejs和浏览器的JS打包工作,它还会自动对代码进行tree shaking减小包的体积,在对库和模块打包时非常有用。React、Vue等框架的构建就是使用的rollup
rollup 支持的打包文件的格式有 amd, cjs, esm/es, iife, umd。其中amd 为 AMD 标准,cjs 为 CommonJS 标准,esm/es为 ES 模块标准,iife 为立即调用函数, umd 同时支持 amd、cjs 和 iife
.js 默认采用 ES 模块标准,ESM:ECMAScript 模块是未来的官方标准和主流
tree-shaking
tree-shaking 本质上是 消除无用的 JS 代码。 当引入一个模块时,并不引入整个模块的所有代码,而是只引入需要的代码,那些不需要的无用代码就会被”摇“掉
tree-shaking 虽然能够消除无用代码,但仅针对 ES6 模块语法,因为 ES6 模块采用的是静态分析,从字面量对代码进行分析
DCE(dead code elimination)
无用代码有一个专业术语 - dead code elimination(DCE)。编译器可以判断出哪些代码并不影响输出,然后消除这些代码。DCE主要包括以下几个方面
●代码不会被执行,不可到达
●代码执行的结果不会被用到
●代码只会影响死变量,只写不读
基于两个关键实现
1.ES6 的模块引入是静态分析的,可以在编译时正确判断到底加载了什么代码。 ES6 Module一些特性如下
1.只能作为模块顶层的语句出现,不能出现在 function 或是 if等块级作用域中
2.import 的模块名只能是字符串常量
3.import binding 是 immutable 的,类似 const
4.import hoisted,不管 import的语句出现的位置在哪里,在模块初始化的时候所有的import 都必须已经导入完成
2.分析程序流,判断哪些变量被使用、引用,打包这些代码
1.基于作用域,在 AST 过程中对函数或全局对象形成对象记录
2.在整个形成的作用域链对象中进行匹配 import 导入的标识,最后只打包匹配的代码,而删除那些未被匹配使用的代码
下面的截图中 index.js 是入口文件,打包生成的代码在 bundle.js 中,除此之外的 a.js、util.js 等文件均作为被引用的依赖模块
1)消除未使用的变量
a.js中定义的变量 b 和 c 没有使用到,它们不会出现在打包后的bundle.js文件中
2)消除未被调用的函数
仅引入但未使用到的 util3()和 util2()函数没有被打包进来
3)消除未被使用的类
只引用类文件 mixer.js 但实并未用 它的任何方法和变量,该类不会出现在bundle.js文件