原文地址:How To Create An NPM Package | Total TypeScript
以下为原文翻译

在本指南中,我们将介绍将软件包发布到 npm 所需的每一个步骤。

这不是一份最低限度的指南。我们将从一个空目录中建立一个完全可用于生产的软件包。这将包括

  • Git 用于版本控制
  • TypeScript 用于编写我们的代码并保持其类型安全
  • Prettier 用于格式化我们的代码
  • @arethetypeswrong/cli 用于检查我们的出口情况
  • tsup 用于将我们的 TypeScript 代码编译成 CJS 和 ESM
  • Vitest,用于运行我们的测试
  • GitHub Actions,用于运行我们的 CI 流程
  • Changesets 用于版本管理和发布我们的软件包

如果你想看看成品,请查看这个 demo repo

1.Git

在本节中,我们将创建一个新的 git 仓库,设置”.gitignore”,创建初始提交,在 GitHub 上创建一个新仓库,并将代码推送到 GitHub。

1.1:初始化版本库

运行以下命令初始化一个新的 git 仓库:

自动
git init


#### 1.2: 设置".gitignore

在项目根目录下创建一个 `.gitignore` 文件,并添加以下内容:

自动
节点模块

1.3: 创建初始提交

运行以下命令创建初始提交:

自动
git add .
git commit -m “初始提交”


### 1.4:在 GitHub 上创建新仓库

