[译] 使用 esbuild 加速你的 TypeScript monorepo

1,914 阅读3分钟

Speed up your TypeScript monorepo with esbuild

TypeScript monorepos 是组织大中型项目的好方法。 TypeScript 通过添加类型检查和深度 IDE 集成来改善开发人员体验。 使用 monorepo 有助于扩展您的项目。

然而,与纯 JavaScript 相比,TypeScript 为您的项目添加了一个额外的编译层,这可能会降低开发人员的体验。 虽然原生 TypeScript 编译器并不慢(恕我直言),但如果您计划构建大型代码库,这仍然是您需要考虑的事情。 但是如果有一种方法可以通过使用不同的编译器来加速 TypeScript 编译呢?

进入 esbuild:一个快速的 JavaScript 打包器,声称比类似项目(webpack、rollup + terser、parcel 2)快 10 倍以上。 我一直在将 esbuilt 用于几个 TypeScript 项目,并且对它的表现感到惊讶。

🍊 Tangerine monorepo

在学习 esbuild 的过程中,我还没有找到很多关于如何将它集成到 TypeScript monorepos 中的例子。所以我创建了我自己的模板:🍊 tangerine-monorepo,一个“最小”的基于 TypeScript 的 Node.js monorepo 设置,完全由 esbuild 提供支持。

特点

  • 使用 TypeScript 编写代码、测试和脚本。
  • 使用 esbuild 编译您的 TypeScript 代码库、测试和脚本。
  • 使用 tsc CLI 对代码库进行类型检查而不发出编译文件(因为它们由 esbuild 处理)。 无需更新 TypeScript 的项目参考
  • 使用 esbuild-runner 动态运行脚本。
  • 使用 Yarn 工作区 可以轻松地在 monorepo 中工作。
  • 使用 Ultra runner 从项目根目录运行脚本。
  • 使用可共享的 ESLint 配置和 Jest 配置来提供可扩展的 linting 和测试设置。
  • 使用 esbuild + nodemon 在开发模式下重新加载服务器(即使工作区依赖项已更改)。

工作区

Tangerine monorepo 包括五个工作区:

  • packages/is-even: 最简单的工作区——它不依赖于任何其他工作区。 它是一个 Node.js 模块,它公开了一个 isEven 函数,用于判断输入数字是否为偶数。 它包括一个从终端调用函数的 CLI 脚本和一个测试文件,两者都是用 TypeScript 编写的。 CLI 脚本使用 esbuild-runner 运行,它使用 esbuild 动态编译它。
  • package/is-odd: 取决于 packages/is-even。 它是一个 Node.js 模块,它公开了一个 isOdd 函数,该函数判断输入数字是否为奇数(通过调用 isEven 并检查它是否为假)。 它包括一个 CLI 脚本和一个测试文件。
  • package/server: 取决于 packages/is-oddpackages/is-even。 它是一个 Node.js Express 服务器,它公开了两个调用 isEvenisOdd 的路由。 它使用 nodemon 在开发模式下重新加载服务器。
  • packages/jest-config: 使用 esbuild 编译测试和代码库的共享 Jest 配置。
  • packages/eslint-config: 共享 ESLint 配置。

所有工作区都使用 esbuild 来编译 TypeScript 代码库。 无论是构建、测试还是运行 CLI 脚本,与原生 TypeScript 编译器相比,编译都是即时的(您可以通过临时交换 esbuild 和 tsc 来快速测试差异)。

tsc CLI 仅用于对代码库进行类型检查(不发出已编译的文件——因为它们由 esbuild 处理)。 我希望人们通常使用 IDE 集成来对代码进行类型检查,并且仅在特定用例(例如预提交挂钩)中显式调用 tsc CLI。

个工作区的 package.json 都将 maintypes 条目指向 src/index.ts。 考虑到它是未编译的代码,乍一看可能很奇怪……请参阅 Turborepo 博客上的 “您可能不需要 TypeScript 项目引用” 的解释。 到目前为止,这种模式在我的用例中运行良好(尤其是在使用 esbuild 时)。 不过,您可能希望更新这些条目以满足您的需要(例如,将包发布到 npm 时)。