Vite:JavaScript的联合国
构建工具的演进历程
Evan You回顾了前端构建工具的发展历程:“我十多年前开始做前端时,大家最初都没有构建工具。你只需要把JavaScript放在页面上,它就能运行。那是美好的旧时光,但随着我们在Web上构建越来越复杂的东西,应用程序的复杂度开始增长。”
模块系统的诞生
“我们开始将代码拆分成模块,但源代码现在存在于不同的文件、不同的模块中。你需要将它们重新拼接在一起 - 这就是我们称之为’打包’的第一代方案:简单地将所有文件连接在一起,用函数闭包装每个文件,这样变量就不会泄漏到外部。”
从CommonJS到现代构建工具
“Node.js出现后选择了CommonJS作为其模块系统,人们习惯了CommonJS,但希望能在浏览器中运行这些代码。由于浏览器不支持模块,我们开始有了能够将CommonJS模块打包成单个文件的真正打包器。”
Vite的技术架构
无打包开发服务器
Vite的核心理念是开发阶段无需打包:“Vite开始时完全没有打包。你会编写导入.vue文件或TS文件的代码,这些会作为HTTP请求发送到开发服务器,服务器找到.vue文件,即时编译成JavaScript并返回。这一切都依赖于浏览器中原生的ES模块支持。”
插件系统设计
“我们需要一个既能用于打包器又能用于开发服务器的插件系统。我注意到了Jason Miller创建的WMR项目,它有一个’rollup插件容器’的概念 - 这是一个模拟容器,能够运行rollup插件而无需实际运行rollup本身。”
热模块替换的技术实现
性能突破
“Vite最大的贡献是向人们展示了热模块替换能有多快。人们开始认为做Web开发时,保存文件后变化应该立即反映在页面上是理所当然的。”
技术原理
“Webpack设计了热模块替换API,我们的实现参考了它。它有一个叫做热模块替换边界的概念。你需要对代码进行一些插桩来表明’这个模块是一个HMR边界’,这意味着当它依赖的文件被修改时,变化会冒泡传播到边界并被拦截。”
安全考虑与生产构建
开发服务器安全
“当你有一个未打包的开发服务器时,默认情况下会提供当前目录下的所有文件。如果用户将开发服务器直接暴露在网络中,用户将能够访问你Vite应用根目录下的任何文件。”
生产优化
“对于生产构建,我们仍然需要打包器,因为不能直接发送所有这些模块 - 加载会太慢。打包器具有更复杂的能力:代码压缩、代码分割等。”
未来发展方向
Rust集成
“我们正在将Rolldown和Oxc集成到Vite中,这样我们就有一个完全由Rust驱动的垂直技术栈,速度极快且性能更好。”
Vite Plus工具链
“我们正在构建名为Vite Plus的统一工具链:想象一下Vite但功能更强大。它不仅包含Vite开发和Vite构建,还有Vite链接、Vitest、Vite格式化,并在monorepo中智能缓存。”
开源社区协作
Evan You强调了开源协作的重要性:“Vite和Vue都是已经超越其创建者的项目。它们是社区现在。不可避免地,你使用的一些想法来自其他人,可能在某处有层层灵感链。”
通过这次技术对话,我们看到了现代前端构建工具从简单的文件拼接发展到今天复杂生态系统全过程,以及Vite在其中扮演的关键角色。