辰風依恛
文章35
标签0
分类11
Node.js 函数打包为 npm 包的规范流程

Node.js 函数打包为 npm 包的规范流程

Node.js 函数打包为 npm 包的规范流程

概述

本教程提供从零开始创建和发布 npm 包的标准化流程,遵循最佳实践和行业规范。

第一步:项目初始化

1. 创建项目目录结构

1
2
mkdir my-package
cd my-package

2. 初始化 package.json

1
npm init -y

3. 标准项目结构

1
2
3
4
5
6
7
8
9
10
11
my-package/
├── src/ # 源代码目录
│ └── index.ts # 主入口文件
├── static/ # 静态资源
├── test/ # 测试文件
├── package.json # 包配置
├── tsconfig.json # TypeScript 配置
├── .gitignore # Git 忽略规则
├── .npmignore # NPM 发布忽略规则
├── README.md # 文档
└── LICENSE # 许可证

第二步:开发环境配置

1. 安装开发依赖

方案一:使用 TypeScript 编译器 (tsc)

1
2
3
npm install -D typescript @types/node
npm install -D rimraf # 清理工具
npm install -D jest @types/jest # 测试框架(可选)

方案二:使用 tsup 构建工具(推荐)

1
2
3
4
npm install -D tsup
npm install -D @types/node
npm install -D rimraf # 清理工具
npm install -D jest @types/jest # 测试框架(可选)

tsup 优势:

  • 零配置,开箱即用
  • 支持 ES Modules 和 CommonJS 双格式输出
  • 自动生成类型声明文件
  • 更快的构建速度
  • 更好的 Tree Shaking

2. 配置 TypeScript (tsconfig.json)

使用 tsc 的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test"]
}

使用 tsup 的简化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test"]
}

3. 配置构建脚本 (package.json)

使用 tsc 的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && tsc",
"dev": "tsc -w",
"test": "jest",
"prepublishOnly": "npm run build",
"lint": "eslint src/**/*.ts"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"static",
"README.md",
"LICENSE"
]
}

使用 tsup 的配置(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && tsup",
"dev": "tsup --watch",
"test": "jest",
"prepublishOnly": "npm run build",
"lint": "eslint src/**/*.ts"
},
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"files": [
"dist",
"static",
"README.md",
"LICENSE"
]
}

4. 配置 tsup (tsup.config.ts 或 package.json)

方式一:在 package.json 中配置

1
2
3
4
5
6
7
8
9
10
11
{
"tsup": {
"entry": ["src/index.ts"],
"format": ["cjs", "esm"],
"dts": true,
"clean": true,
"sourcemap": true,
"splitting": false,
"minify": false
}
}

方式二:创建 tsup.config.ts 文件

1
2
3
4
5
6
7
8
9
10
11
import { defineConfig } from 'tsup'

export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
clean: true,
sourcemap: true,
splitting: false,
minify: false
})

方式三:命令行参数(package.json scripts)

1
2
3
4
5
{
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts --clean --sourcemap"
}
}

第三步:代码开发规范

1. 源代码编写规范

src/index.ts - 主入口文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 主类 - 提供核心功能
*/
export class MyLibrary {
private config: any;

constructor(config?: any) {
this.config = config || {};
}

/**
* Express 中间件方法
*/
serveExpress() {
return (req: any, res: any, next: any) => {
// Express 中间件逻辑
res.json({ message: 'Hello from Express' });
};
}

/**
* Koa 中间件方法
*/
serveKoa() {
return async (ctx: any, next: any) => {
// Koa 中间件逻辑
ctx.body = { message: 'Hello from Koa' };
await next();
};
}
}

// 默认导出
export default MyLibrary;

// CommonJS 兼容导出
if (typeof module !== 'undefined' && module.exports) {
module.exports = MyLibrary;
}

2. 类型定义规范

创建类型定义文件 src/types/index.ts

1
2
3
4
5
6
7
8
9
10
export interface Config {
prefix?: string;
debug?: boolean;
}

export interface ApiResponse {
success: boolean;
data?: any;
error?: string;
}

第四步:构建和测试

1. 构建流程

使用 tsc 的构建流程

1
2
3
4
5
6
7
8
# 清理并构建
npm run build

# 开发模式(监听文件变化)
npm run dev

# 运行测试
npm test

