在 Monorepo 中打包软件包

内部 软件包不同,外部软件包可以部署到 npm (opens in a new tab) 以及 在本地使用。在本指南中,我们将打包一个软件包,使其同时支持 ECMAScript 模块 (opens in a new tab) (esm) 和 CommonJS 模块 (opens in a new tab) (cjs),这是 npm 上最常用的格式。

设置构建脚本

让我们从使用我们的 内部软件包 教程创建的软件包开始。

在那里,我们创建了一个 math-helpers 软件包,其中包含一些用于加减的辅助函数。我们已经决定这个软件包足够好,可以发布到 npm,所以我们将对其进行打包。

在该教程结束时,我们在 /packages 下设置了一个软件包,它看起来像这样

├── apps
│   └── web
│       └── package.json
├── packages
│   └── math-helpers
│       ├── src
│       │   └── index.ts
│       ├── tsconfig.json
│       └── package.json
├── package.json
└── turbo.json

我们将使用打包器向 math-helpers 添加一个 build 脚本。如果您不确定选择哪个打包器,我们建议您使用 tsup (opens in a new tab).

首先,使用您的 包管理器packages/math-helpers 中安装 tsup

{
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts"
  }
}

tsup 默认将文件输出到 dist 目录,因此您应该

  1. dist 添加到您的 .gitignore 文件中,以确保它们不会被 git 提交。
  2. dist 添加到您 turbo.json 中的 build 输出中。
{
  "pipeline": {
    "build": {
      "outputs": ["dist/**"]
    }
  }
}

这样,当运行 tsup 时,输出可以被 Turborepo 缓存

最后,我们需要更新我们的包入口点。在 package.json 中,将 main 指向 ./dist/index.js,用于使用 CommonJS 模块 (cjs) 的客户端,将 module 指向 ./dist/index.mjs,用于使用 ECMAScript 模块 (esm) 的客户端,并将 types 指向类型定义文件 - ./dist/index.d.ts

{
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts"
}

不需要同时打包到 cjsesm。但是,建议这样做,因为它可以让你的包在更多环境中使用。

如果你在使用 mainmoduletypes 时遇到错误,请查看 tsup 文档 (在新标签页中打开)

打包是一个复杂的话题,我们在这里没有足够的空间来涵盖所有内容!

在我们的应用程序之前构建我们的包

在我们运行 turbo run build 之前,我们需要考虑一件事。我们刚刚在我们的单仓库中添加了一个 任务依赖packages/math-helpersbuild 需要在 apps/webbuild 之前运行。

幸运的是,我们可以使用 dependsOn 来轻松配置这一点。

{
  "pipeline": {
    "build": {
      "dependsOn": [
        // Run builds in workspaces I depend on first
        "^build"
      ]
    }
  }
}

现在,我们可以运行 turbo run build,它会自动在构建我们的应用程序之前构建我们的包。

设置一个开发脚本

我们的设置有一个小问题。我们很好地构建了我们的包,但它在开发中运行得不好。我们对 math-helpers 包所做的更改没有反映到我们的应用程序中。

这是因为我们没有一个 dev 脚本在我们工作时重建我们的包。我们可以轻松地添加一个

{
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts",
    "dev": "npm run build -- --watch"
  }
}

这将 --watch 标志传递给 tsup,这意味着它将监视文件更改。

如果我们已经在 turbo.json 中设置了 开发脚本,运行 turbo run dev 将并行运行我们的 packages/math 开发任务和我们的 apps/web 开发任务。

总结

我们的包现在处于一个我们可以考虑部署到 npm 的位置。在我们关于 版本控制和发布 的部分,我们将这样做。