原文:itnext.io/step-by-ste…javascript
在这篇文章中,咱们会使用 TypeScript, TSLint, Prettier, Jest
等构建并发布一个 NPM TypeScript 包。下面将会是咱们要构建的:html
node -v // v8.12.0
npm -v // v6.4.1
复制代码
mkdir irene-awesome-greeter && cd irene-awesome-greeter
复制代码
.gitignore
文件并写入 node_modules,新建 README
文件。echo "node_modules" >> .gitignore
echo "# Irene Awesome Greeter" >> README.md
复制代码
git init
git add . && git commit -m "Initial commit"
git remote add origin <Git Repository Url>
git push -u origin master
复制代码
package.json
。npm init -y
复制代码
至此,生成的目录结构以下:
下载 TypeScript。java
npm i -D typescript
复制代码
下载完后,在根目录下多了 node_modules
文件夹和 package-lock.json
文件。node
为了编译 TypeScript
,咱们须要一个配置文件,在根目录下新建 tsconfig.json
,内容以下。⚠️注意我(译者)在原文配置的基础上添加了 lib,指定了 es6,缘由见 - 详情。git
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"outDir": "./lib",
"strict": true,
"lib": ["es6"]
},
"include": ["src"],
"exclude": ["node_modules", "**/__tests__/*"]
}
复制代码
JavaScript
文件须要遵循的标准,可选值:"ES3"(默认),"ES5","ES6"/"ES2015","ES2016","ES2017"或"ESNext"
。咱们选择了 es5
为了使包具备更好的浏览器兼容性。target === "ES3" or "ES5" ? "CommonJS" : "ES6"
。TypeScript
会将生成的声明文件和对应编译后的 JavaScript
代码一块儿导出,以便包能够在 TypeScript
和 JavaScript
项目中同时使用。本项目中生成的声明文件是 /lib/index.d.ts。JavaScript
代码会在与 tsconfig.json
同级的 lib 文件夹中。ES5
,可是在代码中使用了 ES6
特性,就须要在 lib 中加上 ES6。默认值:若是 lib 没有指定默认注入的库的列表,默认注入的库为:
node_modules
和 __tests__
只是在开发阶段使用,构建阶段无需编译。更多的编译选项可参考 www.typescriptlang.org/docs/handbo…es6
建立 src
文件夹,在其下新建一个 index.ts,内容以下:github
export const Greeter = (name: string) => `Hello ${name}`;
复制代码
在 package.json
中添加 build script。typescript
"build": "tsc"
复制代码
除了 package-lock.json
之外, 咱们通常都不但愿提交自动生成的文件到 Git 上去,由于只要改变了源文件,每次 build 的时候它们都不一样,就会形成不少冲突,因此咱们把 lib 文件夹放到 .gitignore
中。npm
node_modules
/lib
复制代码
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
复制代码
在 .gitignore
中,咱们添加 /lib 是由于不想 Git 远程仓库中有编译后的文件,但对于要发布的包则偏偏相反,咱们不要源代码,只须要编译后的文件!有两种方式能够实现:json
.npmignore
文件,在其中添加不要的文件(夹)。src
tsconfig.json
tslint.json
.prettierrc
复制代码
可是,这并非一个好的实践,由于根目录下每次新增长一个文件(夹)都须要添加到 .npmignore
中,因而有了下面这种方式。package.json
中设置一个要发布的文件(夹)白名单"files": ["lib/**/*"]
复制代码
就是这么的简单!只有 lib 文件夹会出如今发布的包里(README.md 和 package.json 会被默认添加)。更多关于黑名单 VS 白名单的内容能够参考 blog.npmjs.org/post/165769…一个好的包应该要包括单元测试。接下来,咱们添加 Jest —— Facebook 开发的一个很是棒的测试框架。
jest
还须要 ts-jest @types/jest
,它们只是在开发阶段须要,因此添加到 devDependencies。npm i -D jest ts-jest @types/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
复制代码
一个好的包应该尽量自动化。接下来,咱们来看看 NPM 中其余的 scripts:prepare,prepublishOnly,perversion,version,postversion
。
npm install
(不带任何参数)时运行。"prepare": "npm run build"
复制代码
prepare
script 以前运行,而且仅在 npm publish
运行。在这里,咱们能够运行 npm run test & npm run lint
以确保咱们不会发布错误的不规范的代码。"prepublishOnly": "npm run test && npm run lint"
复制代码
npm run lint
。"preversion": "npm run lint"
复制代码
version
script 在 git commit
以前运行,因此还能够在此添加 git add
。"version": "npm run format && git add -A src"
复制代码
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"
}
复制代码
{
"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 add -A && git commit -m "Setup Package"
git push
复制代码
在发布以前,若是你没有 NPM 帐号的话,必须先注册一个。你能够在 www.npmjs.com/signup 上注册或者经过运行 npm adduser
注册。若是你已经有帐号了,运行 npm login
登录你的 NPM 帐号。
好了!如今你能够发布了。
npm publish
复制代码
能够看到,先运行 prepare
script,在其中运行了 npm run build
,而后运行 prepublishOnly
script,在其中运行了 npm run test && npm run lint
。
如今,你能够去 NPM 上查看你刚刚发布的包。URL 是 https://npmjs.com/package/<your-package-name>
,我发布的包就是 npmjs.com/package/ire…
执行以下命令会建立一个新版本, preversion,version,postversion
scripts 会被执行:建立一个新的 tag 而且推送到咱们的远程仓库。
npm version patch
复制代码
咱们再发布一次:
npm publish
复制代码
如今,咱们的包就有了一个 1.0.1 的版本:
[译文]一步步构建发布一个 TypeScript NPM 包