使用 tsup 的构建流程(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 清理并构建
npm run build

# 开发模式(监听文件变化)
npm run dev

# 运行测试
npm test

# 仅构建 CommonJS 格式
npx tsup src/index.ts --format cjs --dts

# 仅构建 ES Modules 格式
npx tsup src/index.ts --format esm --dts

# 生产环境构建(压缩代码)
npx tsup src/index.ts --format cjs,esm --dts --minify

2. 验证构建结果

tsc 构建结果

构建完成后检查 dist 目录:

1
2
3
4
5
6
dist/
├── index.js # 编译后的 JavaScript
├── index.d.ts # TypeScript 类型声明
├── index.js.map # 源码映射文件
└── types/
└── index.d.ts # 类型定义

tsup 构建结果

构建完成后检查 dist 目录:

1
2
3
4
5
6
7
dist/
├── index.js # CommonJS 格式输出
├── index.mjs # ES Modules 格式输出
├── index.d.ts # TypeScript 类型声明
├── index.d.mts # ES Modules 类型声明
├── index.js.map # CommonJS 源码映射
└── index.mjs.map # ES Modules 源码映射

3. tsup 构建配置详解

常用配置选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 基本构建
npx tsup src/index.ts

# 多格式输出
npx tsup src/index.ts --format cjs,esm

# 生成类型声明
npx tsup src/index.ts --dts

# 清理输出目录
npx tsup src/index.ts --clean

# 生成源码映射
npx tsup src/index.ts --sourcemap

# 代码分割
npx tsup src/index.ts --splitting

# 压缩代码
npx tsup src/index.ts --minify

# 外部依赖处理
npx tsup src/index.ts --external react,vue

# 平台特定构建
npx tsup src/index.ts --platform node
npx tsup src/index.ts --platform browser

# 目标环境
npx tsup src/index.ts --target node16
npx tsup src/index.ts --target es2020

高级配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 多入口构建
npx tsup src/index.ts src/cli.ts --format cjs,esm --dts

# 自定义输出目录
npx tsup src/index.ts --out-dir build

# 环境变量注入
npx tsup src/index.ts --env.NODE_ENV production

# 监听模式(开发)
npx tsup src/index.ts --watch

# 服务端渲染优化
npx tsup src/index.ts --format cjs --platform node --target node16

# 浏览器优化
npx tsup src/index.ts --format esm --platform browser --target es2020

3. 本地包开发和测试(npm link)

  • 在本地开发和测试包,无需发布到 npm
  • 模拟真实的包安装和使用场景
  • 支持实时修改和测试

在包项目中创建全局链接

1
2
3
4
5
# 在包项目根目录执行
npm link

# 输出示例:
# /usr/local/lib/node_modules/your-package -> /path/to/your/package

在测试项目中使用链接的包

1
2
3
4
5
6
7
8
9
10
# 创建测试项目
mkdir test-project
cd test-project
npm init -y

# 链接到全局包
npm link your-package-name

# 或者使用完整路径
npm link /path/to/your/package

验证链接是否成功

1
2
3
4
5
6
7
8
# 在测试项目中检查
npm ls your-package-name

# 查看链接状态
npm ls -g --link

# 测试导入
node -e "console.log(require('your-package-name'))"

实时开发和测试

1
2
3
4
5
# 在包项目中修改代码后,重新构建
npm run build

# 在测试项目中会立即看到变化
# 无需重新安装或重启

取消链接

1
2
3
4
5
6
7
8
# 在测试项目中取消链接
npm unlink your-package-name

# 或者使用 uninstall
npm uninstall your-package-name

# 在包项目中取消全局链接
npm unlink

多个包之间的链接

1
2
3
4
5
6
7
8
9
10
11
# 假设有两个包:package-a 和 package-b

# 在 package-a 中创建链接
cd package-a
npm link

# 在 package-b 中链接到 package-a
cd package-b
npm link package-a

# 现在 package-b 可以使用 package-a 作为依赖

使用相对路径链接

1
2
# 如果包在同一个项目中
npm link ../my-other-package

查看所有全局链接

1
2
3
4
5
# 查看所有全局链接的包
npm ls -g --depth=0 --link

# 查看特定包的链接信息
npm ls -g your-package-name

链接不生效

1
2
3
4
5
6
7
# 检查包名是否正确
npm ls your-package-name

# 重新链接
npm unlink your-package-name && npm link your-package-name

# 或者重启终端

权限问题

1
2
3
4
5
# 在 macOS/Linux 上可能需要 sudo
sudo npm link

# 或者修改 npm 全局目录权限
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

Windows 系统注意事项

1
2
3
4
5
6
7
# Windows 上可能需要管理员权限
# 以管理员身份运行 PowerShell 或命令提示符

# 检查全局安装目录
npm config get prefix

# 确保有写入权限
  1. 开发流程

    1
    2
    3
    4
    5
    6
    7
    # 1. 在包项目中开发
    npm run dev

    # 2. 在测试项目中测试
    npm link your-package

    # 3. 修改 → 构建 → 测试循环
  2. 版本管理

    1
    2
    3
    4
    5
    # 在发布前确保取消所有链接
    npm unlink

    # 测试正式安装
    npm install your-package@latest
  3. 团队协作

    1
    2
    # 使用相对路径避免全局冲突
    npm link ../team-member-package

4. 测试配置(可选)

package.json 添加测试配置:

1
2
3
4
5
6
7
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:link": "npm run build && cd test-project && npm test"
}
}

