Npm包发布实践

从接触 npm 到现在已经几年了,一直都是在使用别人发布到 npm 包,虽然自己也想发布 npm 包供大家使用,但一直都没有好的点子.因为工作中经常会用到一些常用正则,或者是常用的工具函数,而我又暂时没有发现 npm 上相关的 npm 包,觉得这个想法不错,也在此将本次发布 npm 包的过程记录下来,以便总结.

创建基于 typescript 的 npm 包

考虑到现在 typescript 的使用场景越来越多,所以使用 typescript 越来越有必要了.

1、创建 npm 包目录

1
2
3
4
cd your work path
mkdir target dir
cd dir
npm init

2、安装 typescript

1
npm install -g typescript

3、配置 typsceript 编译配置

1
tsc --init

现在就默认生成了 typescript 编译配置了,可以看到有很多配置项,但现在我们只需要关注以下几项:

1
2
3
4
5
6
7
8
9
10
11
12
{
"compilerOptions": {
...
"module": "umd",
...
"declaration": true,
...
},
"include": [
"./src/*.ts"
]
}

module 是指 ts 编译为 js 后所支持的模块,一般是 commonjs、amd、umd 和 es[x]等,umd 是指同时支持 amd 和 commonjs

declaration 是自动生成*.d.ts 描述文件,因为最终我们编写的 ts 代码都会编译为 ts,如果 ts 直接使用 js 包,就不能推断出类型,所以 ts 使用 js 需要 d.ts 描述文件

include 则是需要编辑的文件

当然还有很多配置,了解更多请前往tsconfig.json · TypeScript 中文网 · TypeScript——JavaScript 的超集查看

写一个简单的功能

我就以当前项目为列子,在项目根目录创建 src 目录并在 src 下创建 index.ts,写入以下代码

1
2
3
4
5
6
7
8
// isEmpty
const isEmpty = function (input: string): boolean {
return !!!input;
};

export { isEmpty };

export default { isEmpty };

因为 node 模块引入的是一个对象,所以上面加了最后一行 export default

现在我们在 vs code 里使用快捷键 ctrl+shift+b 或者在控制台进入当前目录执行 tsc 命令,顺利的话会在根目录生成 dist 文件夹,里面包含.js、.js.map、.d.ts 文件.

单元测试

现在虽然代码部分写完了,但我们还没有测试,也不知道写的对不对,所以需要进行单元测试.我使用的是 karma+jasmine.

1、安装相关依赖

1
2
3
npm i karma-cli -g
mpn i -D karma karma-jasmine karma-typescript @types/jasmine

2、测试配置

1
karma init

会在项目根目录下生成 karma.conf.js,因为我使用的是 ts,所以对 karma.conf.js 做一些修改,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
frameworks: ['jasmine', 'karma-typescript'],
files: [
'src/*.ts',
'test/*.spec.ts'
],
preprocessors: {
'src/*.ts': 'karma-typescript',
'test/*.spec.ts': 'karma-typescript'
},
reporters: ['progress', 'karma-typescript'],
browsers: ['ChromeHeadless'],
...

当然还有很多配置,了解更多请前往http://karma-runner.github.io查看

然后我们在根目录下创建 test 目录并创建 index.spec.ts,编写以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import verify from "../src/index";
// 或者
import { isEmpty } from "../src/index";

describe("This is isEmpty", () => {
let empty = "";
let notEmpty = "i am not empty";

it("This is empty", () => {
expect(verify.isEmpty(empty)).toBe(true);
});

it("This is not empty", () => {
expect(verify.isEmpty(notEmpty)).toBe(false);
});
});

然后在控制台运行 karma start,不出意外可以开到如下界面:
201908051703.png
并且 karma 会在根目录下生成测试报告,在 coverage 目录下,打开 index.html 就可以看到测试报告了.

发布 npm 包

修改入口文件,在 package.json 中将 index.js 修改为./dist/index.js

其实在发布之前还可以将我们对代码进行混淆,我们也不用这么麻烦,可以配置 webpack 来编译 ts、执行测试命令、打包混淆编译后都 js 代码等,这里我就先不说了.

在发布 npm 的时候我们先要有一个 git 仓库存放我们都代码,我使用都 github.这里就不做介绍了,下面都操作默认已经关联了 git 仓库.

发布都时候如果不想把所有都文件都提交到 npm 可以添加.npmignore 文件,规则和.gitnore 类似,

如果 npm 包是第一次发布:

1
2
npm whoami  // 验证本地npm账户凭据,验证失败则会提示你添加npm账户,按着提示走就行了
npm publish --access=public // 公开发布,如果不公开去掉--access=public即可

如果已经发布过了,只是更新

1
npm publish

另外在发布的时候,如果包名重复了,则会提示你,换个报名就好了,但是找不到合适的包名这么办呢,可以用你的用户名或者还没有使用过的名字作为前缀,如:

1
"name": "@yourname/packagename"

删除/废弃 npm 包

npm unpublish
npm deprecate [@version]

注意事项:

  1. 发布/更新的时候,必须使用 npmjs.com 源,不然会失败
  2. 每次更新 npm 包的时候都需要更新版本号,npm 不允许更新包后不更新版本
  3. npmjs.org 不支持删除发布时间超过二十四小时的包,建议使用废弃命令

参考文章: npm 包的发布

参考文章: npm 新的包命名规范

[越努力,越幸运!]