该小节主要知识点:
- ⭐️
模块化的发展史 Treeshaking基本原理- ⭐️
Webpack、Rollup、Vite、Esbuild、Babel、Tsc、Swc有什么不同 ? - ⭐️ 什么是
Bundle、Bundless、No-Bundle?
给大家抛出一个问题:
上一小节我们使用
tsc将 我们的 ts代码 全部转换成了 js、js.map、d.ts的代码
请问 这是打包吗?为什么?
在正式解答什么是 Bundle、Bundless、No-Bundle 之前,先带大家回顾一下模块化的发展史
模块化的发展史
在那个HTML文件里面写所有的JS、CSS代码,刀耕火种的年代,**工程化**逐渐兴起
优秀的前辈们开始了对 工程化 以及 模块化 的探索之路
一.无模块化标准阶段
1.文件划分
问题:命名冲突,script标签顺序管理困难,变量全部定义在全局-调试困难
2.命名空间
优化命名冲突:每个文件都是引入一个大的对象,解决了大对象下的变量命名冲突
3.LIFE(立即执行函数)
目的是为了解决变量命名冲突
二.模块化标准阶段
1.CJS-CommonJs
特点:只支持 node 环境,同步,导出变量可以修改
2AMD(Asynchronous Module Definition,异步模块加载机制)
代表:requirejs
3.CMD和UMD
CMD:与AMD一样解决异步问题
UMD:一直兼容CJS和AMD的方案
4.ESM(浏览器原生和服务端支持异步)-ESModule
在 node端 如何使用 ESModule呢?
1.package.json中 type 改为 module
2.文件名后缀为 mjs
特点:双端支持,异步,导出变量为引用,无法修改
在 浏览器端 如何使用 ESModule呢
script标签中设置 type='module' 即可
CJS与ESM的差异-- Treeshaking 基本原理
ESModule 模块依赖关系是确定的,和运行时的状态无关
可以进行可靠的⭐️ 静态分析 也就是 不执行里面的js代码 就可以分析得到 依赖图谱
而 CommonJs require 执行之后 我们 才可以知道 这个模块引用了其他的哪些模块
Webpack、Rollup、Vite、Esbuild、Babel、Tsc、Swc 有什么不同
第一类叫做 Bundle 型
Webpack - Bundle
特点:
通过构建依赖图谱 最终将产物放到 main.js 中
对于除 js 之外的其他资源 bundle、transform 能力也同样优异
Rollup - Bundle
特点:
通过构建依赖图谱 最终将产物打包到 main.js 中
大力支持ESModule
第二类叫做 No-Bundle 型
Vite:
development 阶段:- No-Bundle
使用 ESbuild 对 ts、tsx、jsx 文件 进行 transform 进行平行编译之后 不Bundle
而是通过浏览器原生支持 ESModule 的特点,使用 script标签 type = ’module‘ 引入
production 阶段: - Bundle
使用Rollup进行全量Bundle 将产物打包到 main.js 种
第三类叫做 Bundless 型 有些开源库作者也喜欢叫 Transform 型
TSC - typescript compiler
Esbuild
Babel
Swc
他们的 特点是什么:编译生成 js 代码
比如我们上一小节中 将 ts 代码编译成了 js 代码
实际上 上面四个都可以完成代码的编译/转换 达到我们想要的效果
但是他们的能力 仅限于 例如 ts js jsx tsx ... 而不包括其他资源例如:css、图片、字体 ...
所以什么是Bundless?
Bundless 即文件到文件的构建模式,它不对依赖做任何处理,只对源码做平行编译输出 -- (引自辟起老师)
以下是示例:
└── src
├── index.less
├── index.ts
└── test.js
它会被编译成
└── src
├── index.d.ts
├── index.js
├── index.less
└── test.js
还记得本小节开头的问题吗?
上一小节我们使用 tsc 将 我们的 ts代码 全部 转换成了 js、js.map、d.ts的代码
请问这是 打包 吗?
答案是 -- 不是
这是 Bundless 的方案
所以 什么是 Bundle、Bundless、No-Bundle?
相信你看到这里,对于三种模式已经有了自己的理解了 如果还是一知半解 建议反复观看前面举的例子
总结一下:
Bundle 就是通过 分析依赖图谱 将所有文件打入一个文件 里面去使用
Bundless 就是只对 所有源文件 进行 平行编译/transform 不会去分析依赖关系进行打包
No-Bundle 例如Vite 就是 利用Bundless 编译/transform 之后通过 浏览器原生支持ESModule 的特性使用 script标签引入 type = 'module' 做 development 开发
小结:
本小节我们
1.首先带大家系统回顾了一下模块化发展的过程,引出了我们现在最常用的CommonJs、ESModule、LIFE、UMD等
2.主要介绍了这个 Treeshaking 优异的能力,它是通过 ESModule 静态分析 的特点来实现的
3.通过举例当前工程化领域流行的几个工具,为大家介绍了他们的异同指出它们的特点,让大家自行体会什么是Bundle、Bundless、No-Bundle
4.总结了什么是Bundle、Bundless、No-Bundle,即 Bundle--通过 分析依赖图谱 将所有文件打入一个文件,Bundless--只对 所有源文件进行 平行编译/transform 不会去分析依赖关系进行打包,No-Bundle--利用 Bundless 编译/transform 之后通过浏览器原生支持ESModule的特性使用 script标签引入 type = 'module'
下一小节将带着大家将我们的第一个 npm 包发布到 npm 仓库中 ~
小节思考:
你能自己表述出来 什么是 Bundle、Bundless、No-Bundle 吗?