jest.config.js

1
2
3
4
5
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/test/**/*.test.ts']
};

第五步:发布前配置

1. 忽略文件配置

.gitignore - Git 版本控制忽略规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 依赖目录
node_modules/

# 构建输出
dist/
build/

# 日志文件
*.log
npm-debug.log*

# 环境变量
.env
.env.local
.env.production

# 系统文件
.DS_Store
Thumbs.db

# IDE 配置
.vscode/
.idea/

.npmignore - NPM 发布忽略规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 源代码目录
src/

# 配置文件
tsconfig.json
jest.config.js
.eslintrc.js

# 开发依赖
node_modules/

# 测试文件
test/
*.test.ts
*.spec.ts

# Git 相关
.git/
.gitignore

# 开发工具配置
.eslintignore
.prettierrc

# 临时文件
*.tmp
*.temp

2. 文档和许可证

README.md - 项目文档模板:

1
2
3
4
5
6
7
# My Package

功能描述和使用说明

## 安装
```bash
npm install my-package

使用

1
2
3
import MyLibrary from 'my-package';

const lib = new MyLibrary();

API 文档

  • serveExpress() - Express 中间件
  • serveKoa() - Koa 中间件

许可证

MIT

1
**LICENSE** - MIT 许可证模板:

MIT License

Copyright (c) [year] [fullname]

Permission is hereby granted…

1
2
3
4
5
6
7
8
9
10
11
## 第六步:发布流程

### 1. 版本管理
```bash
# 查看当前版本
npm version

# 升级版本(遵循语义化版本)
npm version patch # 修复 bug
npm version minor # 新增功能
npm version major # 不兼容变更

2. 发布前检查

1
2
3
4
5
6
7
8
# 构建项目
npm run build

# 运行测试
npm test

# 验证包内容
npm pack

3. 发布到 NPM

1
2
3
4
5
6
7
8
9
10
11
# 登录 NPM(首次)
npm login

# 发布正式版
npm publish

# 发布测试版
npm publish --tag beta

# 撤销发布(24小时内)
npm unpublish my-package@1.0.0

4. 发布后验证

1
2
3
4
5
6
7
8
# 创建测试项目验证
mkdir test-project
cd test-project
npm init -y
npm install my-package

# 测试导入
node -e "console.log(require('my-package'))"

第七步:配置参数详解

package.json 关键字段说明

字段 作用 配置时机 示例值
name 包名,全局唯一 项目初始化 "my-package"
version 版本号,语义化版本 每次发布 "1.0.0"
description 包的功能描述 项目初始化 "A useful library"
main CommonJS 入口文件 构建配置后 "dist/index.js"
types TypeScript 类型文件 添加 TS 后 "dist/index.d.ts"
files 发布到 npm 的文件 发布前确定 ["dist", "static"]
scripts 自定义脚本命令 开发过程中 {"build": "tsc"}
keywords 搜索关键词 项目初始化 ["library", "tool"]
repository 代码仓库地址 项目初始化 {"type": "git", "url": "..."}

tsconfig.json 配置项详解

