feng xiaohan

esbuild + SWC + TS

esbuild

web 构建工具,速度相对于其他构建工具(parcel2、webpack5、rollup + terser)来说要快很多。

它是基于 Go 去开发的,采用了 Go 语言的多线程执行,所以性能要比 JS 要好。

主要特性:

  • 极快的速度,无需缓存即可实现基础打包;

  • 支持 ES6 和 CommonJS 模块;

  • 支持对 ES6 模块进行 tree shaking

    Tree-shaking 是一种 JavaScript 代码优化技术,它可以自动删除未使用的代码,以减小代码的体积,提高应用程序的性能。

    它需要使用支持 ES6 模块语法的打包工具,例如 Webpack、Rollup 等。在使用这些工具时,需要确保在配置中启用 Tree-shaking 功能,以便在打包时自动删除未使用的代码。

  • API 可同时用于 JavaScript 和 Go;

  • 兼容 TypeScript 和 JSX 语法;

  • 支持 Minification;

    生成的代码会被压缩而不是格式化输出。压缩后的代码与未压缩代码是相等的,但是会更小。这意味着下载更快但是更难调试。 一般情况下在生产环境而不是开发环境压缩代码。

  • 支持 plugins(强大的插件系统)

SWC

处理打包之后对不同浏览器的兼容问题。

使用 Rust 语言编写,用于代替 Babel(Babel 是用于处理不同浏览器之间的兼容问题),比 Babel 快很多。

安装

npm install @swc/core esbuild @swc/helpers
  • @swc/core: swc 的核心包,用于编译 JavaScript 和 TypeScript 代码;
  • esbuild:一个快速的 JavaScript 和 TypeScript 构建工具;
  • @swc/helpers: swc 的辅助包,用于转换 JSX 代码(没有 JSX 可不选);

配置

需要修改 tsconfig.json,以支持更高级的语法:

"compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "node"
}

在 config.ts 里编写打包的配置:

// config.ts
import esbuild from "esbuild"; // 引入打包工具
import swc from "@swc/core"; // 引入SWC库(类似于babel es6 转 es5)
import fs from "node:fs";

await esbuild.build({
  // @1
  entryPoints: ["./index.ts"], // 入口文件(可支持多个)
  bundle: true, //模块单独打包
  loader: {
    // 配置xx-loader
    ".js": "js",
    ".ts": "ts",
    ".jsx": "jsx",
    ".tsx": "tsx",
  },
  treeShaking: true, // 代码优化
  define: {
    "process.env.NODE_ENV": '"production"',
  },
  plugins: [
    {
      //实现自定义loader
      name: "swc-loader",
      setup(build) {
        build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, (args) => {
          // args:当前编译文件的信息
          // console.log(args);
          const content = fs.readFileSync(args.path, "utf-8");
          const { code } = swc.transformSync(content, {
            // 转成es5的代码
            filename: args.path,
          });
          return {
            contents: code,
          };
        });
      },
    },
  ],
  outdir: "dist", // 出口
});

@1:esbuild 打包是异步的,在 ES2017 以后可以使用顶层 await 语法。

注意:使用ts-node-esm config.ts时,如果没有-esm需要升级一下这个方法,并且将 package.json 里的"type": "module"