Skip to content
标签
note
字数
1971 字
阅读时间
8 分钟

背景

过去几年里,前端又推出了一堆新的构建工具🔧,例如像以轻量快速著称的 snowpack(目前已经不维护了,并推荐使用 Vite)、编译速度超越 Babel 几十倍的 SWC、打包和压缩资源速度惊人的 esbuild,以及如今呼声最高,被誉为前端下一代构建工具的 Vite。这么多的工具的推出,让以前一家独大的 webpack 突然失去的声音,甚至前端构建领域掀起了一场 去webpack 的浪潮🌊。今天就让我们简单了解下这些构建工具的代表 SWCesbuildVite

turbopack

增量响应式系统,又有 Rust 的速度加持

Turbopack 是建立在 Turbo 之上的,Turbo 是基于 Rust 的开源、增量记忆化框架。Turbo 可以缓存程序中任何函数的结果。当程序再次运行时,函数将不会重新运行,除非它的参数改变了。这种粒度的架构使您的程序能够在函数级别跳过大量工作

SWC

简介

受限于 JS 的语言本身效率的问题,近几年前端领域出现了不少工具被 Rust 重写,其中就包括编译 JS/TS 文件速度比 Babel 快不少的 SWC,其所对标的工具就是 Babel

image.png

SWC 全称为 Speed Web Compiler,其是基于 Rust 实现的工具,目前被很多前端知名项目(Next.js、Parcel 和 Deno)所使用。

核心功能库

@swc/cli: CLI 命令行工具,可通过命令行编译文件。

@swc/core: 编译转码核心的 API 的集合。

swc-loader: 该模块允许您将 SWC 与 webpack 一起使用。

@swc/wasm-web: 该模块允许您使用 WebAssembly 在浏览器内同步转换代码。

@swc/jest: 该模块可以让 jest 的 tranform 速度更快。

而这些功能库几乎都能在 Babel 找到对应的库,例如 @babel/cli@babel/core、以及 babel-loader 等。也更加印证了 SWC 的竞争对手就是 Babel。

功能介绍

编译 JS 文件

通过将一个 es6 语法的 JS 文件,编译为 es5 的语法来比较两款工具编译能力:

Babel 的编译结果: image.png

SWC 的编译结果: image.png 最终 SWC 只花了 0.12s,Babel 花了 1.08s,SWC 的编译速度约为 Babel 的近 9 倍🚀。

在 webpack 中使用

在 webpack 中 SWC 也可以和 babel 掰掰手腕,SWC 提供了 swc-loader,其实也跟 babel-loader 的作用差不多。

在没有无缓存的情况下比较 babel-loader 与 swc-loader 在 webpack 中的编译情况:

babel-loader 的编译耗时: image.png

swc-loader 的编译耗时:

image.png

最终 swc-loader 只花了 4.89s 就完成了文件编译工作,而 babel-loader 花了 12.56s,可见即使是在 webpack 中,swc 的编译效率依旧很高。

swcpack

swc 的打包能力还在建设中,目前只能在 spack.config.js 文件中进行一些简单的配置,预计在 V2 版本会 SWC 的 bundle 能力会有较大的提升。

js
// spack.config.js
const { config } = require('@swc/core/spack')

module.exports = config({
    entry: {
        'web': __dirname + '/src/index.ts',
    },
    output: {
        path: __dirname + '/lib'
    },
    module: {},
});

配置文件

swc 有自己的配置文件 .swcrc,与 babel 的配置文件不同的是 swc 的配置文件基本做到开箱即用,不需要进行对插件或预设进行二次安装。