配置项 作用 推荐值 说明
target 编译目标版本 ES2020 现代 JavaScript 特性
module 模块系统 CommonJS Node.js 兼容性
outDir 输出目录 "./dist" 编译后文件位置
rootDir 源代码目录 "./src" 源代码组织
declaration 生成类型文件 true TypeScript 类型支持
sourceMap 生成源码映射 true 调试支持
strict 严格模式 true 类型安全检查
esModuleInterop ES 模块互操作 true 兼容性优化

第八步:构建机制解析

TypeScript 编译器 (tsc) 构建过程

  1. 源代码扫描: 根据 include 模式匹配 .ts 文件
  2. 类型检查: 使用 strict 配置进行严格类型验证
  3. 代码转换: 将 TypeScript 转换为指定 target 的 JavaScript
  4. 文件输出: 保持目录结构输出到 outDir 目录
  5. 附加文件: 生成 .d.ts 类型声明和 .map 源码映射

tsup 构建过程(基于 esbuild)

  1. 入口分析: 解析指定的入口文件及其依赖
  2. 依赖打包: 使用 esbuild 将依赖打包到单个文件中
  3. 格式转换: 根据配置生成 CommonJS 和 ES Modules 格式
  4. 类型生成: 使用 TypeScript 编译器 API 生成类型声明文件
  5. 源码映射: 生成源码映射文件用于调试
  6. 输出优化: 应用 Tree Shaking 和代码压缩(可选)

tsc 文件映射关系

1
2
3
4
5
6
7
8
src/                    dist/
├── index.ts ├── index.js
├── utils/ ├── index.d.ts
│ └── helper.ts ├── index.js.map
└── types/ └── utils/
└── api.ts └── helper.js
└── helper.d.ts
└── helper.js.map

tsup 文件映射关系

1
2
3
4
5
6
7
8
src/                    dist/
├── index.ts ├── index.js # CommonJS 格式
├── utils/ ├── index.mjs # ES Modules 格式
│ └── helper.ts ├── index.d.ts # 类型声明
└── types/ ├── index.d.mts # ES Modules 类型声明
└── api.ts ├── index.js.map # CommonJS 源码映射
├── index.mjs.map # ES Modules 源码映射
└── (依赖被打包到输出文件中)

tsup 与 tsc 对比

特性 tsc tsup
构建速度 较慢 极快(基于 esbuild)
配置复杂度 中等 简单(零配置)
多格式支持 需要多次构建 单次构建支持多格式
Tree Shaking 有限 优秀
依赖打包 不支持 支持
源码映射 支持 支持
类型生成 支持 支持
代码分割 不支持 支持

tsup 构建流程详解

1. 入口解析阶段

  • 分析入口文件的导入依赖
  • 构建完整的依赖图
  • 排除外部依赖(通过 –external 配置)

2. 打包阶段

  • 使用 esbuild 进行快速打包
  • 应用 Tree Shaking 移除未使用代码
  • 处理模块解析和路径转换

3. 格式转换阶段

  • 根据 –format 配置生成不同格式
  • CommonJS: 使用 module.exports 和 require
  • ES Modules: 使用 import/export 语法

4. 类型生成阶段

  • 使用 tsc API 生成 .d.ts 文件
  • 为不同格式生成对应的类型声明
  • 保持类型定义的准确性

5. 输出优化阶段

  • 生成源码映射文件
  • 应用代码压缩(–minify)
  • 清理输出目录(–clean)

第九步:常见问题解决

1. 类型声明不生效

  • 原因: declaration 配置为 falsetypes 字段缺失
  • 解决: 确保 tsconfig.jsondeclaration: truepackage.json 中正确配置 types 字段

2. 模块导入错误

  • 原因: 模块导出配置不正确
  • 解决: 同时支持 ES6 和 CommonJS 导出方式

3. 静态资源路径问题

  • 原因: 发布后路径变化
  • 解决: 使用 __dirnamepath.join() 构建绝对路径

4. tsup 构建常见问题

问题:CommonJS 导入时出现 “TypeError: X is not a constructor”

  • 原因: tsup 将 ES Modules 默认导出转换为 module.exports.default
  • 解决:
    • 使用命名导入:const { Knife4jDoc } = require('package-name')
    • 使用默认导入:const Knife4jDoc = require('package-name').default
    • 在 package.json 中配置正确的 exports 字段

问题:构建后文件过大

  • 原因: 依赖被打包到输出文件中
  • 解决:
    • 使用 --external 排除外部依赖
    • 配置 --splitting 启用代码分割
    • 使用 --minify 压缩代码

