这是我参与[第五届青训营]伴学笔记创作活动的第十四天
Vite
0.为什么需要构建工具?
| 模块化规范不同(ESM、CommonJS、UMD) | 1.提供模块加载方案 2.兼容不同模块规范 |
|---|---|
| 资源编译(高级语法编译,scss、jsx) | 1.高级语法转移,如Saaa、TpeScript 2.资源加载,如图片、字体、worker |
| 产物质量(代码体积、代码性能) | 产物压缩、无用代码删除、语法降级 |
| 开发效率(热更新) | 热更新 |
1.什么是Vite?
定位:新一代前端构建工具 两大组成部分:
- No-bundle 开发服务.源文件无需打包
- 生产环境基于 Rollup 的 Bundler
核心特征
- 高性能,dev 启动速度和热更新速度非常快!
- 简单易用.开发者体验好
Vite基于原生ESM(绝大数浏览器兼容的模块化规范)的开发服务优势
- 无需打包项目源文件
- 天然的按需加载
- 可以利用文件级的浏览器缓存
Vite基于Golang开发的前端工具(性能极高,在Vite中被深度使用),具备如下能力
- 打包器Bundler
- 编译器Transformer
- 压缩器 Minifier
Vite具有开箱即用的特征:相当于很多WebPack的很多loader和plugin插件 tree-shaking、HMR
2.WebPack和Vite区别
Vite是基于esbuild预构建依赖。而esbuild是采用go语言编写,因为go语言的操作是纳秒级别,而js是以毫秒计数,所以vite比用js编写的打包器快10-100倍。
- webpack: 分析依赖=> 编译打包=> 交给本地服务器进行渲染。首先分析各个模块之间的依赖,然后进行打包,在启动webpack-dev-server,请求服务器时,直接显示打包结果。webpack打包之后存在的问题:随着模块的增多,会造成打出的 bundle 体积过大,进而会造成热更新速度明显拖慢。
- vite: 启动服务器=> 请求模块时按需动态编译显示。是先启动开发服务器,请求某个模块时再对该模块进行实时编译,因为现代游览器本身支持ES-Module,所以会自动向依赖的Module发出请求。所以vite就将开发环境下的模块文件作为浏览器的执行文件,而不是像webpack进行打包后交给本地服务器。
- 分析了webpack和vite的打包方式后,也就明白了为什么vite比webpack打包快,因为它在启动的时候不需要打包,所以不用分析模块与模块之间的依赖关系,不用进行编译。这种方式就类似于我们在使用某个UI框架的时候,可以对其进行按需加载。同样的,vite也是这种机制,当浏览器请求某个模块时,再根据需要对模块内容进行编译。按需动态编译可以缩减编译时间,当项目越复杂,模块越多的情况下,vite明显优于webpack.
- 热更新方面,效率更高。当改动了某个模块的时候,也只用让浏览器重新请求该模块,不需要像webpack那样将模块以及模块依赖的模块全部编译一次。
3.Vite整体架构
开发模式下:
关键技术:依赖预打包
为什么要进行预打包?
- 避免 node_modules 过多的文件请求
- 将 CommonJS 格式转换为 ESM 格式
- 实现原理:
- 服务启动前扫描代码中用到的依赖
- 用 Esbuild 对依赖代码进行预打包
- 改写import 语句,指定依赖为为预构建产物路径
//改写前
import React from 'react';
//改写后
import React from './node_modules/.vite/react.js';
关键技术:单文件编译
用 Esbuild 编译 TS/JSX
优势:编译速度提升 10-100 倍
局限性: 不支持类型检查 不支持语法降级到ES5
生产模式下:
关键技术:代码压缩
Esbuild 作为默认压缩工具,替换传统的 Terser、 Uglify.js 等压缩工具
关键技术:插件机制
开发阶段 一>模拟 Rollup 插件机制 生产环境 一>直接使用 Rollup