js
{
  "jsc": {
    "parser": { 
      // 语法,支持ecmascript和typescript 
      "syntax": "ecmascript", 
      // 是否解析jsx,对应插件 @babel/plugin-transform-react-jsx 
      "jsx": false, 
      // 动态加载 等同于 @babel/plugin-syntax-dynamic-import 
      "dynamicImport": true, 
      // 装饰器 等同于 @babel/plugin-syntax-decorators 
      "decorators": false, 
      //顶层await 等同于@babel/plugin-syntax-top-level-await 
      "topLevelAwait": false, 
      ... 
      // 支持多种编译插件的配置
      },
    // 编译目标 
    "target": "es5", 
    // 等同babel-preset-env的松散配置 
    "loose": false, 
    // 输出代码可能依赖于辅助函数来支持目标环境。
    "externalHelpers": false
  }, 
  // 压缩代码 
  "minify": false
}

详细配置见 官网配置

小结

优势:

  • 编译速度快
  • 迁移成本低,基本可以从 babel 无痛迁移并能覆盖基本的使用场景。

不足:

  • 生态相比于 babel 来说不够完善,用户的覆盖面也不高,某些场景可能会有试错成本。
  • 若需要深入开发的话,需要学习 Rust,有较高的学习成本。
  • SWC 虽然有 bundle 能力,但是 bundle 能力还不太完善,目前其在工程化领域更像是 Compiler(编译工具)。

esbuild

简介

image.png

esbuild 基于 Golang 开发的一款打包构建工具,相比传统的打包构建工具,主打性能优势,在构建速度上可以快 10~100 倍。

下图为 esbuild 和其他的构建工具用默认配置打包 10 个 three.js 库所花费时间的对比,我们能看见 esbuild 比 webpack5 的构建速度快了很多倍。 image.png

为什么能这么快?

根据官网 esbuild 的 FAQ 给出解释,简要总结下 esbuild 相比于传统构建工具有以下优势:

  • 语言优势。esbuild 是基于 go 语言,传统的 JS 开发的构建工具并不适合资源打包这种 CPU 密集场景下,go 更具性能优势。
  • 多线程能力。go 具有多线程运行能力,而 JS 本质上就是一门单线程语言。由于 go 的多个线程是可以共享内存的,所以可以将解析、编译和生成的工作并行化。
  • 从零开始。从一开始就考虑性能,不使用第三方依赖,从始至终是使用的是一致的数据结构从而避免昂贵的数据转换。
  • 内存的有效利用。webpack 的工作机制在经过不同的工具链的时候,都会进行(string => AST => string => ... => string)string 到 AST 的不断转换,这样实际上会占用更多的内存并降低速度。而 esbuild 从头到尾尽可能的共用一份 AST,从而降低内存的占用,提升编译速度。

主要功能

核心 API

esbuild 对外提供了两个核心 API——tranform 和 build,主要功能如下:

  • 支持将 js、ts、jsx、tsx、css 等一系列文件的转译。
  • 支持文件监听和 devServer。
  • 支持 sourcemap。
  • 支持 code-splitting。
  • 支持 tree-shaking 和文件压缩。
  • ...

详细的可见 官方文档

esbuild-loader

也许我们单纯去使用 esbuild 去编译打包我们的项目还是比较麻烦,esbuild 所提供的 esbuild-loader 帮我们解决了这个难题。在 webpack 中我们可以通过 esbuild-loader 体验到惊人的 JS/TS 文件编译的速度和高效的压缩能力。

接下来对比下在 webpack 环境下 esbuild-loaderTerserPlugin 的压缩效率:

TerserPlugin 的压缩耗时: image.png

esbuild-loader 的压缩耗时: image.png

两者压缩之后的 JS 产物的大小几乎没有太大差别,但是 TerserPlugin 所花费的时间是 esbuild-loader 的 10 多倍。

小结

优势:

  • 构建速度非常快
  • 压缩能力也非常强,可支持 JS 和 CSS 的压缩。

不足:

  • 其 tranform 的 API 不能将产物编译到 es5 及以下,产物无法兼容低版本的浏览器。
  • 直接使用 esbuild 进行打包具有一定的使用成本,并且不能完全覆盖使用场景。
  • 在代码分割和 CSS 处理方面功能还有待完善。

参考

swc、esbuild和vite前端构建工具浅析 - 掘金

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写