Skip to content

Vite ​

优缺点 ​

优点 ​

  1. 极快的冷启动速度
    Vite 利用浏览器原生 ES 模块(ESM)支持,采用按需编译策略,无需像 Webpack 那样预先构建整个应用。冷启动时间可缩短至毫秒级,即使是大型项目也能瞬间启动。
  2. 即时热更新(HMR)
    通过 ES 模块的局部更新机制,Vite 的 HMR 响应速度比传统工具快 10 倍以上,且状态保留更可靠。修改代码后,页面几乎瞬间更新,极大提升开发体验。
  3. 内置丰富功能
    开箱即用支持 TypeScript、JSX、CSS Modules 等现代前端技术。
  4. 自动处理 CSS 预处理器(如 Sass、Less)和 PostCSS。
    内置优化的图片处理和资源导入。

缺点 ​

  1. 生态成熟度较低
    作为较新的工具,部分小众库或旧版依赖可能存在兼容性问题,需要额外配置或等待社区适配。
  2. 生产环境构建性能
    虽然 Vite 在开发阶段性能卓越,但生产环境默认使用 Rollup 打包,大型项目的构建速度可能不如专门优化的 Webpack 配置。
  3. 调试复杂度
    由于 Vite 在开发阶段使用不同的模块解析策略(ESM vs CommonJS),某些依赖的调试可能比传统工具更复杂。
  4. SSR 支持有限
    虽然 Vite 提供 SSR 功能,但相比 Next.js 等专用框架,生态和文档支持仍有待完善。

总结 ​

  1. 推荐使用:中小型项目、现代框架(React/Vue)应用、需要快速迭代的开发场景。
  2. 谨慎使用:依赖复杂 CommonJS 模块的项目、需要高度定制构建流程的企业级应用。

本地开发运行机制 ​

  1. 依赖预构建
    • Vite在本地服务器冷启动时会使用esbuild将项目的第三方依赖打包到 node_modules/.vite/ 目录下
    • 默认只有package.json或者lock文件中的依赖发生变化时才会重新打包依赖
    • 也可以通过配置项 optimizeDeps 设置发生变化需要更新的依赖项
    • 打包好的依赖在请求时会被浏览器进行强缓存,只有依赖发生变化或者强刷页面后才会重新请求
    • 预构建的目的主要有两个
      • 将CommonJS和UMD模块都转换成ES Module
      • 将包含多个内部模块的 ES Module 转换成不同的单个模块,如 lodash-es
  2. 项目代码构建
    • 本地开发时会根据项目代码文件的不同后缀进行不同的处理
      • 静态资源默认会通过 export default 的方式将文件URL作为模块内容导出
      • JSON文件则是通过JSON.parse解析后再由 export default导出
      • JS/TS/JSX/TSX会使用 esbuild 进行转换,但esbuild在处理TS时不会进行类型校验,只是将TS的类型声明给去除
      • CSS文件通过内置的 PostCSS 预处理器去进行转换,但是需要手动安装预处理器依赖
      • Vue和React等文件则是需要使用Vite的插件去进行处理
    • 所有的项目代码在本地开发时都会被处理成ES Module,并通过相对路径的方式由浏览器自行引入并解析
      • @rollup/plugin-commonjs 插件可以用来将CommonJS转换为ESM
  3. 热更新
    • 开发服务器启动时,会在index.html中插入一段JS代码,用于创建一个WebSocket链接
    • 通过chokidar对项目根目录进行监听,但是会忽略node_modules、gitignore等目录和文件
    • 当文件发生变化时会根据文件类型进行不同的更新处理
      • package.json —— 相当于更新了项目的第三方依赖,会重新进行依赖的预构建
      • config或者env —— 配置信息变更直接重启开发服务器
      • 项目代码 —— 根据项目代码的类型进行不同的处理
    • ws的服务端在处理完成文件更新之后,会把当前HMR的类型,文件的路径信息等返回给客户端
    • 客户端根据HMR的类型进行不同的处理,对于普通文件的话直接走ESM的动态加载最终完成一次HMR

Plugin (插件) ​

概念 ​

  • 基于Rollup的插件机制单独实现了一套Vite插件
  • 所有的文件转换都在插件中实现,一个插件可以实现Webpack中loader和plugin的效果
  • Vite默认内置一些插件,可以通过插件的enforce配置来强制设置插件调用顺序(在内置前或者后执行)
  • 通过apply配置可以设置插件在开发或生产阶段调用
  • 每一个插件将返回一个对象,包含一个name字段,用于表示插件的名称,其他的插件钩子函数用于执行插件的逻辑

独特的hook ​

  1. config: 用途:动态修改 Vite 配置。
    区别于 Rollup:Rollup 没有专门的配置钩子,需通过命令行参数或配置文件静态定义。

  2. configResolved: 用来记录最终的配置信息。

  3. configureServer: 用途:扩展开发服务器(如添加中间件、自定义路由)。
    区别于 Rollup:Rollup 专注于构建,无开发服务器概念。

  4. transformIndexHtml: 用途:转换 HTML 入口文件(如注入脚本、修改 meta 标签)。

  5. handleHotUpdate: 用来进行热更新模块的过滤,或者进行自定义的热更新处理。

  6. transformWithEsbuild:使用 esbuild 执行快速转换(如 TypeScript、JSX)。
    优势:比纯 JavaScript 实现的转换工具快 10-100 倍。

  7. buildStart 和 buildEnd(带 Vite 上下文)
    用途:在构建开始 / 结束时执行自定义逻辑(如清理临时文件)。
    区别于 Rollup:可访问 Vite 特定的构建上下文(如 ssrBuild 标志)。

  8. resolveId 和 load(增强的模块解析)
    用途:自定义模块解析逻辑(如处理非标准导入路径)。
    Vite 扩展:支持 request 参数中的 ssr 标志,区分 SSR 和客户端构建。

  9. transform(带 Vite 元信息)
    用途:转换模块内容(如编译 SASS、处理图片)。
    Vite 扩展:transform 钩子的第二个参数包含 Vite 特有的元信息(如 server、ssr)。

hooks

Esbuild优势 ​

主要原因是构建速度

  1. Esbuild 则选择使用 Go 语言编写,该编译型语言可以编译为原生代码,在编译的时候都将语言转为机器语言,在启动的时候直接执行即可,在 CPU 密集场景下,Go 更具性能优势。
  2. 并行处理:esbuild 可以充分利用多核 CPU 并行解析和转换代码。
  3. 内存效率高:Go 语言的内存管理更高效,避免了 JavaScript 运行时的垃圾回收开销。

还有一些其他原因

  1. 内置支持TS、JSX、CSS等现代前端技术栈,无需额外配置