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 并不难。这里强烈推荐查看 官方指南,但这里我也给出一般步骤:
- 确保你的
package.json设置得当。 - 根据指南构建项目 (
pnpm build)。 - 使用
pnpm login对 npm 进行身份验证(需要 npm 账户)。 - 运行
pnpm publish。
如果更新了你的包,你需要在再次发布之前增加 package.json 中的 version 选项。
发布有更复杂(且推荐)的方法,比如使用 GitHub actions 和 releases,特别是对于开源包,但这就超出了本文的范围,这里不做讨论。
结论
通过遵循以上内容,你的 TypeScript npm 包现在将提供更好的类型提示、自动完成,并支持 ES 模块(ESM)和 CommonJS(CJS)风格的导入,使它们更易于被更广泛的受众访问和使用。