vite-基于ESM的下一代构建工具
vite的横空出世,不久的将来很可能会深刻的改变前端构建工作。
# vite做了什么
官方解释非常到位。
“ 当我们开始构建越来越大型的应用时,需要处理的 JavaScript 代码量也呈指数级增长。包含数千个模块的大型项目相当普遍。 我们开始遇到性能瓶预——使用 JavaScript 开发的工具通常需要很长时间(甚至是几分钟!)才能启动开发服务器,即使使用HMR,文件修改后的效果也需要几秒钟才能在浏览器中反映出来。 如此循环往复,迟钝的反馈会极大地影响开发者的开发效率和辛福感。 ”
我们再详细说说目前前端构建工具的问题;
# 缓慢的服务器启动
但冷启动开发时,基于打包器(webpack等)的方式启动时必须要先扫描并构建整个应用,然后才能提供服务。 这个过程所需要的时间随着项目中js代码量的上升而变的越来越长。
# 缓慢的更新
开发实践中我们也发现,即使使用HMR模式热更新,也会随项目规模增长花费更多时间。
# vite的优势
主流打包工具webpack在启动时,会从入口文件开始,
递归的构建一个依赖关系图,然后将这些模块打包成一个或多个包。
简单理解下来,webpack需要走完递归查找 - 构建编译 - 打包 - 运行
所有过程才能启动。
相比较而言,vite启动时没有这个过程,vite以原生esm的方式提供模块, 这实际上可以理解为是"按需构建";即启动时并未构建, 也就是说不需要分析模块的依赖,浏览器在请求某个模块时,再根据模块的内容进行编译。 这大大缩短了启动时间。
另外,vite2.0 采用ESBuild预构建依赖,它是Go语言编写的打包器, 基准测试表明,相比js编写的打包器,其预构建依赖的速度要快上10-100倍。
可以这样认为,vite就是对ESBuild的封装。
# ESM ES module
这里不得不提下ESM,因为vite的前提完全基于这个规范。ESM是js官方的标准化模块系统,主流浏览器也已经支持。 它规范了如何把文件解析为模块记录,如何实例化和运行模块。
特别的,ESM使用的被称为Live Binding的方式原生支持HMR。即导出导入的模块都是值引用。 所以,当导出模块改变了,导入模块的值也会实时变化。
# demo案例
下面给出一个浏览器中使用ESM的案例
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ESM Demo</title>
</head>
<body>
<script type="module" src="./app.js"></script>
</body>
</html>
// app.js
import { greeting } from './greeting.js';
const greetingElement = document.createElement('h1');
greetingElement.textContent = greeting;
document.body.appendChild(greetingElement);
// greeting.js
export const greeting = 'Hello, World!';