
Vite 2.0 技术解析框架无关核心、依赖预构建、CSS 一等支持与 SSR 的落地【免费下载链接】viteNext generation frontend tooling. Its fast!项目地址: https://gitcode.com/GitHub_Trending/vi/vite本文以 Vite 官方 2.0 发布公告为骨架完整拆解 Vite 2.0 的五大核心能力——框架无关的核心架构、Rollup 兼容的新插件体系、esbuild 驱动的依赖预构建、一等公民级 CSS 支持以及实验性 SSR——并结合当前仓库中的源码实现依赖预构建调度器、SSR 模块加载、legacy 插件 等逐项印证这些设计在代码层面是如何落地的。读完本文你将理解 Vite 2.0 各特性的设计动机与实现原理并能对照仓库源码定位其关键实现位置。背景Vite 2.0 在 Vite 演进史中的位置Vite法语中快速的意思发音 /vit/是一种面向前端 Web 开发的新型构建工具可以理解为一个预配置好的开发服务器 打包器组合但更轻、更快。它利用浏览器的原生 ES Modules 支持以及 esbuild 等编译到原生语言的编译工具提供流畅的现代开发体验。公告中特别强调了一点由于团队在 1.0 发布前就决定彻底重构内部实现Vite 2.0 实际上是 Vite 的第一个真正稳定的版本first stable release。也就是说1.x 时期的快速迭代都被视为 RC 前的探索2.0 才是架构定型后的起点。公告同时建议想了解 Vite 设计动机的读者阅读 Why Vite想看后续演进可继续阅读 Vite 3.0 发布公告。当前仓库中的 vite 包 版本已演进到 8.x描述为 Native-ESM powered web dev build tool底层工具链也已从 esbuild Rollup 统一迁移到 Rust 编写的 Rolldown。但 2.0 奠定的五大能力——框架无关核心、插件格式、依赖预构建、CSS 支持与 SSR——至今仍是 Vite 的架构支柱这也是本文以 2.0 公告为主线的价值所在。框架无关的核心Framework Agnostic Core从 Vue 专用原型到框架无关公告中回顾了 Vite 的起源最初它是一个服务于 Vue 单文件组件SFC的原生 ESM hack 原型Vite 1 则是这个思路的延续在其上实现了 HMR热模块替换。Vite 2.0 吸取了早期经验从零重新设计了内部架构核心原则是框架无关framework agnostic所有框架特定的支持全部委托给插件处理。公告发布时已提供 Vue、React、Preact、Lit Element 的官方模板Svelte 集成也在社区推进中。在当前仓库中的印证这一框架无关的设计在仓库目录结构中依然清晰可见packages/create-vite 中的官方模板覆盖 vanilla、vue、react、preact、lit、qwik、solid、svelte 等全家桶每个框架各有一对 JS/TS 模板如template-react与template-react-ts模板本身只是静态脚手架不依赖 Vite 内部的框架逻辑框架相关能力全部以插件形式存在仓库根目录下的 monorepo 包含 plugin-legacy 等官方插件包而 Vue/React 等框架编译器插件则交由各自的社区插件包如vitejs/plugin-vue等不在本仓库内实现Vite 内核只负责加载与编排插件。从 create-vite 的 package.json 可见模板包本身只是一个 CLIcreate-vite/cva命令职责就是复制模板并安装依赖——这正是核心不感知框架理念的体现。新的插件格式与 API设计扩展 Rollup 插件接口公告指出新的插件系统受 WMRPreact 团队启发扩展了 Rollup 的插件接口关键特性包括与大量现有 Rollup 插件开箱兼容——现有生态的 Rollup 插件可以近乎零成本地在 Vite 中工作插件可以使用 Rollup 兼容的钩子同时拥有 Vite 特有的钩子和属性用于调整 Vite 独有行为例如区分 dev开发与 build构建两种场景自定义 HMR 处理逻辑改进后的编程 API方便在 Vite 之上构建更高层的工具和框架。在当前仓库中的印证插件体系的核心实现在 packages/vite/src/node/plugin插件解析与 hook 调用编排以及内置插件目录 packages/vite/src/node/plugins 下该目录下的css.ts、importAnalysis.ts、esbuild.ts、worker.ts、manifest.ts等文件正是公告中框架无关核心 内置能力插件化思路的具体产物——每个能力都是一个独立插件而非硬编码进服务器主流程插件 API 与编程 API 的完整文档见 插件 API 和 JavaScript API。值得注意的架构细节从 plugins 的组织方式可以推断Vite 内置插件按功能域切分解析、CSS、资源、Worker、Manifest……框架作者只需在 Rollup 兼容钩子之上实现自己的插件即可接入整条管线这正是 2.0 公告所承诺的扩展性。esbuild 驱动的依赖预构建Dep Pre-Bundling这是 2.0 公告中性能提升最显著的一项。为什么需要预构建Vite 是基于原生 ESM 的开发服务器浏览器会直接以 ESM 方式加载模块。这带来两个必须解决的问题当前仓库的 依赖预构建文档 完整解释了这一点CommonJS / UMD 兼容性开发时所有代码都以原生 ESM 形式提供因此必须以 ESM 形式先转换 CJS/UMD 依赖并做智能 import 分析使得对动态赋值导出的 CJS 模块如 React的命名导入也能正常工作// works as expected import React, { useState } from react性能一些包把 ESM 构建拆成数百个内部互相引用的文件文档以 lodash-es 有 600 内部模块为例如果不预构建浏览器会同时发起数百个 HTTP 请求造成网络拥塞、页面明显变慢。预构建将其合并为单一模块后只需 1 个请求。2.0 的关键变化esbuild 取代 Rollup公告明确指出此前 Vite 1 用 Rollup 做预构建2.0 改用 esbuild使依赖预构建速度提升10-100 倍。公告给出的参考数据在一个包含 React Material UI 等重依赖的测试应用上冷启动M1 MacBook Pro 上从28 秒降到约 1.5 秒。在当前仓库中的印证预构建的完整实现位于 packages/vite/src/node/optimizer包含optimizer.ts预构建调度器。可以看到createDepsOptimizer会为每个开发环境创建独立的优化器实例通过 100ms 的 debounce 合并新发现依赖触发的重复重打包并在重打包完成后自动触发页面重载对应 文档 中服务器运行中发现新依赖会重新 pre-bundle 并刷新页面的描述scan.ts依赖扫描器即自动依赖发现爬取源码中的 bare import 作为预构建入口的实现rolldownDepPlugin.ts当前版本中预构建打包器相关的插件逻辑。这里有一个重要的版本事实当前仓库中的 Vite 已用 RolldownRust 编写替代 esbuild 作为预构建引擎——依赖预构建文档 明确写道 The pre-bundling is performed with Rolldown, so its typically very fast。也就是说2.0 时esbuild 带来 10-100x 提升的演进方向后来进一步延续为全链路 Rust 化但预构建的整体模型发现 → 扫描 → 打包 → 缓存 → 服务保持不变。配套的定制能力也值得掌握详见 dep-optimization-optionsoptimizeDeps.include/exclude显式包含/排除依赖典型场景是插件 transform 后才产生的、初次扫描发现不了的 import缓存预构建产物缓存于node_modules/.vite是否重跑取决于 lockfile 内容、patches 目录修改时间、vite.config.js中相关字段、NODE_ENV等可用--force强制重打包。一等公民级的 CSS 支持公告列出了 Vite 2.0 对 CSS 的三项开箱即用能力这些能力在 内置 CSS 插件 中实现解析器增强Resolver enhancementCSS 中的import和url()路径会经过 Vite 的 resolver 增强使其遵循别名alias配置并能解析 npm 依赖中的资源URL rebasingurl()中的路径会自动基于资源最终服务位置而非导入方文件位置重新计算因此无论从哪个目录导入同一个 CSS其相对资源引用都指向正确CSS 代码分割CSS code splitting一个代码分割的 JS chunk 会同时产出对应的 CSS 文件请求该 JS chunk 时对应的 CSS 会被自动并行加载。公告的原始表述完整继承Vite treats CSS as a first-class citizen of the module graph and supports the following out of the box:Resolver enhancement:importandurl()paths in CSS are enhanced with Vites resolver to respect aliases and npm dependencies.URL rebasing:url()paths are automatically rebased regardless of where the file is imported from.CSS code splitting: a code-split JS chunk also emits a corresponding CSS file, which is automatically loaded in parallel with the JS chunk when requested.这三项能力在仓库中均有对应的测试用例可验证例如CSS 代码分割playground/css-codesplit 与 playground/css-no-codesplitimport、url()rebasing、模块化 CSS.module.css等playground/css 及其 子目录含 less/sass/stylus 预处理链。服务端渲染SSR支持公告中的设计要点Vite 2.0 随附实验性 SSR 支持完整文档见 SSR 指南核心设计有三点高效的 ESM 源码加载与更新Vite 提供一组 API让 Node.js 端在开发期间能高效加载并更新基于 ESM 的源码——几乎像服务端 HMR编辑文件后 SSR 输出立即更新无需重启依赖外部化externalization自动将 CommonJS 兼容的依赖 externalize 掉即用 Node 原生的require加载从而提升开发服务器响应速度和 SSR 构建速度生产服务器与 Vite 解耦生产环境的服务端可以完全不依赖 Vite 运行同一套配置也容易被改造为预渲染 / SSG。公告还强调Vite SSR 是作为**低层能力low-level feature**提供的预期是更高层的框架在其之上构建例如当时的 Nuxt 3、SvelteKit 等。在当前仓库中的印证SSR 相关源码集中在 packages/vite/src/node/ssrssrModuleLoader.tsSSR 模块加载器对应Node.js 端加载与更新 ESM 源码的能力ssrTransform.tsSSR 场景下的模块转换将浏览器端的 import/导出语义转译为 Node 可执行的 ESMssrManifestPlugin.tsSSR manifest 生成支撑生产服务器与 Vite 解耦——构建时生成资源清单生产端按清单按需加载 CSS/资源即可无需 Vite 本身fetchModule.ts 等文件则服务于按需拉取模块的场景。依赖外部化的策略由 external.ts 与 nodeResolve.ts 共同决定行为可用 playground/ssr 与 playground/ssr-deps 中的测试用例交叉验证后者专门覆盖 SSR 场景下依赖 externalize 的各种组合。可选的 Legacy 浏览器支持vitejs/plugin-legacyVite 默认目标是支持原生 ESM 的现代浏览器但通过官方插件 vitejs/plugin-legacy 可以**选择性地opt-in**为旧浏览器提供兼容。公告中的原始承诺The plugin automatically generates dual modern/legacy bundles, and delivers the right bundle based on browser feature detection, ensuring more efficient code in modern browsers that support them.即自动生成 modern/legacy 双份构建产物基于浏览器特性检测分发正确的产物确保支持 ESM 的现代浏览器继续拿到高效的原生 ESM 代码。当前仓库中该插件位于 packages/plugin-legacyREADME 完整说明了其默认行为与全部选项默认行为引用自 plugin-legacy README为最终 bundle 中的每个 chunk 生成对应的 legacy chunk经babel/preset-env转换并以SystemJS 模块形式产出仍支持代码分割生成 polyfill chunk包含 SystemJS 运行时以及根据浏览器目标与实际使用useBuiltIns: usage检测决定的必要 polyfill向生成的 HTML 注入script nomodule标签仅在特性缺失的浏览器中加载 polyfills 与 legacy bundle注入import.meta.env.LEGACY环境变量仅 legacy 生产构建中为true。典型用法// vite.config.js import legacy from vitejs/plugin-legacy export default { plugins: [ legacy({ targets: [defaults, not IE 11], }), ], }核心选项速览完整说明见 plugin-legacy README选项类型默认值说明targetsstring \| string[] \| { [key: string]: string }last 2 versions and not dead, 0.3%, Firefox ESR传给babel/preset-env决定 legacy chunk 的语法降级目标兼容 Browserslist 语法会自动读取项目的 browserslist 配置modernTargetsstring \| string[]edge105, firefox106, chrome105, safari16.4, chromeAndroid105, iOS16.4收集 modern chunk polyfill 时的目标仅在renderLegacyChunks为false时使用polyfillsboolean \| string[]true是否/如何生成 legacy polyfill chunk传字符串数组可显式指定 core-js 模块additionalLegacyPolyfills/additionalModernPolyfillsstring[]—手动追加 DOM API polyfillusage 检测只覆盖 ES 语法特性modernPolyfillsboolean \| string[]false为 modern 构建单独生成 polyfill chunkREADME 明确提示 core-js3 的自动检测非常激进不建议无脑开truerenderLegacyChunksbooleantrue设为false可只输出 modern 构建把插件降级为仅向 modern 构建注入 polyfillexternalSystemJSbooleanfalse设为true时不内联systemjs/dist/s.min.js改为外部引用renderModernChunksbooleantrue设为false时只输出 legacy bundle也适用于file:协议下本地打开的场景另外两点实操细节使用terser压缩时需安装 terser若项目有严格 CSP需引入导出的cspHashes将内联脚本哈希加入script-src白名单值会随次版本变化建议动态生成而非硬编码。测试验证可参考 playground/legacy含__tests__下的 10 个测试文件覆盖多输出、自定义文件名、modern target 等场景。快速上手一分钟启动 Vite 应用公告给出的入门方式发布时要求 Node.js 12npm init vitejs/app需要说明的适用前提npm init vitejs/app是 Vite 2.0 时代的命令在当前仓库对应的版本中官方脚手架已演进为create-vite命令为npm create vitelatest my-app当前 create-vite 包 的bin字段暴露了create-vite与cva两个命令且engines要求node ^20.19.0 || 22.12.0。模板目录template-vanilla、template-vue、template-react、template-svelte等均可在 packages/create-vite 下直接查看每个模板都附带最小可运行的index.html、package.json与框架入口文件是理解框架无关核心 模板即框架适配层最直接的教材。小结2.0 五大能力在今天的映射2.0 能力2.0 时的形态当前仓库中的位置框架无关核心内核去 Vue 化框架能力插件化packages/create-vite 模板族 外部框架插件新插件格式扩展 Rollup 插件接口兼容现有 Rollup 插件packages/vite/src/node/plugin.ts、内置插件依赖预构建esbuild 引擎10-100x 提速packages/vite/src/node/optimizer引擎现为 Rolldown一等 CSS 支持解析增强 / URL rebasing / CSS 代码分割css.ts、playground/css-codesplitSSR 支持实验性低层 APIpackages/vite/src/node/ssr、playground/ssrLegacy 浏览器vitejs/plugin-legacy 双产物packages/plugin-legacyVite 2.0 公告的价值在于它定义了 Vite 从快而巧走向稳而全的架构基线框架无关让它可以成为任何框架的底座Rollup 兼容的插件格式让生态平滑迁移预构建让原生 ESM 开发体验可用CSS 与 SSR 补齐了生产级需求。对照当前仓库源码可以确认这些能力不仅被保留而且被持续加深——预构建从 esbuild 演进到 RolldownSSR 从实验性能力成长为支撑整个生态框架的核心运行时这正是阅读 2.0 公告与源码对照时最值得体会的一点。【免费下载链接】viteNext generation frontend tooling. Its fast!项目地址: https://gitcode.com/GitHub_Trending/vi/vite创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考