原文: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__/*"]
}
複製代碼
下面解釋下配置文件字段:注意 ES6 = ES2015
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"
複製代碼
在控制檯運行 npm run build,你會看到生成了一個新的 lib 文件夾,裏面是編譯後的 js 代碼和聲明文件。
除了 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 formatnpm 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 包