# 前端工程化的痛点及 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,并打包第三方依赖,避免请求瀑布的出现,导致白屏时间过长)
    • 热更新(待更新)