Codog

关注微信公众号:Codog代码狗

0%

比较完整的NPM发包流程

现在的npm包是越来越卷了,之前只要把能用的js文件打包发到npm上就可以了,现在随着技术更新迭代,又多了一些需求,常见比如typescript支持,支持ES模块。

通过一个MR请求,我也是整理了下之前理解有误的地方,再结合一些别人的实践,重新发一个包,比较完整的说明下当前npm包的发布流程,以及一些常见的问题。

通过一个实际的小功能,转换数值类型到中文字符表示,比如传入123,返回“一百二十三”,这个功能之前自己试着实现了下,当前npm上有几个类似的,多一个也不过分吧。。

包含哪些内容?

  • 如何发布一个typescript包,包含函数声明文件
  • rollup打包,支持UMD格式和ES Module格式
  • 一些package.json字段说明
  • 比较实用的小技巧

初始化

使用npm init初始化,填入必要的字段。

新建src/index.ts文件,并将之前的js代码拷贝过来,补全相关的类型定义

打包编译

首先需要打包编译成js代码,并进行相关压缩操作。这里使用rollup,相比webpack它更轻量,配置少,比较适合工具库的打包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// rollup.config.js
import { terser } from 'rollup-plugin-terser';
import typescript from 'rollup-plugin-typescript2';

export default {
input: 'src/index.ts',
output: [
{
file: 'lib/index.esm.js',
format: 'es',
},
{
file: 'lib/index.umd.js',
format: 'umd',
name: 'num2Cn',
},
],
plugins: [
terser(),
typescript()
]
};

上述文件就说明了我们要打包编译出两个文件,UMD格式的和ES Module格式的。UMD格式需要定义一个变量,这样在浏览器环境下,所有的方法都会挂载在这个变量上了。

还需要typescript插件做编译,terser插件做代码压缩。注意,这里使用的是rollup-plugin-typescript2插件而不是官方提供的,我的原因是导出声明文件配置麻烦而且一直没成功。。

关于typescript相关配置需要再新建tsconfig.json文件。我这里是这样的。

1
2
3
4
5
6
7
8
9
10
11
12
{
"compilerOptions": {
"rootDir": "./src",
"declaration": true,
"outDir": "./lib",
"target": "ES2015",
"module": "ES2020",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
}
}

使用declaration声明需要类型定义.d.ts文件,target表示要编译出的代码格式,一般使用es6,module表示源代码的语法版本,这是使用最新的es2020。

接下来,需要执行rollup --config就可以发现项目目录下多了3个文件了:
image

不放心的话可以在本地测试下打包的结果。没问题后就进入发布流程了。

发布

一个PR引发的思考。。

在发布前我们先想一下,哪些东西是使用者实际需要的?

最直接的,当然是打包出来的结果,也就是lib文件里的内容,源代码需要吗?通常情况为了方便开发者调试,一般也会发布到npm上。其他测试文件需要吗?这个其实是不需要的。

还有一点,哪些文件是需要推送到版本管理工具上的?lib文件需要吗?实际不需要,因为这个可读性比较差,不太适合放到github上,而测试文件或者可能的一些管理文件、说明文件就比较需要了。

了解这点很重要,github和npm有各自的诉求,不能一股脑的全部推送。

管理github同步当然是用.gitignore来控制了,我这里的是:

1
2
3
4
node_modules/
lib/
npm-debug.log
yarn-error.log

npm对于这方面的处理逻辑比较多,会首先检查package.json中的files字段,然后是自己的.npmignore文件,最后使用.gitignore文件。关于这点可以查看文档:npm文档。我们这里使用files来声明:

1
2
3
4
5
6
7
{
// ....
"files": [
"src/",
"lib/"
],
}

配置之后,如何确认我们将要发布的内容,有以下方式可以选择:

  • 执行npx npm-packlist
  • 执行npm publish --dry-run
  • 执行npx pkgfiles

前两种时官方文档推荐,最后一个是三方包,(参考文档)[https://docs.npmjs.com/cli/v7/commands/npm-publish]

做如下配置:

1
2
3
4
5
6
{
// ...
"main": "lib/index.umd.js",
"module": "lib/index.esm.js",
"types": "lib/index.d.ts",
}

都准备好了就可以发布了,首先需要把所有更改都提交,首次发布的话无需升级版本,否则需要执行npm version patch|mirror|major。还有它会在git打一个tag,可以执行git push --tags来推送到github。

然后执行npm publish即可,这样一个npm包就发布成功了。

做个小总结,发布流程一般为:

  • 编码及测试
  • git提交更改
  • npm run build
  • npm version patch|mirror|major
  • npm publish

示例包地址:number-to-chinese,有场景使用的话希望多多支持~

最后

关于npm发布还有很多最佳实践,像这次我是参考他人的经验和vue是如何书写package.json文件的,通过jsdelivr可以方便的查看包内容。还有一个np包,专门用来做npm发布管理的,感兴趣可以去尝试下。

参考文章: