[译文]一步步构建发布一个 TypeScript NPM 包
介绍
在这篇文章中,我们会使用 TypeScript, TSLint, Prettier, Jest
等构建并发布一个 NPM TypeScript 包。下面将会是我们要构建的:
前提
- 下载 Node.js 和 NPM。
node -v // v8.12.0 npm -v // v6.4.1
- 选一个好的包名。包名必须是 pascal-case 并且全部小写。因为 NPM 上有 700k+ 的包,所以你需要在构建之前先去 www.npmjs.com/ 查询你的包名有没有被使用。在本文中,我取了 irene-awesome-gretter。
基本构建
- 选择一个合适的名字创建包文件夹。
mkdir irene-awesome-greeter && cd irene-awesome-greeter
- 新建
.gitignore
文件并写入 node_modules,新建README
文件。echo "node_modules" >> .gitignore echo "# Irene Awesome Greeter" >> README.md
- Git 初始化包并关联远程仓库。下面 Git Repository Url 是远程仓库的 Url。
git init git add . && git commit -m "Initial commit" git remote add origin <Git Repository Url> git push -u origin master
- NPM 初始化包,后续我们会修改生成的
package.json
。
至此,生成的目录结构如下:npm init -y
添加 TypeScript as devDependencies
Formatting & Linting
- 下载
prettier tslint tslint-config-prettier
。和TypeScript
一样,它们只是在包开发阶段所需的工具,所以是 devDependencies。
一个好的包应该包括严格的代码规范,尤其是有其他协作者共同开发时。npm i -D prettier tslint tslint-config-prettier
tslint-config-prettier
能防止TSLint
和Prettier
格式化规则的冲突。 - 在根目录下,新建
tslint.json
,添加如下内容:{ "extends": ["tslint:recommended", "tslint-config-prettier"] }
- 在根目录下,新建
.prettierrc
,添加如下内容:{ "printWidth": 120, "trailingComma": "all", "singleQuote": true }
- 最后,在
package.json
中添加 lint 和 format script。
现在,你的"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", "lint": "tslint -p tsconfig.json"
package.json
应该长这样:在控制台运行 npm run lint / npm run format
npm run lint npm run format
移除不必要文件
在 .gitignore
中,我们添加 /lib 是因为不想 Git 远程仓库中有编译后的文件,但对于要发布的包则恰恰相反,我们不要源代码,只需要编译后的文件!有两种方式可以实现:
- 黑名单:新建一个
.npmignore
文件,在其中添加不要的文件(夹)。
但是,这并不是一个好的实践,因为根目录下每次新增加一个文件(夹)都需要添加到src tsconfig.json tslint.json .prettierrc
.npmignore
中,于是有了下面这种方式。 - 白名单:在
package.json
中设置一个要发布的文件(夹)白名单
就是这么的简单!只有 lib 文件夹会出现在发布的包里(README.md 和 package.json 会被默认添加)。更多关于黑名单 VS 白名单的内容可以参考 blog.npmjs.org/post/165769…"files": ["lib/**/*"]
Jest Testing
一个好的包应该要包括单元测试。接下来,我们添加 Jest —— Facebook 开发的一个非常棒的测试框架。
- 因为我们是针对 ts 源文件编写测试用例,所以除了
jest
还需要ts-jest @types/jest
,它们只是在开发阶段需要,所以添加到 devDependencies。npm i -D jest ts-jest @types/jest
- 配置 Jest。有两种方式,在
package.json
添加 "jest" 字段 或者 新建一个单独的配置文件。我们选择后者,因为前者配置内容会被添加到发布的包中而后者不会。新建jestconfig.json
,添加如下内容:
移除{ "transform": { "^.+\\.(t|j)sx?$": "ts-jest" }, "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"] }
package.json
中的 "test" script,添加一个新的 test script。
现在,你的"test": "jest --config jestconfig.json",
package.json
长下面这样:
写一个测试用例
是时候写一个测试用例了。在 src
目录下,新建一个 __tests__
文件夹,在其中新建一个测试文件,文件名必须以 test.ts
结尾,例如:Greeter.test.ts。
import { Greeter } from '../index';
test('My Greeter', () => {
expect(Greeter('Carl')).toBe('Hello Carl');
});
这个测试用例验证了当输入 'Carl' 的时候,Greeter 方法是否返回 'Hello Carl'。 接下来我们运行一下
npm run test
![[译文]一步步构建发布一个 TypeScript NPM 包](https://static.blogweb.cn/article/8682105be5034951b402d2f947f7b536.webp)
scripts in NPM
一个好的包应该尽可能自动化。接下来,我们来看看 NPM 中其他的 scripts:prepare,prepublishOnly,perversion,version,postversion
。
- prepare:会在打包和发布包之前以及本地
npm install
(不带任何参数)时运行。"prepare": "npm run build"
- prepublishOnly:在
prepare
script 之前运行,并且仅在npm publish
运行。在这里,我们可以运行npm run test & npm run lint
以确保我们不会发布错误的不规范的代码。"prepublishOnly": "npm run test && npm run lint"
- preversion:在发布新版本包之前运行,为了更加确保新版本包的代码规范,我们可以在此运行
npm run lint
。"preversion": "npm run lint"
- version:在发布新版本包之后运行。如果您的包有关联远程 Git 仓库,像我们的情况一样,每次发布新版本时都会生成一个提交和一个新的版本标记,那么就可以在此添加规范代码的命令。又因为
version
script 在git commit
之前运行,所以还可以在此添加git add
。"version": "npm run format && git add -A src"
- postversion:在发布新版本包之后运行,在
git commit
之后运行,所以非常适合推送。"postversion": "git push && git push --tags"
截至目前,我们的 NPM scripts 长下面这样:
"scripts": {
"test": "jest --config jestconfig.json",
"build": "tsc",
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
"lint": "tslint -p tsconfig.json",
"prepare": "npm run build",
"prepublishOnly": "npm run test && npm run lint",
"preversion": "npm run lint",
"version": "npm run format && git add -A src",
"postversion": "git push && git push --tags"
}
终极版 package.json
{
"name": "irene-awesome-greeter",
"version": "1.0.0",
"description": "A nice greeter", //
"main": "lib/index.js", //
"types": "lib/index.d.ts", //
"scripts": {
"test": "jest --config jestconfig.json",
"build": "tsc",
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
"lint": "tslint -p tsconfig.json",
"prepare": "npm run build",
"prepublishOnly": "npm run test && npm run lint",
"preversion": "npm run lint",
"version": "npm run format && git add -A src",
"postversion": "git push && git push --tags"
},
"repository": {
"type": "git",
"url": "git+https://github.com/irenetang1993/irene-awesome-greeter.git"
},
"keywords": ["Hello", "Greeter"], //
"author": "Irene Tang", //
"license": "ISC",
"bugs": {
"url": "https://github.com/irenetang1993/irene-awesome-greeter/issues"
},
"homepage": "https://github.com/irenetang1993/irene-awesome-greeter#readme",
"devDependencies": {
"@types/jest": "^24.0.15",
"jest": "^24.8.0",
"prettier": "^1.18.2",
"ts-jest": "^24.0.2",
"tslint": "^5.18.0",
"tslint-config-prettier": "^1.18.0",
"typescript": "^3.5.2"
},
"files": [
"lib/**/*"
]
}
我们完善了 description,author,keywords 信息,修改了 main
,新增了 types
。 main
字段非常重要,因为指明了模块的入口。types
字段指明了声明文件的入口。
提交并推送到 Git
git add -A && git commit -m "Setup Package"
git push
发布
在发布之前,如果你没有 NPM 账号的话,必须先注册一个。你可以在 www.npmjs.com/signup 上注册或者通过运行 npm adduser
注册。如果你已经有账号了,运行 npm login
登陆你的 NPM 账号。
![[译文]一步步构建发布一个 TypeScript NPM 包](https://static.blogweb.cn/article/3bb3f2d840434022b895984e579f37ba.webp)
好了!现在你可以发布了。
npm publish
可以看到,先运行 prepare
script,在其中运行了 npm run build
,然后运行 prepublishOnly
script,在其中运行了 npm run test && npm run lint
。
![[译文]一步步构建发布一个 TypeScript NPM 包](https://static.blogweb.cn/article/035b16acff72440589dcc8bc67b3508a.webp)
查看你的发布
现在,你可以去 NPM 上查看你刚刚发布的包。URL 是 https://npmjs.com/package/<your-package-name>
,我发布的包就是 npmjs.com/package/ire…
![[译文]一步步构建发布一个 TypeScript NPM 包](https://static.blogweb.cn/article/a551ca158bc848a4a8c6d6646a6808c7.webp)
创建一个新版本
执行如下命令会创建一个新版本, preversion,version,postversion
scripts 会被执行:创建一个新的 tag 并且推送到我们的远程仓库。
npm version patch
![[译文]一步步构建发布一个 TypeScript NPM 包](https://static.blogweb.cn/article/808fab80398b4715b024d359f66f3b51.webp)
我们再发布一次:
npm publish
现在,我们的包就有了一个 1.0.1 的版本:
![[译文]一步步构建发布一个 TypeScript NPM 包](https://static.blogweb.cn/article/56e016efab314d239e1bfa2de7ff123f.webp)
其他文章链接
转载自:https://juejin.cn/post/6844903892119977998