# 前端工程化的痛点及 vite 的解决方案
# 痛点一:模块化规范太多,需要一个支持和兼容
- vite 的解决方案
- 支持 ESM 模块化方案(支持异步,浏览器原生支持),由于浏览器原生支持 ESM,所以可以基于 ESM 实现
no-bunder
- 兼容其他的模块化方案,通过在
预构建
过程中来使用 esbuild
来将其他模块化方案转换成 ESM
- 模块化方案面对的问题
- 模块的拆分
- 模块的依赖关系导致的加载顺序(a 模块依赖 b 模块,那就需要先引入 b 模块再引入 a 模块)
- 变量命名冲突
- 浏览器是否兼容
- 模块化方案发展历史
- 第一阶段:通过
<script>
来做模块化,但是存在变量命名冲突,模块加载顺序的问题 - 第二阶段:通过
命名空间(window.moduleA, window,moduleB)
来做模块化,解决了变量命名冲突,但是 没有解决模块加载顺序的问题 - 第三阶段:通过
IIFE(立即执行函数)
来做模块化,解决了变量命名冲突,但是没有解决模块加载顺序的问题 - 第四阶段:通过
CommonJS
规范来做模块化,解决了变量冲突,模块加载顺序的问题,但是存在一个加载是同 步的问题(这在浏览器是个大问题,当加载的模块过大时,会阻塞后续代码的执行,会造成界面白屏时间过长),并且 浏览器并不支持这个模块化方案 - 第五阶段:通过
AMD
来做模块化,也就是异步模块定义方案,解决了上述的问题,但是写起来太麻烦,并且也 没有得到浏览器的支持 - 最终阶段:通过
ESM
来做模块化,完美解决了上述问题所有问题(变量命名冲突,模块加载顺序),并且加载是 异步的,不会阻塞页面渲染,并且是浏览器原生支持
# 痛点二:需要对 ts,tsx 等高级语法做一个转译,对静态资源做处理,使其能作为一个正常模块加载,能够对语法做一个降级,并注入一些高级语法,以支持低级浏览器
- vite 的解决方案
- 通过
esbuild
来对 ts,tsx 等语法来进行一个转译(但是 ts 的语法检查还是需要 tsc
) - vite 内置对 JSON 模块的加载(底层使用 @rollup/pluginutils 的 dataToEsm 方法将 JSON 对象转换为一 个包含各种具名导出的 ES 模块)
- 通过
bable
来将高级语法编译成低级语法(比如把箭头函数变成普通函数),通过 corejs
来注入一些高级 API (比如 promise),从而兼容低版本的浏览器
# 痛点三:提高产物质量,要能给对代码进行压缩和 Treeshaking
- vite 的解决方案
- 通过
esbuild
来对代码进行一个压缩 - treeShaking (待更新)
# 痛点四:开发效率低下,开发启动时间很长,热更新很慢
- vite 的解决方案
- 开发阶段直接
no-bunder
不打包直接启动,利用浏览器原生支持 ESM 的这一点,让浏览器来加载源代码对应的模块(在预构建过程中,利用 esbuild
来将其他模块化方案转换成 ESM,并打包第三方依赖,避免请求瀑布的出现,导致白屏时间过长) - 热更新(待更新)