Vite 依赖的 esbuild 的理解

917 阅读3分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。

前面我们已经看到,Vite 的打包速度非常快,除了它有预打包的功能,还有一个原因是它使用了 esbuild

image-20211221214321619

esbuild 是什么东西?esbuild 是一个非常快的 JavaScript 打包工具。它有以下特点:

  • 超快的构建速度,快到不需要使用缓存(而如果我们使用 babel 去转换代码,babel 还可以利用缓存以提升效率,之前转化过的文件下次可能就不再做转化了);

    image-20211221123952056

  • 支持 ES6 模块和 CommonJS 模块(所以如果我们通过 esbuild 去打包我们的 js 代码时,我们的 js 代码既可以使用 ES6,也可以使用 CommonJS,但最好还是用 ES6,因为用 ES6 的话很多代码直接就不需要再做转化了);

  • 支持 ES6 模块的 Tree shaking(摇树,即把我们代码中从来没用过的代码删除掉,比如某个从未被调用过的函数就会被删除掉);

  • 支持通过 JavaScriptGo 访问的 APIesbuild 是通过 Go 语言实现的,而 babel 是用 JavaScript 实现的);

  • 支持 TypeScriptJSX 语法;

  • 支持 SourceMap

  • 支持代码压缩;

  • 支持扩展其它插件(这个和 babel 一样,babel 也支持扩展插件);

因此,你会发现,esbuild 的功能和 bable 很像,但是相对于 babel 来说,esbuild 的速度更快,能做的事情也更多(比如它还支持代码压缩、支持 GoAPI、支持 ES6tree shakingWebpack 也支持 tree shaking,但也需要做相关的配置),而这些 babel 做不了)。所以 esbuild 相当于有 babel 的功能,同时又拥有类似于 Webpack 工具提供的一些功能。

但是,esbuild 目前对于有些语法特性可能是不支持的,所以现在并不是说有很多工具都在使用它。但 Vite 选择了 esbuild 对代码进行构建,所以速度非常快,这也是 Vite 速度快的另外一个原因。

那么,esbuild 为什么这么快呢?有以下几个原因:

  • esbuild 是用 Go 语言编写的,可以直接转换成机器代码(机器码可以直接在操作系统上运行,所以速度很快),而无需经过字节码(而 JavaScript 代码的执行会有这么一个过程:JavaScript 代码先进行解析,解析成 ASTAST 之后会转成字节码,然后 V8 引擎会读取字节码,并对字节码做运行,但在真正运行字节码前,V8 引擎其实还会对字节码再做一些转换的。**总之,在执行 JavaScript 代码的过程中,会存在转换为字节码这一过程。**当然,V8 也会做一些优化,它会把我们经常执行的一些字节码转成机器码,之后再运行到这些代码效率就会更高些);
  • esbuild 可以充分利用 CPU 的多内核(esbuild 在对代码进行转换时会开启一个新的进程,在这个进程中它会根据当前主机 CPU 的内核数开启多个线程(因为线程是可以运行在内核里的)),尽可能让它们饱和运行;
  • esbuild 的所有内容都是从零开始编写的,而不是使用(依赖)很多第三方的包(而像 Vite 就有依赖 Connect 包,Webpack 就有依赖 memfs 包等许多第三方包,而如果第三方包本身就存在性能问题,那么使用了它开发出来的工具最终肯定也会存在性能问题),所以从一开始就可以考虑各种性能问题;
  • 等等

更多关于 esbuild 的内容可以查阅官方文档:esbuild.github.io/esbuild.github.io/faq/#why-is…