本文档解释了 Vite 在开发过程中如何分析源代码中的导入语句以及解析模块说明符为实际文件路径。该系统是 Vite 能够原生在浏览器中提供 ES 模块服务并处理复杂模块解析场景的基础。
有关构建过程中导入重写的信息,请参阅 构建过程。有关预打包优化依赖项的详细信息,请参阅 高级功能。
Vite 的导入分析和模块解析系统主要在开发期间运行,以将源代码导入转换为浏览器兼容的 URL。该系统包含两个主要协同工作的组件:
导入分析和解析流程
importAnalysisPlugin 和 resolvePlugin 协同工作,处理导入并生成浏览器兼容的模块 URL。
来源:packages/vite/src/node/plugins/importAnalysis.ts221-251 packages/vite/src/node/plugins/resolve.ts160-172
导入分析系统由 importAnalysisPlugin 实现,该插件在开发期间运行,用于解析和转换导入语句。
导入分析组件流程
该插件使用 es-module-lexer 解析导入,并跟踪 HMR 的绑定。
分析过程遵循以下关键步骤:
es-module-lexer 提取导入说明符。MagicString 在原地更新导入语句。来源:packages/vite/src/node/plugins/importAnalysis.ts256-280 packages/vite/src/node/plugins/importAnalysis.ts143-190
不同类型的导入会得到不同的处理。
| 导入类型 | 示例 | 转换 |
|---|---|---|
| 裸导入 | import 'vue' | import '/@fs/project/node_modules/vue/dist/vue.js' |
| 相对导入 | import './utils' | import './utils.js' |
| CSS 导入 | import './style.css' | import './style.css.js' |
| 动态导入 | import('./module') | import('./module.js') |
| 资源导入 | import './image.png' | import './image.png?import' |
来源:packages/vite/src/node/plugins/importAnalysis.ts600-650 packages/vite/src/node/plugins/importAnalysis.ts450-500
resolvePlugin 实现了 Vite 的模块解析算法,并用特定的策略处理不同类型的模块说明符。
模块解析决策树
解析器遵循基于优先级的处理不同导入模式的方法。
来源:packages/vite/src/node/plugins/resolve.ts175-450 packages/vite/src/node/plugins/resolve.ts1400-1800
对于文件系统路径和相对导入,tryFsResolve 处理:
.js、.ts、.tsx 等)index.js、index.ts)package.json 的 browser 字段映射对于裸导入,tryNodeResolve 实现 Node.js 风格的解析:
package.json 的 exports 字段处理main、module、browser)preserveSymlinks 选项处理符号链接来源:packages/vite/src/node/plugins/resolve.ts800-1200 packages/vite/src/node/plugins/resolve.ts1400-1800
解析系统与 Vite 的依赖项优化紧密协作,以处理预打包的依赖项。
依赖项优化集成
解析器在回退到常规 Node 解析之前会检查优化后的依赖项。
集成点包括:
isOptimizedDepUrl() 检查导入是否匹配已优化的依赖项。ensureVersionQuery() 添加浏览器缓存清除参数。来源:packages/vite/src/node/plugins/resolve.ts223-238 packages/vite/src/node/plugins/resolve.ts356-384
解析后,导入 URL 必须进行规范化以确保浏览器兼容性。
normalizeResolvedIdToUrl 函数处理多种转换场景:
/@fs/ 前缀。\0 前缀以进行进一步处理。URL 规范化策略
根据其位置和类型,不同的已解析路径会得到不同的 URL 处理。
来源:packages/vite/src/node/plugins/importAnalysis.ts104-141
CSS 导入会得到特殊处理,以与 Vite 的 CSS 处理管道协同工作。
.js 后缀以进行 JS 模块转换。?inline 和 ?raw 查询会修改处理行为。动态导入需要特殊解析以提取:
该系统为解析失败提供详细的错误报告:
来源:packages/vite/src/node/plugins/importAnalysis.ts270-290 packages/vite/src/node/plugins/css.ts258-266 packages/vite/src/node/plugins/resolve.ts425-450
这个导入分析和模块解析系统使 Vite 能够原生提供 ES 模块服务,同时保持与 Node.js 生态系统的兼容性,并通过 HMR 提供快速的开发反馈。