一、背景 本次将 NPM 包 yt-comment-date-format 从 1.0.3 版本升级至 2.0.1,核心目标是为其添加 TypeScript 支持,让使用者获得完整的类型推断能力。本文完整记录从配置调整到发布上线的全流程,适用于所有 TS 包的 NPM 发布场景。
二、前置准备 1. 环境配置
注册 NPM 账号:前往 NPM 官网 完成注册;
安装 Node.js/NVM:推荐使用 NVM 管理 Node.js 版本(避免版本兼容问题);
初始化项目:1 2 3 4 npm init -y tsc --init
2. 核心依赖安装 1 2 3 4 npm install typescript --save-dev npm install dayjs --save
三、关键配置调整 1. tsconfig.json:开启类型声明生成 修改 tsconfig.json,核心配置如下(其他配置可按需调整):
1 2 3 4 5 6 7 8 9 10 11 12 13 { "compilerOptions" : { "target" : "es5" , "module" : "commonjs" , "declaration" : true , "outDir" : "dist" , "strict" : true , "esModuleInterop" : true , "skipLibCheck" : true , "forceConsistentCasingInFileNames" : true } , "exclude" : [ "node_modules" , "dist" ] }
注意:若包内有私有类型但需对外暴露(如接口、类型别名),需为其添加 export,否则使用者无法获取类型推断。
2. package.json:指定入口与类型文件 在 package.json 中添加/修改以下配置,告诉 NPM 和 TS 编译器包的入口与类型文件位置:
1 2 3 4 5 6 7 8 9 10 { "main" : "dist/index.js" , "types" : "dist/index.d.ts" , "files" : [ "dist" ] , "scripts" : { "build" : "tsc" , "test" : "npm run build && node test.js" , "release" : "tsc && npm publish" } }
3. .gitignore:忽略编译产物 避免将编译后的 dist 目录提交到 Git 仓库(仅保留源码):
1 2 3 # .gitignore node_modules/ dist/
四、构建与测试 1. 编写 TS 源码(示例) 入口文件 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 40 41 42 43 44 45 46 47 48 49 50 51 52 'use strict' ;import dayjs from 'dayjs' ;export function commentTimeFormat (time4server: number , time4comment: number ): string { const a = dayjs (time4server); const b = dayjs (time4comment); const originDate = (fm: string ) => a.format (fm); const c = dayjs (originDate ('YYYY-MM-DD' )); const d = dayjs (originDate ('YYYY-01-01' )); const diff = a.diff (b, 'seconds' ); const diffMinute = a.diff (b, 'minutes' ); const diffHour = a.diff (b, 'hours' ); const diffTodayHour = a.diff (c, 'hours' ); const diffCurrent = a.diff (d, 'seconds' ); const textConfig = ['刚刚' , '分钟前' , '小时前' , '昨天 HH:mm' , 'M月D日 HH:mm' , 'YYYY年M月D日 HH:mm' ]; let newTime = '' ; if (diff > diffCurrent) { newTime = b.format (textConfig[5 ]); } else { if (diffHour - diffTodayHour >= 24 ) { newTime = b.format (textConfig[4 ]); } else if (diffHour >= diffTodayHour) { newTime = b.format (textConfig[3 ]); } else { newTime = diffHour >= 1 ? `${diffHour} ${textConfig[2 ]} ` : diffMinute >= 1 ? `${diffMinute} ${textConfig[1 ]} ` : textConfig[0 ]; } } return newTime; }
2. 编写测试脚本 测试文件 test.js(验证格式化逻辑):
1 2 3 4 5 6 7 8 9 10 const { commentTimeFormat } = require ('./dist/index.js' );const now = 1560845869969 ; console .log (commentTimeFormat (now, now - 1000 *59 )); console .log (commentTimeFormat (now, now - 1000 *60 *59 )); console .log (commentTimeFormat (now, now - 1000 *60 *60 *23 )); console .log (commentTimeFormat (now, now - 1000 *60 *60 *24 *1.9 )); console .log (commentTimeFormat (now, now - 1000 *60 *60 *24 *17 )); console .log (commentTimeFormat (now, now - 1000 *60 *60 *24 *500 ));
3. 执行构建与测试 1 2 3 4 npm run build npm run test
五、发布流程 1. 版本管理 NPM 提供标准化版本更新命令,避免手动修改版本号:
1 2 3 4 5 6 npm version patch npm version minor npm version major
2. 切换 NPM 官方源 发布前需将镜像切回 NPM 官方源(避免发布失败):
1 2 3 4 npm config get registry npm config set registry https://registry.npmjs.org
3. 登录 NPM 账号
4. 发布包 1 2 3 4 npm publish --access public npm run release
注意:若包名已被占用,需修改 package.json 中的 name 字段。
5. 本地调试(发布前验证) 发布前可通过 npm link 本地调试包,避免发布后发现问题:
1 2 3 4 5 6 npm link npm link yt-comment-date-format import { commentTimeFormat } from 'yt-comment-date-format' ;
六、撤销/标记废弃发布 1. 推荐:标记包/版本为废弃 不建议直接删除已发布的包(可能影响依赖该包的项目),优先使用 deprecate 标记:
1 2 3 4 npm deprecate yt-comment-date-format@2.0.1 '该版本存在 bug,建议升级至 2.0.2' npm deprecate yt-comment-date-format '该包已不再维护,请使用 xxx 替代'
2. 撤销发布(谨慎使用) 1 2 3 4 npm unpublish yt-comment-date-format@2.0.1 --force npm unpublish yt-comment-date-format --force
七、镜像配置(npmmirror 替代淘宝镜像) 淘宝 NPM 镜像已迁移至 npmmirror,推荐使用最新镜像地址:
1 2 3 4 5 6 npm config set registry https://registry.npmmirror.com npm --registry https://registry.npmmirror.com install 包名 npm install -g cnpm --registry=https://registry.npmmirror.com
八、完整配置示例 1. package.json 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 { "author" : { "name" : "yhorz.cn/csorz" } , "bundleDependencies" : false , "dependencies" : { "dayjs" : "^1.10.4" } , "deprecated" : false , "description" : "评论时间格式化" , "devDependencies" : { "typescript" : "^4.2.4" } , "license" : "ISC" , "main" : "dist/index.js" , "name" : "yt-comment-date-format" , "scripts" : { "build" : "tsc" , "release" : "tsc && npm publish --access public" , "test" : "npm run build && node test.js" } , "types" : "dist/index.d.ts" , "version" : "2.0.1" , "files" : [ "dist" ] }
2. tsconfig.json 1 2 3 4 5 6 7 8 9 10 11 12 13 { "compilerOptions" : { "target" : "es5" , "module" : "commonjs" , "declaration" : true , "outDir" : "dist" , "strict" : true , "esModuleInterop" : true , "skipLibCheck" : true , "forceConsistentCasingInFileNames" : true } , "exclude" : [ "node_modules" , "dist" ] }
总结 关键点回顾
TS 包发布核心:开启 declaration: true 生成 .d.ts 文件,并在 package.json 中指定 types 字段;
发布流程:配置调整 → 构建测试 → 版本更新 → 切换官方源 → 登录发布;
镜像配置:日常开发使用 npmmirror(https://registry.npmmirror.com),发布前切回 NPM 官方源;
最佳实践:发布前用 npm link 本地调试,废弃包优先用 deprecate 而非 unpublish。
遵循以上流程可确保 TS 包发布后具备完整的类型支持,同时规避发布过程中的常见问题(如镜像错误、版本冲突、类型缺失)。