2024 年如何正确发布 Typescript npm 包指南

375 阅读4分钟

2024 年如何正确发布 Typescript npm 包指南


发布 npm 包本身不难,但为 TypeScript 项目配置起来就有些麻烦了。我的包能在大多数项目中正常工作吗?用户能享受到类型提示和自动补全吗?它能同时兼容 ES 模块(ESM)和 CommonJS(CJS)导入方式吗?

看完这篇文章,你会知道如何让你的 TypeScript 包在各种 JavaScript 和 TypeScript 项目中更容易使用,以及对浏览器的支持!

创建一个 TypeScript 项目

让我们首先创建我们的基础 Node.js 项目,并添加 TypeScript 作为开发依赖项:

pnpm init
pnpm add -D typescript

src 文件夹内组织你的代码,并创建包的入口点:

mkdir src
touch src/index.ts

现在,Node.js 和浏览器都不理解 TypeScript,所以我们需要设置 tsc (TypeScript 编译器)来将我们的 TypeScript 代码编译成 JavaScript。

通过运行以下命令来向项目添加一个 tsconfig.json 文件:

npx tsc --init

如果现在运行 npx tsc ,它将扫描我们的文件夹,并在与 .ts 文件相同的目录中创建 .js 文件,但这不是我们想要的。让我们在运行之前添加更好的配置,避免造成混乱。

将以下行添加到 tsconfig.json 中:

{  
	"compilerOptions": {  
	// ... Other options  
	"rootDir": "./src", // Where to look for our code  
	"outDir": "./dist", // Where to place the compiled JavaScript  
}

package.json 中添加一个 "build" 脚本:

{  
	"scripts": {  
		"build": "tsc"  
		}  
	}

现在运行 npm run build ,将会出现一个新的 dist 文件夹,其中包含编译后的 JavaScript。同时确保将 dist 文件夹添加到你的 .gitignore 中。

.cache
.DS_Store
.idea
*.log
*.tgz
coverage
dist
lib-cov
logs
node_modules
temp

配置 tsconfig.json

我们已经可以将 TypeScript 编译成 JavaScript。然而,如果直接将其发布到 npm,你只能在其他 JavaScript 项目中使用它。此外,默认的 target 是 "es2016",而现代浏览器只支持到 "es2015"。我们需要解决这个问题!

首先,让我们将 target 更改为 es2015 (或 es6 ,因为它们是相同的)。esModuleInterop 默认为 true ,它通过允许 ESM 风格的导入来提高兼容性,所以我们保持原样

我们使用 TypeScript 的原因很简单:类型!但是如果现在就构建并发布,它将不会附带任何类型。通过将 declaration 设置为 true 解决这个问题。这将在我们的 .js 文件旁边生成声明文件 ( .d.ts )。仅此一点,你的包就可以立即在 TypeScript 项目中使用,并且即使在 JavaScript 项目中也能提供类型提示。

声明文件已经在提高支持和开发者体验方面取得了很大进展。然而,我们可以通过添加 declarationMap 来进一步改进。这样,将生成源映射( .d.ts.map ),将我们的声明文件( .d.ts )映射到原始的 TypeScript 源代码( .ts )。这意味着代码编辑器在使用 " 转到定义 " 时,可以跳转到原始的 TypeScript 代码,而不是编译后的 JavaScript 文件。

sourceMap 将添加源映射文件( .js.map ),这使得调试器和其他工具能够在实际使用生成的 JavaScript 文件时显示原始的 TypeScript 源代码。

[!NOTE]
使用 declarationMap 和/或 sourceMap 意味着我们还需要将源代码与包一起发布到 npm。

我们的最终 tsconfig.json 文件:

{
	"compilerOptions": {
		"target": "es2015",
		"module": "commonjs",
		"strict": true,
		"esModuleInterop": true,
		"rootDir": "./src",
		"outDir": "./dist",
		"sourceMap": true,
		"declaration": true,
		"declarationMap": true,
	}
}

配置 package.json

这里的事情要简单得多。首先我们需要指定用户导入我们的包时的入口点。所以让我们将 main 设置为 dist/index.js 。

除了入口点,我们还需要指定主要类型声明文件 types。在这种情况下,那就是 dist/index.d.ts 。

我们还需要指定哪些文件要随包一起发送。当然,我们需要发送我们构建的 JavaScript 文件,但由于我们正在使用 sourceMap 和 declarationMap ,我们还需要发送 src 。

这是一份包含了以上配置的 package.json :

{
  "name": "typescript-package",
  "description": "",
  "author": "wisadel",
  "license": "ISC",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc"
  },
  "keywords": [],
  "files": [
	    "dist",
		"src"
	],
  
  "devDependencies": {
    "typescript": "^5.4.5"
  }
}

发布到 npm

将代码发布到 npm 并不难。这里强烈推荐查看 官方指南,但这里我也给出一般步骤:

  1. 确保你的 package.json 设置得当。
  2. 根据指南构建项目 (pnpm build)。
  3. 使用 pnpm login 对 npm 进行身份验证(需要 npm 账户)。
  4. 运行 pnpm publish

如果更新了你的包,你需要在再次发布之前增加 package.json 中的 version 选项。

发布有更复杂(且推荐)的方法,比如使用 GitHub actions 和 releases,特别是对于开源包,但这就超出了本文的范围,这里不做讨论。

结论

通过遵循以上内容,你的 TypeScript npm 包现在将提供更好的类型提示、自动完成,并支持 ES 模块(ESM)和 CommonJS(CJS)风格的导入,使它们更易于被更广泛的受众访问和使用。