Skip to content

Vite

esbuild 为什么快?

  1. go 的语言优势 js 的解释型语言的特质决定了在执行中需要不断的解释执行的过程,Go 语言编写的程序比 JavaScript 少了一个动态解释的过程;实际 go 代码执行时是开的多进程
  2. 代码实现上: esbuild 使用比较克制,很多在 webpack 上使用插件实现的功能 如 loader, minify 等插件均使用的 go 实现的,在实际构建过程中,较少的插件,保证了结构的一致性(主要指 ast 处理,在 webpack 的处理中,需要对一个文件做 ast 处理,是 webpack → 字符串 → ast → 字符串 → webpack 这样的一个过程,如果是多个 babel 则有多个这样的过程,esbuild 在实现过程中将这些 babel 直接写进了 go 代码中,所以保证了结构一致性。),提升了构建速度。

所以其本身也有很多缺点

  1. 热加载功能的缺失。
  2. 不支持按需引入

对于第三方包 如 lodash 等 不支持按需引入而是在开发阶段全部载入(loadsh.js),现在 Vite 上有插件去转换

  1. esbuild 不是像 webpack 一样的大一统项目,提供完善的插件机制,而是在极度精简之后的打包工具,快是 esbuild 追求目标。

为什么 Vite 会比 Webpack 快

  1. 按需编译方面
  • Vite: 只需要编译当前访问的模块,不需要编译所有模块
  • Webpack: 所有模块都需要编译
  1. 编译方面
  • Vite: 使用 esbuild 编译,esbuild 是用 go 编写的,编译速度快
  • Webpack: 使用 babel 编译,babel 是用 js 编写的,编译速度慢
  1. 预构建方面
  • Vite: 预构建方面,Vite 会在开发服务器启动时预构建所有依赖项,包括依赖项的依赖项,这样可以确保所有依赖项都是最新的,并且可以立即使用。
  • Webpack: Webpack 是不支持预构建的。
  1. HMR 方面
  • Vite: Vite 的热更新是基于浏览器的原生 ESM 支持实现的,所以 Vite 热更新的性能是非常高效的
  • Webpack: Webpack 热更新的实现原理是基于 webpack-dev-server 插件,当文件发生变化时,webpack-dev-server 会重新编译文件,并将新的文件发送到浏览器,浏览器收到新的文件后,会重新执行文件或者重新加载整个页面,这个过程需要浏览器重新解析文件,所以 Webpack 热更新的性能是比较低的
  1. 产物方面
  • Vite: 产物产物是 es 模块,浏览器可以直接解析
  • Webpack: 产物是 commonjs 模块,浏览器不能直接解析,需要额外的处理
  • Vite: 只需要编译

说说你对 Vite 的理解,什么是 bundleless

想要了解 bundleless,需要先了解 模块化的概念, 特别是在 Chrome 等原生支持 ESModule 的情况下就催生了 bundleless 的概览,其不需要从入口文件开始将依赖的文件打包成一个 js 文件,而是在浏览器加载模块时按需去加载,对于原生的 js 文件,直接通过浏览器的解析,所以速度是最快的,对于其他原生不支持的,如 jsx、tsx、vue、scss 等先经过编译,再通过浏览器解析。这样就可以少了整个的收集、编译、转换、打包的过程。

但是其本身也存在一些问题: 如 1. 只支持 js 文件,不支持其他的文件类型 2. 文件碎片化严重 3. 不支持 HMR 等

其他文件的支持

  • 对于 tsx、jsx、ts => esbuild
  • 对于 css => postcss

那么对于这些就通过插件化的方式去支持, 如 @vitejs/plugin-vue@vitejs/plugin-react-swc@vitejs/plugin-legacy

esbuild 编译其他文件

为什么 Vite 在开发阶段用 esbuild 在生产阶段用 rollup

  1. esbuild:
  • 优点:
    • 强调性能,内置了对 css、图片、react、typescript 等内置支持,
    • 编译速度特别快(是 webpack 和 rollup 速度的 100 倍+),
  • 缺点
    • 是目前插件系统较为简单,生态不如 webpack 和 rollup 成熟。
  1. rollup: 强调对库开发的支持,基于 ESM 模块系统,对 tree shaking 有着良好的支持,产物非常干净,支持多种输出格式,适合做库的开发,插件 api 比较友好,缺点是对 cjs 支持需要依赖插件,且支持效果不佳需要较多的 hack,不支持 HMR,做应用开发时需要依赖各种插件。
  2. webpack :
  • 优点: 强调对 web 开发的支持
    • 内置了 HMR 的支持,
    • 插件系统比较强大,对各种模块系统兼容性最佳(amd,cjs,umd,esm 等,兼容性好的有点过分了,这实际上有利有弊,导致面向 webpack 编程),
    • 有丰富的生态
  • 缺点
    • 产物不够干净
    • 产物不支持生成 esm 格式
    • 插件开发上手较难,不太适合库的开发
    • 性能较低:

原因: 1. 整个使用 js 进行构建,作为解释性语言 在这种 CPU 密集型场景下 性能是比较低的 2. 插件系统的兼容性过高,其主要通过 babel 等对 js 进行转换,而 babel 又是一个比较重的库,所以其对性能的影响是比较大的。3. 在处理构建的过程中其 loader 进行了多次的 parse => transform => generate , 而不想 rollup 等其都是一次转换成 AST , 多次 transform 的过程

Vite 的优缺点

缺点

  1. 开发环境、生产环境构建机制不一致

因为其开发环境使用 esbuild 生产环境使用的是 rollup ,但是承诺之后会用 Rolldown 来彻底解决这类问题

  1. 大型项目开发期间页面刷新缓慢

每个页面的请求数太多,瓶颈其实发生在浏览器和 DevTools 上。而背后的原因是 Vite 直接把 ES 模块直接发送到浏览器的机制

怎么设计一个打包工具