问题:类型声明文件不完整

  • 原因: tsup 的类型生成可能不完整
  • 解决:
    • 确保源代码有完整的类型定义
    • 使用 --dts 标志生成类型声明
    • 检查 tsconfig.json 中的类型配置

问题:ES Modules 和 CommonJS 导入不一致

  • 原因: exports 字段配置不正确
  • 解决:
    • 在 package.json 中配置完整的 exports 字段
    • 确保 import 和 require 指向正确的文件
    • 测试两种导入方式是否正常工作

问题:构建速度慢

  • 原因: 配置不当或依赖过多
  • 解决:
    • 使用 --external 排除不必要的依赖
    • 启用 --minify 减少文件大小
    • 考虑使用缓存或增量构建

5. tsup 配置优化建议

性能优化

1
2
3
4
5
6
7
8
# 排除外部依赖,减少打包体积
npx tsup src/index.ts --external react,vue,lodash

# 启用代码分割
npx tsup src/index.ts --splitting

# 生产环境压缩
npx tsup src/index.ts --minify

兼容性优化

1
2
3
4
5
6
7
8
# 指定目标环境
npx tsup src/index.ts --target node16

# 配置平台
npx tsup src/index.ts --platform node

# 启用 CommonJS 互操作
npx tsup src/index.ts --cjs-interop

开发体验优化

1
2
3
4
5
6
7
8
# 监听模式开发
npx tsup src/index.ts --watch

# 生成源码映射便于调试
npx tsup src/index.ts --sourcemap

# 清理输出目录
npx tsup src/index.ts --clean

第十步:最佳实践总结

开发规范

  1. 代码组织: 使用 src/ 目录组织源代码
  2. 类型安全: 充分利用 TypeScript 类型系统
  3. 文档完善: 提供完整的 API 文档和使用示例
  4. 测试覆盖: 添加单元测试确保功能稳定

发布规范

  1. 版本管理: 严格遵循语义化版本规范
  2. 文件控制: 精确控制发布内容,避免泄露源代码
  3. 质量保证: 发布前进行完整测试和验证
  4. 持续集成: 考虑添加自动化测试和发布流程

维护规范

  1. 更新日志: 维护 CHANGELOG.md 记录变更
  2. 问题跟踪: 使用 GitHub Issues 管理问题
  3. 社区支持: 提供清晰的贡献指南

第十一步:发布到 npm 官网的完整流程

1. 账号准备阶段

检查是否已有 npm 账号

1
2
3
4
5
# 检查当前登录状态
npm whoami

# 如果显示用户名,说明已登录
# 如果显示错误 "Not logged in",说明需要登录

注册 npm 账号(如果没有)

  1. 访问官网: https://www.npmjs.com/signup
  2. 填写信息:
    • 用户名(username): 全局唯一,将作为包名前缀
    • 邮箱地址: 用于验证和通知
    • 密码: 至少8个字符
  3. 邮箱验证: 检查邮箱并点击验证链接
  4. 双重验证(推荐): 启用 2FA 增强安全性

账号验证准备

  • 确保邮箱可以正常接收邮件
  • 准备手机用于 2FA(如果启用)
  • 记录用户名和密码到安全位置

2. 本地环境配置

检查 npm 版本

1
2
3
4
5
# 确保使用最新版本 npm
npm -v

# 如果需要更新
npm install -g npm@latest

配置 npm 镜像(如果需要)

1
2
3
4
5
6
7
8
9
10
11
# 检查当前镜像
npm config get registry

# 如果需要切换回官方镜像
npm config set registry https://registry.npmjs.org/

# 配置淘宝镜像(仅用于安装,发布时必须用官方)
npm config set registry https://registry.npmmirror.com/
# 发布前切换回官方镜像
npm config set registry https://registry.npmjs.org/

可以使用nrm切换npm镜像

3. 登录 npm

命令行登录

1
2
3
4
5
6
7
8
9
10
# 执行登录命令
npm login

# 按提示输入信息
Username: your-username
Password: ********
Email: your-email@example.com

# 如果启用了 2FA,需要输入一次性密码
Enter one-time password: 123456

登录验证

1
2
3
4
5
6
# 验证登录状态
npm whoami
# 应该显示你的用户名

# 查看当前用户信息
npm profile get

