阅读 288

【浅析】Vite

可以分为两个层面,前端开发工具和构建工具,说明 Vite 在开发过程中与构建项目中有极致的体验提升

1 ESM (ECMAScript Module)

CommonJs 社区规范

ES6之前,服务端的规范

// CommonJS模块,运行时加载
let { stat, exists, readfile } = require('fs')
复制代码

具有以下特点

  1. 动态解析 运行时加载模块
  2. 加载整个模块 commonJS 模块中,导出的是整个模块
  3. 每个模块皆为对象 commonJS 模块都被视作一个对象
  4. 值拷贝 commonJS 的模块输出和函数的值传递相似,都是值的拷贝

AMD、UMD 社区规范

ES6之前,客户端的规范

  1. 如上
  2. 异步加载

ES Module 官方规范

ES6之后

// ES6模块,编译时加载
import { stat, exists, readFile } from 'fs';
复制代码

具有以下特点

  1. 静态解析 即在解析阶段就确定输出的模块,所以 es6 模块的 import 一般写在被引入文件的开头。
  2. 加载的不是整个模块 在 es6 模块中经常会看见一个模块中有好几个 export 导出
  3. 模块不是对象 在 es6 里,每个模块并不会当做一个对象看待
  4. 模块的引用 es6 模块中,导出的并不是模块的值拷贝,而是这个模块的引用

浏览器是怎么加载ESM的

<!-- ES6 模块 -->
<script type="module" src="./entry.js"></script>
复制代码

浏览器加载ESM也使用<script>标签,但是要加入type="module"属性。异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本。如果网页有多个ESM,它们会按照在页面出现的顺序依次执行。

ESM在浏览器的兼容性

image2021-6-22_17-46-41.png

2 为什么使用Vite

  1. 缓慢的服务器启动,打包时间久
  2. 缓慢的热更新,更新一个模块,全局打包
  3. 缓慢的构建流程

3 开发环境使用Vite

快速冷启动

Webpack:先经过打包,生成 bundle 文件,再启动本地服务器

bundler.37740380.png image2021-6-23_21-39-51.png

Vite:先启动本地服务器,不打包,不编译,Vite 使用 esbuild 预构建依赖。
esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。

esm.3070012d.png esm.3070012d.png

按需编译

访问入口,根据http请求路径,加载对应的模块依赖,只有访问到的资源和模块依赖才会进行编译,将vue等浏览器不能识别的文件编译为ESM,返回给浏览器

image2021-6-23_21-42-45.png

热重载(HMR)

Webpack:一旦保存必经过打包,生成新的 bundle 文件,再启动本地服务器,随着项目的复杂度提升打包时间增加,等待热重载需要漫长的时间

image2021-6-23_21-44-1.png

Vite:对于已加载的模块进行缓存,精准将改动的 vue 等浏览器不能识别的文件再次编译为 ESM ,毫秒级更新,不依赖项目的大小

image2021-6-23_21-43-37.png

4 生产环境使用Vite

为什么使用 rollup 进行打包

  1. 轻量,基于 ESM 的打包器
  2. 打包后的 bundle 文件体积更小
  3. 结合 tree-shaking,删除未引用代码(Dead code)

为什么生产环境仍需打包

  1. 尽管原生 ESM 现在得到了广泛支持,但由于嵌套导入会导致额外的网络往返,在生产环境中发布未打包的 ESM 仍然效率低下(即使使用 HTTP/2
  2. 为了在生产环境中获得最佳的加载性能,最好还是将代码进行 tree-shaking、懒加载和 chunk 分割(以获得更好的缓存)
  3. 要确保开发服务器和生产环境构建之间的最优输出和行为一致并不容易。所以 Vite 附带了一套 构建优化 的 构建命令,开箱即用

为何不用 ESBuild 打包?

  1. 虽然 esbuild 快得惊人,并且已经是一个在构建库方面比较出色的工具,但一些针对构建应用的重要功能仍然还在持续开发中 —— 特别是代码分割和 CSS 处理方面
  2. 就目前来说,Rollup 在应用打包方面更加成熟和灵活。未来也不排除使用 esbuild 作为生产构建器的可能

image2021-6-23_21-51-20.png

5 拓展

特性

  1. 将原本 webpack 大部分工作交给浏览器去完成
  2. 使用 esbuild 预构建,CommonJS / UMD 转换为 ESM 格式,Vite 将有许多内部模块的 ESM 依赖关系转换为单个模块,以提高后续页面加载性能(eg:lodash-es
  3. 天然支持 typescript
  4. 支持lesssass等,只需要安装对应编译器,不需要写 loader 配置等

ESM与Tree-shaking

ESM静态解析,rollup打包编译过程中,结合 tree-shaking,删除未引用的代码(Dead code)

生产环境兼容性

用于生产环境的构建包会假设目标浏览器支持现代 JavaScript 语法,默认情况下,vite 的目标浏览器是指能够支持原生 ESM script 标签和支持原生ESM动态导入的

传统浏览器可以通过插件 @vitejs/plugin-legacy 来支持,它将自动生成传统版本的 chunk 及与其相对应 ES 语言特性方面的 polyfill,兼容版的 chunk 只会在不支持原生 ESM 的浏览器中进行按需加载\

Vite与Weex的可能性

  1. 是不是要用weex语法去开发?

  2. vite怎么支持weex-vue-loader?

  3. 怎么去和App端交互?

参考建议

webpack 官网

vite 官网

rollup.js 官网

caniuse 官网

esbuild github

文章分类
前端
文章标签