使用 [GitHub CLI](https://cli.github.com/),运行以下命令创建一个新仓库。我为这个示例选择的名称是 `tt-package-demo`:

自动
gh repo create tt-package-demo --source=. --public

1.5: 推送至 GitHub

运行以下命令将代码推送到 GitHub:

自动
git push —set-upstream origin main


## 2: `package.json`

在本节中,我们将创建一个 `package.json` 文件,添加一个 `license` 字段,创建一个 `LICENSE` 文件,并添加一个 `README.md` 文件。

### 2.1:创建 `package.json` 文件

用这些值创建一个 `package.json` 文件:

自动
{
"名称":"tt-package-demo"、
"版本":"1.0.0",
"描述":"Total TypeScript 的演示软件包"、
"关键词":["demo"、"typecript"]、
"主页":"https://github.com/mattpocock/tt-package-demo"、
"错误":{
"url":"https://github.com/mattpocock/tt-package-demo/issues"
},
"作者":"Matt Pocock <[email protected]> (https://totaltypescript.com)"、
"存储库":{
"类型":"git"、
"url":"git+https://github.com/mattpocock/tt-package-demo.git"
},
"文件":["dist"]、
"类型":"模块"

+name 是人们安装软件包时使用的名称。它在 npm 上必须是唯一的。您可以免费创建 organization scopes(例如 @total-typescript/demo),这有助于使其具有唯一性。

  • 版本 “是软件包的版本。它应遵循语义版本0.0.1格式。每次发布新版本时,都应递增这个数字。
  • descriptionkeywords 是对软件包的简短描述。它们会在 npm 注册表的搜索中列出。
    +homepage 是软件包主页的 URL。GitHub repo 是一个很好的默认设置,如果有文档网站也可以。
  • bugs 是人们报告软件包问题的 URL。
    +author 就是你!您可以选择添加您的电子邮件和网站。如果您有多个贡献者,可以将他们指定为具有相同格式的贡献者数组。
  • repository 是软件包仓库的 URL。这会在 npm 注册表上创建一个指向 GitHub 仓库的链接。
  • 文件 “是一个文件数组,人们安装软件包时应将其包括在内。在本例中,我们将包含 dist 文件夹。默认情况下会包含 README.mdpackage.jsonLICENSE
  • type 设置为 module 表示您的软件包使用 ECMAScript 模块,而非 CommonJS 模块。

2.2:添加 “许可证 “字段

package.json中添加license字段。选择许可证 此处。我选择了 MIT

自动

{
“license”(许可证):“MIT

#### 2.3: 添加`LICENSE`文件
创建一个名为 `LICENSE`(无扩展名)的文件,其中包含许可证文本。如果是 MIT 许可证,则为

自动

MIT 许可

版权 (c) [年份] [全名]
特此允许任何人免费获取以下副本

本软件及相关文档文件(以下简称 "软件"),以处理

不受限制地使用本软件,包括但不限于以下权利
使用、复制、修改、合并、出版、分发、再许可和/或出售
软件的副本,并允许接受软件的人
在符合以下条件的情况下,可为其提供许可:
上述版权声明和本许可声明应包含在所有
软件的副本或实质性部分。

}
本软件按 "原样 "提供,不作任何明示或暗示的保证。

默示保证,包括但不限于适销性保证、
特定用途的适用性和非侵权性。在任何情况下
作者或版权持有者对任何索赔、损害赔偿或其他损失负责。
由以下原因引起的责任,无论是合同诉讼、侵权诉讼还是其他原因引起的责任
因本软件或本软件的使用或其他交易而产生的或与之有关的任何争议
软件。

将”[年份]“和”[全名]“占位符改为当前年份和您的姓名。

2.4: 添加README.md文件

创建包含软件包说明的 README.md 文件。下面是一个例子:

自动

tt-package-demo
Total TypeScript 的演示包。

当人们查看您的软件包时,这将显示在 npm 注册表上。

## 3: TypeScript

在本节中,我们将安装 TypeScript、设置 `tsconfig.json`、创建源文件、创建索引文件、设置 `build` 脚本、运行构建、将 `dist` 添加到 `.gitignore`、设置 `ci` 脚本,并为 DOM 配置我们的 `tsconfig.json`。

#### 3.1: 安装 TypeScript

}

运行以下命令安装 TypeScript:

自动
npm install --save-dev typescript

我们添加 -save-dev,将 TypeScript 作为开发依赖安装。这意味着人们安装你的软件包时不会包含它。

3.2: 设置tsconfig.json

创建包含以下值的 tsconfig.json

自动
{
“编译器选项”:{
/* 基本选项:*/
“esModuleInterop”: true、
“skipLibCheck”: true、
“目标”:“es2022”、
“allowJs”:true、
“resolveJsonModule”: true、
“模块检测”:“force”、
“isolatedModules”: true、
“verbatimModuleSyntax”: true、

/* 严格性 */
“strict”: true、
“noUncheckedIndexedAccess”: true、
“noImplicitOverride”: true、

/* 如果使用 TypeScript 进行转置:*/
“模块”:“NodeNext”、
“outDir”:“dist”、
“rootDir”(根目录):“src”:
“sourceMap”: true、

/* 如果您是为图书馆而建:*/
“声明”: true、

/* 如果您为 monorepo 中的一个库进行构建:*/
“declarationMap”: true
}

我的 [TSConfig Cheat Sheet](https://www.totaltypescript.com/tsconfig-cheat-sheet) 中详细解释了这些选项。

### 3.3: 为 DOM 配置 `tsconfig.json

如果您的代码在 DOM 中运行(即需要访问 `document`、`window` 或 `localStorage` 等),请跳过此步骤。

如果您的代码不需要访问 DOM API,请在 `tsconfig.json` 中添加以下内容:


{
"编译器选项":{
// ...其他选项
"库":["es2022"]
}

这样,您的代码中就无法使用 DOM 类型。
如果您不确定,请跳过这一步。

3.4:创建源文件

创建一个内容如下的 src/utils.ts 文件:

自动

export const add = (a: number, b: number) a + b;

#### 3.5:创建索引文件
创建一个内容如下的 `src/index.ts` 文件:

自动

export { add } from "./utils.js";

.js “扩展名看起来会很奇怪。本文 有更多解释。

3.6:设置 build 脚本

package.json中添加一个scripts对象,内容如下:

自动

{

“脚本”:{
“构建”:“tsc”
}

这将把您的 TypeScript 代码编译为 JavaScript。
#### 3.7:运行您的构建
运行以下命令编译 TypeScript 代码:

自动

npm run build

这将创建一个包含已编译 JavaScript 代码的 dist 文件夹。

3.8:在.gitignore中添加`dist

将 “dist “文件夹添加到”.gitignore “文件中:

自动

地区


这将防止您编译的代码被包含在 git 仓库中。
### 3.9: 设置`ci`脚本
在`package.json`中添加一个`ci`脚本,内容如下:

自动

{

"脚本":{

"ci":"npm run build"
}

这为我们在 CI 上运行所有必要操作提供了快捷方式。

4: 更漂亮

在本节中,我们将安装 Prettier、设置.prettierrc、设置format脚本、运行format脚本、设置check-format脚本、将check-format脚本添加到CI脚本中并运行CI脚本。
Prettier 是一种代码格式器,可自动将代码格式化为一致的风格。这样,您的代码就更容易阅读和维护了。

4.1: 安装 Prettier

}

运行以下命令安装 Prettier:

自动

npm install —save-dev prettier


#### 4.2: 设置`.prettierrc`。
创建一个内容如下的 `.prettierrc` 文件:
自动

{

"semi": true、

"singleQuote": true、
"trailingComma"(尾随逗号):"所有"、
"打印宽度":80,
"tabWidth"(标签宽度):2

你可以在该文件中添加更多选项,自定义 Prettier 的行为。你可以在 这里 找到完整的选项列表。

4.3:设置 “格式 “脚本

}
package.json中添加一个format脚本,内容如下:

自动

{

“脚本”:{

“格式”:“prettier —write .”
}

这将使用 Prettier 格式化项目中的所有文件。
### 4.4:运行 `format` 脚本
运行以下命令格式化项目中的所有文件:
自动

npm 运行格式

你可能会注意到一些文件发生了变化。用

自动
git add .
git commit -m “用 Prettier 格式化代码”


#### 4.5: 设置 "检查格式 "脚本
在`package.json`中添加一个`check-format`脚本,内容如下:
自动
{

"脚本": {

"检查格式":"prettier --check ."

}

这将检查项目中所有文件的格式是否正确。

4.6: 添加到我们的 CI 脚本中

将 “check-format “脚本添加到 “package.json “中的 “ci “脚本:
自动
{

“脚本”: {

“ci”:“npm run build && npm run check-format”

}

}

这将运行 `check-format` 脚本,作为 CI 流程的一部分。
## 5: `exports`、`main` 和`@arethetypeswrong/cli`。
在本节中,我们将安装 `@arethetypeswrong/cli`,设置 `check-exports` 脚本,运行 `check-exports` 脚本,设置 `main` 字段,再次运行 `check-exports` 脚本,设置 `ci` 脚本,并运行 `ci` 脚本。
`@arethetypeswrong/cli` 是一个检查软件包导出是否正确的工具。这一点很重要,因为这些输出很容易出错,会给使用软件包的用户带来麻烦。
#### 5.1: 安装`@arethetypeswrong/cli`。

运行以下命令安装 `@arethetypeswrong/cli`:

自动

npm install --save-dev @arethetypeswrong/cli

5.2: 设置一个 check-exports 脚本

package.json中添加一个check-exports脚本,内容如下:

自动
{
“脚本”: {

“check-exports”: “attw —pack .”

}

这将检查软件包的所有输出是否正确。
#### 5.3: 运行 `check-exports` 脚本
运行以下命令检查软件包中的所有输出是否正确:
自动
npm run check-exports

您会发现各种错误:

自动

┌───────────────────┬──────────────────────┐

│ │ “tt-package-demo” │
├───────────────────┼──────────────────────┤
│ 节点10 │ 💀 解析失败 │

├───────────────────┼──────────────────────┤

│ node16(来自 CJS) │ 💀 解决失败 │
}
├───────────────────┼──────────────────────┤
│ 节点 16(来自 ESM) │ 💀 解析失败 │
├───────────────────┼──────────────────────┤
│ bundler │ 💀 Resolution failed │
└───────────────────┴──────────────────────┘

这表明任何版本的 Node 或任何捆绑程序都无法使用我们的软件包。
让我们来解决这个问题。
### 5.4: 设置 `main
在`package.json`中添加一个`main`字段,内容如下:
自动

{

"main":"dist/index.js"

这会告诉 Node 在哪里找到软件包的入口点。

5.5: 再次尝试 `check-exports

运行以下命令检查软件包中的所有输出是否正确:
自动
npm run check-exports


您应该只注意到一个警告:

自动

┌───────────────────┬──────────────────────────────┐

│ │ "tt-package-demo" │
├───────────────────┼──────────────────────────────┤
│ 节点10 │ 🟢 │

├───────────────────┼──────────────────────────────┤

│ node16(来自 CJS) │ ⚠️ ESM(仅动态导入) │
├───────────────────┼──────────────────────────────┤
}
│ 节点 16(来自 ESM) │ 🟢 (ESM) │
├───────────────────┼──────────────────────────────┤
│ bundler │ 🟢 │
└───────────────────┴──────────────────────────────┘

这说明我们的软件包与运行 ESM 的系统兼容。使用 CJS 的用户(通常是传统系统)需要使用动态导入来导入。

5.6 修复 CJS 警告

如果您不想支持 CJS(我建议您这样做),请将 check-exports 脚本更改为
自动
{

“脚本”: {

“check-exports”: “attw —pack .—ignore-rules=cjs-resolves-to-esm”

}

}

现在,运行 `check-exports` 会显示所有内容都是绿色的:
自动
┌───────────────────┬───────────────────┐
│ │ "tt-package-demo" │
├───────────────────┼───────────────────┤

│ 节点10 │ 🟢 │

├───────────────────┼───────────────────┤
│ node16(来自 CJS) │ 🟢 (ESM) │
├───────────────────┼───────────────────┤
│ 节点 16(来自 ESM) │ 🟢 (ESM) │
├───────────────────┼───────────────────┤
│ bundler │ 🟢 │
└───────────────────┴───────────────────┘

如果您希望同时发布 CJS 和 ESM,请跳过此步骤。

5.7: 添加到我们的 CI 脚本中

package.json 中的 ci 脚本中添加 check-exports 脚本:
自动
{

“脚本”: {

“ci”: “npm run build && npm run check-format && npm run check-exports”

}

## 6: 使用 `tsup` 实现双重发布
如果您想同时发布 CJS 和 ESM 代码,可以使用 `tsup`。这是一个建立在 `esbuild` 基础上的工具,可以将您的 TypeScript 代码编译成两种格式。
我个人建议跳过这一步,只发布 ES 模块。这将大大简化您的设置,并避免双重发布的许多隐患,如 [Dual Package Hazard](https://github.com/GeoffreyBooth/dual-package-hazard)。
但如果你想的话,请便。
}
#### 6.1: 安装`tsup`。

运行以下命令安装 `tsup`:

自动

npm install --save-dev tsup

6.2: 创建一个 tsup.config.ts 文件

创建内容如下的 tsup.config.ts 文件:

自动
import { defineConfig } from “tsup”;
导出 default defineConfig({

entryPoints: [“src/index.ts”]、

格式:[“cjs”、“esm”]、

dts: true、
}

outDir:“dist”、
clean: true、
});

+ `entryPoints`是软件包入口点的数组。在本例中,我们使用 `src/index.ts`。
+ `format` 是要输出的格式数组。我们使用 `cjs`(CommonJS)和 `esm`(ECMAScript 模块)。
+ `dts` 是一个布尔值,用于告诉 `tsup` 生成声明文件。
+ `outDir` 是编译代码的输出目录。

+ `clean` 命令 `tsup` 在编译前清理输出目录。
#### 6.3: 更改 `build` 脚本
将`package.json`中的`build`脚本改为以下内容:
自动
{

"脚本": {

"构建": "tsup"

}

现在我们将运行 tsup 来编译代码,而不是 tsc

6.4: 添加 “出口 “字段

package.json 中添加包含以下内容的 exports 字段:
自动
{

“出口”: {

”./package.json”: ”./package.json”、

”.”:{

“导入”:”./dist/index.js”、
“默认”:”./dist/index.cjs”
}
}
}

`exports` 字段告诉使用您的软件包的程序如何找到您的软件包的 CJS 和 ESM 版本。在本例中,我们将使用 `import` 的用户指向 `dist/index.js` ,使用 `require` 的用户指向 `dist/index.cjs`。
还建议在 `exports` 字段中添加 `./package.json`。这是因为某些工具需要方便地访问`package.json`文件。
#### 6.5: 再次尝试 `check-exports
运行以下命令检查软件包中的所有输出是否正确:
自动

npm run check-exports

现在,一切都是绿色的:

自动

┌───────────────────┬───────────────────┐
│ │ “tt-package-demo” │
├───────────────────┼───────────────────┤

│ 节点10 │ 🟢 │

├───────────────────┼───────────────────┤
│ node16(来自 CJS) │ 🟢 (CJS) │
├───────────────────┼───────────────────┤
│ 节点 16(来自 ESM) │ 🟢 (ESM) │
├───────────────────┼───────────────────┤
│ bundler │ 🟢 │
└───────────────────┴───────────────────┘

#### 6.6:将 TypeScript 变为内联程序
我们不再运行 `tsc` 来编译代码。而 `tsup` 实际上并不检查我们的代码是否有错误,它只是将代码转换成 JavaScript。
这意味着如果我们的代码中有 TypeScript 错误,我们的 `ci` 脚本就不会出错。哎呀
让我们来解决这个问题。
#### 6.6.1:在 `tsconfig.json` 中添加 `noEmit

在 `tsconfig.json` 中添加 `noEmit` 字段:

自动

{

"编译器选项":{

// ...其他选项

"noEmit": true

}

6.6.2:删除 tsconfig.json 中未使用的字段

删除 tsconfig.json 中的以下字段:
}
+outDir
+rootDir
+sourceMap

  • `声明

+declarationMap

在我们新的 “打绒 “设置中,不再需要它们。

6.6.3:将 module 改为Preserve

您现在可以选择在 tsconfig.json 中将 module 改为 Preserve
自动
{

“编译器选项”:{

// …其他选项

“模块”:“保存”

}

这意味着您不再需要导入带有 `.js` 扩展名的文件。这意味着,`index.ts` 看上去可以像这样:
自动
从"./utils "导出 *;

6.6.4:添加 “lint “脚本

package.json中添加一个lint脚本,内容如下:

自动

{
“脚本”:{
“林特”:“tsc”

}


这会将 TypeScript 作为内核运行。
#### 6.6.5:在`ci`脚本中添加`lint`。
将 `lint` 脚本添加到 `package.json` 中的 `ci` 脚本:
自动
{
"脚本":{
"ci":"npm run build && npm run check-format && npm run check-exports && npm run lint"

}

现在,我们将在 CI 过程中获取 TypeScript 错误。

7: 使用 Vitest 进行测试
在本节中,我们将安装 vitest、创建测试、设置 test 脚本、运行 test 脚本、设置 dev 脚本,并将 test 脚本添加到我们的 CI 脚本中。
}
vitest` 是用于 ESM 和 TypeScript 的现代测试运行器。它就像 Jest,但更好用。

7.1:安装 `vitest

运行以下命令安装 vitest
自动

npm install —save-dev vitest


### 7.2:创建测试

创建一个内容如下的 `src/utils.test.ts` 文件:

自动

从 "./utils.js" 中导入 { add };

import { test, expect } from "vitest";
test("add", () => {
expect(add(1, 2)).toBe(3);

});

这是一个简单的测试,用于检查 hello 函数是否返回正确的值。

7.3: 设置 “测试 “脚本

package.json中添加一个test脚本,内容如下:

自动
{
“脚本”:{
“测试”:“vitest运行”

}


`vitest run` 一次运行项目中的所有测试,无需监视。

### 7.4:运行 `test` 脚本
运行以下命令运行测试:
自动
npm run test
}

输出结果如下

自动

✓ src/utils.test.ts (1)

你好

测试文件 1 已通过 (1)
通过测试 1 (1)


这表明测试已成功通过。

### 7.5: 设置 `dev` 脚本
常见的工作流程是在开发过程中以观察模式运行测试。在`package.json`中添加一个`dev`脚本,内容如下:
自动

{
"脚本":{
"dev":"vitest"

}

这将以观察模式运行测试。

7.6: 添加到我们的 CI 脚本中

test 脚本添加到 package.json 中的 ci 脚本:
自动
{
“脚本”:{
“ci”:“npm run build && npm run check-format && npm run check-exports && npm run lint && npm run test”
}


## 8\.用 GitHub 操作设置我们的 CI

在本节中,我们将创建一个 GitHub 操作工作流,在每次提交和拉取请求时运行我们的 CI 流程。

这是确保我们的软件包始终处于工作状态的关键一步。
### 8.1:创建工作流程
创建内容如下的 `.github/workflows/ci.yml` 文件:
自动
名称: CI
上:
pull_request:

推:

分支机构

- 主要

并发性:

group: ${{ github.workflow }}-${{ github.ref }}

cancel-in-progress: true
工作

ci:
运行于: ubuntu-latest
步骤:
- 使用:actions/checkout@v4
- 名称: 使用 Node.js

使用:actions/setup-node@v4
用:
}

节点版本:"20"
- 名称: 安装依赖项
运行:npm install

- 名称运行 CI
运行: npm run ci

GitHub 将此文件作为运行 CI 流程的指令。
+name 是工作流程的名称。

  • on指定工作流程的运行时间。在本例中,它在拉取请求时运行,并推送到 main 分支。
  • concurrency 可防止工作流的多个实例同时运行,使用 cancel-in-progress 可取消任何现有运行。
  • jobs 是一组要运行的工作。在本例中,我们有一个名为 ci的工作。
  • actions/checkout@v4 从版本库中取出代码。
  • actions/setup-node@v4 设置 Node.js 和 npm。
  • npm install 安装项目的依赖项。
  • npm run ci 运行项目的 CI 脚本。

如果 CI 流程的任何部分失败,工作流就会失败,而 GitHub 会在我们的提交旁边显示一个红叉,让我们知道。

8.2:测试我们的工作流程

}
将更改推送到 GitHub,然后查看版本库中的 “操作 “选项卡。你应该会看到工作流程正在运行。
这将对我们的每次提交和对版本库的每次 PR 发出警告。

9.使用变更集发布

在本节中,我们将安装 @changesets/cli,初始化变更集,公开变更集发布,将 commit 设为 true,设置 local-release 脚本,添加变更集,提交变更,运行 local-release 脚本,最后在 npm 上查看你的软件包。
Changesets 是一款可以帮助您对软件包进行版本控制和发布的工具。我向所有在 npm 上发布软件包的人推荐这款出色的工具。

9.1: 安装@changesets/cli

运行以下命令初始化变更集:

自动

npm install —save-dev @changesets/cli


#### 9.2:初始化更改集

运行以下命令初始化变更集:

自动

npx 变更集启动

这将在项目中创建一个包含 config.json 文件的 .changeset 文件夹。这也是你的变更集所在的位置。

9.3: 公开变更集版本

.changeset/config.json 中,将 access 字段改为 public

自动

// .changeset/config.json
{
“访问”:“公共”


如果不更改此字段,"changesets "将不会向 npm 发布软件包。

### 9.4:将 `commit` 设为 `true`:

在 `.changeset/config.json` 中,将 `commit` 字段改为 `true`:
自动
// .changeset/config.json
{
"commit": true

这将在版本控制后把更改集提交到您的版本库。

9.5: 设置 local-release 脚本

package.json中添加一个local-release脚本,内容如下:

自动
{
“脚本”:{
“本地发布”:“变更集版本&&变更集发布”
}


此脚本将运行 CI 进程,然后将软件包发布到 npm。当你想从本地机器发布软件包的新版本时,就会运行这个命令。

#### 9.6 在 "仅限预发布 "模式下运行 CI

在`package.json`中添加内容如下的`prepublishOnly`脚本:

自动
{
"脚本":{
"仅预发布":"npm run ci"
}
}

这将在将软件包发布到 npm 之前自动运行 CI 流程。

如果用户不小心在未运行 local-release 的情况下运行了 npm publish 脚本,将其与 local-release 脚本分开会很有用。感谢 Jordan Harband的建议!

9.7: 添加变更集

运行以下命令添加变更集:
自动
npx 变更集

这将打开一个交互式提示,您可以在其中添加变更集。更改集是一种将更改分组并赋予版本号的方法。
将此版本标记为 "补丁 "版本,并给出类似 "初始版本 "的描述。
这将在 `.changeset` 文件夹中创建一个包含更改集的新文件。

#### 9.8: 提交您的更改

将更改提交到版本库:

自动

git add .

git commit -m "准备首次发布"

9.9: 运行 local-release 脚本

运行以下命令释放软件包

自动

npm run local-release


这将运行您的 CI 流程,对软件包进行版本控制,并将其发布到 npm。

它将在您的版本库中创建一个 `CHANGELOG.md` 文件,详细说明此版本中的更改。每次发布时都会更新。
}
#### 9.10: 在 npm 上查看您的软件包
转到

自动

http://npmjs.com/package/< 您的软件包名称

你应该在那里看到你的包裹!你成功了!你已经发布到了 npm!

摘要

现在您已经拥有了一个完全设置好的软件包。您已经设置好了

  • 带有最新设置的 TypeScript 项目
  • Prettier,既能格式化代码,又能检查格式是否正确
  • @arethetypeswrong/cli,检查软件包导出是否正确
  • tsup,可将 TypeScript 代码编译为 JavaScript
  • vitest,用于运行测试
  • GitHub Actions,运行您的 CI 流程
  • Changesets,用于版本和发布软件包