登录问题排查

  • 认证失败: 检查用户名/密码,或重置密码
  • 网络问题: 检查网络连接和防火墙设置
  • 2FA 问题: 确保手机时间同步,重新生成验证码

4. 发布前最终检查

包名检查

1
2
3
4
5
# 检查包名是否可用,如果冲突会让你使用你的用户名作为前缀
npm search your-package-name

# 或者直接尝试发布,如果冲突会提示
npm publish --dry-run

版本号检查

1
2
3
4
5
6
7
# 查看当前版本
npm version

# 如果需要更新版本
npm version patch # 修复 bug(1.0.0 → 1.0.1)
npm version minor # 新增功能(1.0.0 → 1.1.0)
npm version major # 不兼容变更(1.0.0 → 2.0.0)

文件内容检查

1
2
3
4
5
6
7
8
# 生成发布包预览
npm pack

# 查看包内容
tar -tzf your-package-1.0.0.tgz

# 应该只包含 dist/, static/, README.md, LICENSE 等必要文件
# 不应该包含 src/, test/, 配置文件等

5. 正式发布流程

第一次发布

1
2
3
4
5
# 执行发布命令
npm publish

# 输出示例
+ your-package@1.0.0

发布后验证

1
2
3
4
5
6
7
8
9
10
11
# 查看包信息
npm info your-package

# 创建测试项目验证
mkdir test-package
cd test-package
npm init -y
npm install your-package

# 测试导入
node -e "console.log(require('your-package'))"

发布到特定标签

1
2
3
4
5
6
7
8
# 发布到 beta 标签
npm publish --tag beta

# 安装特定标签
npm install your-package@beta

# 将 beta 标签设置为最新
npm dist-tag add your-package@1.0.0 latest

6. 发布后管理

版本管理

1
2
3
4
5
6
7
8
9
10
11
# 查看所有版本
npm view your-package versions

# 查看标签
npm dist-tag ls your-package

# 删除特定版本(24小时内)
npm unpublish your-package@1.0.0

# 删除整个包(72小时内,需要支持)
npm unpublish your-package --force

包信息更新

1
2
3
4
5
6
7
8
9
# 更新包描述
npm pkg set description="New description"

# 更新关键词
npm pkg set keywords='["new", "keywords"]'

# 更新仓库信息
npm pkg set repository.type=git
npm pkg set repository.url=https://github.com/your/repo

维护更新

1
2
3
4
5
6
# 发布新版本
npm version patch && npm publish

# 或者手动更新版本号后发布
# 修改 package.json 中的 version,然后
npm publish

7. 常见发布问题解决

包名冲突

1
2
3
4
# 错误信息:Package name already exists
# 解决方案:修改包名或使用作用域包
npm init --scope=your-username
# 包名变为:@your-username/package-name

权限问题

1
2
3
4
# 错误信息:E403
# 解决方案:检查登录状态和包权限
npm whoami
npm owner ls your-package

网络超时

1
2
3
# 错误信息:ETIMEDOUT
# 解决方案:检查网络,重试发布
npm publish --retry 3

2FA 要求

1
2
3
# 错误信息:OTP required
# 解决方案:启用 2FA 或使用一次性密码
npm profile enable-2fa auth-only

8. 最佳实践建议

安全性

  • 启用 2FA 保护账号
  • 使用强密码并定期更换
  • 不要在公共代码中泄露令牌

版本管理

  • 严格遵循语义化版本规范
  • 为重大变更提供迁移指南
  • 维护详细的更新日志

质量控制

  • 发布前运行完整测试套件
  • 使用 CI/CD 自动化测试和发布
  • 提供清晰的文档和示例

社区维护

  • 及时回复 issue 和 PR
  • 定期更新依赖项
  • 考虑添加贡献指南

完整流程总结

通过以上标准化流程,您可以:

  • 从零开始创建专业的 npm 包
  • 确保代码质量和类型安全
  • 支持多种使用场景和框架
  • 规范发布和维护流程
  • 提供良好的开发者体验

这个流程适用于大多数 Node.js 库的开发,可以根据具体需求进行调整和扩展。

本文作者:辰風依恛
本文链接:https://766187397.github.io/2025/10/18/Node.js%20%E5%87%BD%E6%95%B0%E6%89%93%E5%8C%85%E4%B8%BA%20npm%20%E5%8C%85%E7%9A%84%E8%A7%84%E8%8C%83%E6%B5%81%E7%A8%8B/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×