Vite:JavaScript的联合国
构建工具的演进历程
Evan You回顾了前端构建工具的发展历程:“我十多年前开始做前端时,大家都没有使用构建工具。就像直接把JavaScript放在页面上运行一样简单。但随着我们构建越来越复杂的Web应用,用户对Web体验的期望不断提高,应用复杂度也随之增长。”
模块系统的诞生
“最初,所有脚本共享相同的全局作用域,存在全局命名空间问题。于是我们开始将它们拆分为模块,但源代码分布在不同的文件和模块中后,就需要将它们重新拼接起来。这就是我们称之为’打包’的第一代方案——简单地将所有文件连接在一起,并用函数闭包包装每个文件,防止变量泄漏。”
从CommonJS到现代构建工具
“当Node.js出现并选择CommonJS作为其模块系统后,人们习惯了CommonJS,但需要将其打包以在浏览器中运行。同时,人们开始在JavaScript之上发明新语法,如CoffeeScript和ES6,这催生了将新语法编译为浏览器可运行格式的转译器。”
Vite的技术架构
开发服务器的创新设计
Vite的初始理念实际上是一个HTTP服务器。“Vite开始时完全没有打包。当你编写导入.vue文件或TS文件的代码时,它会作为HTTP请求发送到开发服务器,服务器找到.vue文件后即时编译为JavaScript并返回。这一切都依赖于浏览器中原生的ES模块支持。”
插件系统的演进
“我意识到需要一个同时适用于打包器和开发服务器的插件系统。当时我注意到Jason Miller创建的WMR项目,它引入了’rollup插件容器’的概念——一个能够运行rollup插件而无需实际运行rollup本身的模拟容器。”
热模块替换的技术突破
“Vite最大的贡献是向人们展示了热模块替换可以有多快。人们开始认为,在进行Web开发时,保存文件后更改应该立即反映在页面上。Vite的热模块替换与应用程序大小解耦,无论应用多大,如果是可热替换的模块,更新几乎是瞬时的。”
HMR边界概念
“热模块替换具有HMR边界的概念。你必须对代码进行一些插装,以指示’此模块是HMR边界’,当它依赖的文件被修改时,更改将向上传播到边界并被拦截。在基于组件的框架如React或Vue中,可以安全地假设每个组件都是热模块替换边界。”
安全考虑与未来发展
开发环境的安全问题
“当你有未打包的开发服务器时,默认情况下会提供当前目录下的所有文件。如果用户将开发服务器直接暴露在网络上,访问者将能够访问Vite应用根目录下的任何文件。”
Rust集成与未来规划
“我们正在努力将Rolldown和Oxc集成到Vite中,构建完全由Rust驱动的垂直技术栈。在此基础上,我们正在构建名为Vite Plus的统一工具链:包含Vite开发、Vite构建、Vite链接、Vitest、Vite格式化等功能,并在monorepo中智能缓存。”
开源社区的力量
Evan You强调:“Vite和Vue都是已经超越其创建者的项目。它们现在是社区项目,纪录片应该关注项目背后的人们、社区、生态系统以及参与项目成长的人们——这非常重要。”
通过利用Rollup的现有插件生态系统,Vite能够快速起步。“很多Rollup插件可以直接在Vite中开箱即用,我们跳过了’从零开始发展生态系统’的问题。”