「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。
前面我们已经看到,Vite 的打包速度非常快,除了它有预打包的功能,还有一个原因是它使用了 esbuild:
esbuild 是什么东西?esbuild 是一个非常快的 JavaScript 打包工具。它有以下特点:
-
超快的构建速度,快到不需要使用缓存(而如果我们使用
babel去转换代码,babel还可以利用缓存以提升效率,之前转化过的文件下次可能就不再做转化了); -
支持
ES6模块和CommonJS模块(所以如果我们通过esbuild去打包我们的js代码时,我们的js代码既可以使用ES6,也可以使用CommonJS,但最好还是用ES6,因为用ES6的话很多代码直接就不需要再做转化了); -
支持
ES6模块的Tree shaking(摇树,即把我们代码中从来没用过的代码删除掉,比如某个从未被调用过的函数就会被删除掉); -
支持通过
JavaScript或Go访问的API(esbuild是通过Go语言实现的,而babel是用JavaScript实现的); -
支持
TypeScript和JSX语法; -
支持
SourceMap; -
支持代码压缩;
-
支持扩展其它插件(这个和
babel一样,babel也支持扩展插件);
因此,你会发现,esbuild 的功能和 bable 很像,但是相对于 babel 来说,esbuild 的速度更快,能做的事情也更多(比如它还支持代码压缩、支持 Go 的 API、支持 ES6 的 tree shaking(Webpack 也支持 tree shaking,但也需要做相关的配置),而这些 babel 做不了)。所以 esbuild 相当于有 babel 的功能,同时又拥有类似于 Webpack 工具提供的一些功能。
但是,esbuild 目前对于有些语法特性可能是不支持的,所以现在并不是说有很多工具都在使用它。但 Vite 选择了 esbuild 对代码进行构建,所以速度非常快,这也是 Vite 速度快的另外一个原因。
那么,esbuild 为什么这么快呢?有以下几个原因:
esbuild是用Go语言编写的,可以直接转换成机器代码(机器码可以直接在操作系统上运行,所以速度很快),而无需经过字节码(而JavaScript代码的执行会有这么一个过程:JavaScript代码先进行解析,解析成AST,AST之后会转成字节码,然后V8引擎会读取字节码,并对字节码做运行,但在真正运行字节码前,V8引擎其实还会对字节码再做一些转换的。**总之,在执行JavaScript代码的过程中,会存在转换为字节码这一过程。**当然,V8也会做一些优化,它会把我们经常执行的一些字节码转成机器码,之后再运行到这些代码效率就会更高些);esbuild可以充分利用CPU的多内核(esbuild在对代码进行转换时会开启一个新的进程,在这个进程中它会根据当前主机CPU的内核数开启多个线程(因为线程是可以运行在内核里的)),尽可能让它们饱和运行;esbuild的所有内容都是从零开始编写的,而不是使用(依赖)很多第三方的包(而像Vite就有依赖Connect包,Webpack就有依赖memfs包等许多第三方包,而如果第三方包本身就存在性能问题,那么使用了它开发出来的工具最终肯定也会存在性能问题),所以从一开始就可以考虑各种性能问题;- 等等
更多关于 esbuild 的内容可以查阅官方文档:esbuild.github.io/ 、esbuild.github.io/faq/#why-is…