摘要:單元測試一個合格的庫應該包含完整的單元測試。是的支持版,和是一樣的,它能夠直接運行為后綴的單元測試文件。在目錄下加入然后執行即可看到單元測試結果。
這篇文章主要是講述如何使用 TypeScript 編寫一個完善,包含測試、文檔、持續集成的庫,涵蓋了編寫整個庫所需要的技術和工具,主要涵蓋:
項目目錄骨架
TypeScript 配置
使用 jest 單元測試
使用 vuepress 編寫文檔
使用 github pages 部署文檔
持續集成部署
原文首發于我的個人網站:聽說 - https://tasaid.com/,推薦在我的網站閱讀更多技術文章。
前端開發 QQ 群:377786580
歡迎使用和了解滴滴金融出品的移動端組件庫 Mand-mobile。
為了迎合這篇文章,我編寫了一個可以開箱即用的庫模板:https://github.com/linkFly6/ts-lib-basic。
里面集成了這篇文章所闡述的所有內容。
初始化項目目錄先初始化項目目錄,一般來說,src 放源碼,dist 放編譯后的代碼,tests 放單元測試,所以先初始化好基礎目錄。
. ├── .vscode # vscode 配置 │ └── launch.json # vscode 調試配置 ├── dist # 編譯產出目錄,編譯后才有 ├── src # 源碼 ├── tests # 單元測試 ├── .gitignore # git 忽略文件 ├── .npmrc # npm 配置 ├── .travis.yml # github 持續集成 ├── LICENSE # 開源協議 ├── README.md # README ├── package-lock.json # npm 鎖定依賴 ├── package.json # npm ├── tsconfig.json # typescript 配置 └── tslint.json # tslint 校驗
先按照這個目錄文件結構,然后我們會一步步填上內容。
通過 npm init 初始化一個 npm 配置:
初始化 TypeScript 相關工具既然包是基于 TypeScript 的,那么 TypeScript 工具必不可少。
ts-node在開發中,可以使用 ts-node(可以理解為可以直接執行 ts 文件的 node)來直接運行我們的 ts 代碼。
npm i --save-dev typescript npm i --save-dev ts-node
如果是 node 應用,為了讓 TypeScript 能夠進行 node 類型推導,則需要安裝 Node 對應的類型聲明:
npm i --save-dev @types/nodetsconfig.json
tsconfig.json 是 TypeScript 的配置文件,這里提供一份可供參考是配置,置于項目根目錄:
{
"compilerOptions": {
"sourceMap": false,
"module": "commonjs", // 模塊配置
"noImplicitAny": true, // 是否默認禁用 any
// "removeComments": true, // 是否移除注釋
"types": [ // 默認引入的類型聲明
"node", // 默認引入 node 的類型聲明
],
"baseUrl": ".", // 工作根目錄
"paths": {
// ~/ 指向 server/types,types 目錄下都是 types 文件,所以不會編譯產出
"~/*": [
"./types/*"
]
},
"target": "es6", // 編譯目標
"outDir": "dist", // 輸出目錄
"declaration": true, // 是否自動創建類型聲明
},
// 此配置生效范圍
"include": [
"src/**/*"
],
}
tslint.json
tslint 類似 eslint,是 TypeScript 中的代碼風格約束工具。
關于 lint,個人方面比較傾向于非強制性的,所以只在 vscode 中安裝了擴展 tslint,這樣 vscode 會根據項目根目錄配置的 tslint.json 標出不符合規范的信息。
這里有一份推薦配置:
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {},
"rules": {
"max-line-length": [
true,
140
],
// 禁止內置原始類型
"ban-types": false,
// 禁止給參數賦值
"no-parameter-reassignment": false,
// 禁止空接口
"no-empty-interface": true,
// 顯示類型代碼就不需要再加類型聲明了
"no-inferrable-types": true,
// 不允許使用內部模塊
"no-internal-module": true,
// 不允許在變量賦值之外使用常量數值。如果未指定允許值的列表, 則默認情況下允許-1、0和1 => 亂七八糟的數字會讓人混淆
// "no-magic-numbers": [true],
// 不允許使用內部 "modules" 和 "namespace"
"no-namespace": true,
// 非空斷言,強制使用 == null 之類的斷言
// "no-non-null-assertion": true
// 禁止 /// ,直接用 import 即可
"no-reference": true,
// 禁止使用 require,應該使用 import foo = require("foo")
"no-var-requires": false,
// import 的順序按照字母表
"ordered-imports": false,
// 對象屬性聲明按照字母表
"object-literal-sort-keys": false,
// // 結束語句后的分號
"semicolon": [
false,
"always"
],
// 字符串強制單引號
"quotemark": [
true,
"single",
"jsx-double"
],
// 禁止 arguments.callee
"no-arg": true,
// if 語句的單行不用括號,多行用括號
"curly": false,
// 是否強制使用箭頭函數,禁止匿名函數
"only-arrow-functions": false,
// 是否禁止多個空行
"no-consecutive-blank-lines": false,
// 在函數括號前要求或不允許空格
"space-before-function-paren": false,
// 箭頭函數的參數使用括號
"arrow-parens": [
true,
"ban-single-arg-parens"
],
// 不固定變量類型
"no-shadowed-variable": false,
// 行尾多余的空格
"no-trailing-whitespace": false,
// == 和 ===
"triple-equals": false,
// 禁止一些位運算符
"no-bitwise": false,
// 禁止 console
"no-console": false,
// 檢查變量名
"variable-name": [
true,
"ban-keywords"
// "check-format",
// "allow-leading-underscore"
],
// 一行聲明變量表達式
"one-variable-per-declaration": false,
// 允許在一個文件里定義多個 class
"max-classes-per-file": [
true,
5
],
// 判斷表達式 fn && fn()
"no-unused-expression": [
true,
"allow-fast-null-checks"
],
// 空函數
"no-empty": false,
// forin 是否必須包含 hasOwnProperty 判斷
"forin": false,
"no-debugger": false,
// 強制要求必須要聲明類型
"typedef": [
true
]
},
"rulesDirectory": [
"./src"
]
}
package-lock.json
package-lock.json 是 npm 5 之后引入的,為了解決 npm 過去使用的 package.json 版本依賴太寬松的問題。
比如說 package.json 中依賴了包 mand-mobile,使用了最常用的插入依賴(^):
"mand-mobile": "^4.16.4",
假設自己項目在上線階段, mand-mobile 更新到了 mand-mobile@4.17.0,而剛好 mand-mobile@4.17.0 又不小心出現了一個新 bug 會導致頁面腳本錯誤。這時候上線安裝依賴的時候,由于 package.json 和 ^ 約束太寬松,就會導致 mand-mobile@4.17.0 被安裝,從而導致上線出問題。
package-lock.json 就是為了解決這個問題,通過 npm 安裝包的時候,會檢測本地是否有 package-lock.json。
如果沒有 package-lock.json,就在安裝包的時候將當前包依賴的詳細信息(包括子級依賴)都寫入生成 package-lock.json。
如果有 package-lock.json,則根據 package.json,參考 pacakge-lock.json 來安裝包依賴。來保證依賴穩定。
本質上 ppackage-lock.json 的作用類似于 node_modules 包依賴的快照。
單元測試一個合格的庫應該包含完整的單元測試。這里我們使用 jest 對應的 TypeScript 版本:ts-jest。
ts-jestts-jest 是 jest 的 TypeScript 支持版,API 和 jest 是一樣的,它能夠直接運行 .ts 為后綴的單元測試文件。
安裝 ts-jest 和對應的類型聲明文件:
npm i --save-dev jest #ts-jest 依賴 jest npm i --save-dev ts-jest npm i --save-dev @types/jest
在 package.json 中加入 jest 配置和 npm run test 的腳本:
{
"name": "my-app",
"main": "dist/index.js",
"scripts": {
"test": "jest --verbose"
},
"jest": {
"rootDir": "tests",
"transform": {
"^.+.tsx?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|(.|/)(test|spec)).tsx?$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
}
}
這時候就可以基于 jest 編寫單元測試了。在 tests/ 目錄下加入 example.test.ts:
import { isArrayLike } from "../src"
describe("my-app:isArrayLike", () => {
test("isArrayLike(): true", () => {
expect(
isArrayLike([]),
).toBe(true)
})
test("isArrayLike(): false", () => {
expect(
isArrayLike({}),
).toBe(false)
})
})
然后執行 npm run test 即可看到單元測試結果。
express 測試如果要測試 express/koa 之類的 web 應用框架程序,則可以使用 tj 大神的 supertest。
安裝對應的包:
npm i --save-dev supertest npm i --save-dev @types/supertest
import * as express from "express"
/**
* 用于測試 express、koa 等 web 應用框架的工具
*/
import * as request from "supertest"
import middleware from "../src"
describe("my-app:basic", () => {
test("locals", done => {
const app = express()
app.use(middleware)
app.get("/example", (req, res) => {
res.send({ code: 0 })
})
// 使用 supertest 進行測試
request(app).get("/example").expect(200, { code: 0 }, done)
})
})
debug
debug 也是 tj 大神編寫的一個庫,用于在應用程序中輸出 debug 信息,用于調試工具庫,著名的庫大部分都采用該庫進行 debug 支持。
npm i --save debug npm i --save-dev @types/debug
import * as d from "debug"
const debug = d(`my-app:basic`)
debug("debug info")
在啟動應用程序的時候,只需要在環境變量中注入 DEBUG 即可:
DEBUG=my-app* node app.js DEBUG=my-app* ts-node app.tsvscode 基于 ts-node 調試
在 .vscode/launch.json 中可以配置基于 ts-node 的調試:
{
// 使用 IntelliSense 了解相關屬性。
// 懸停以查看現有屬性的描述。
// 欲了解更多信息,請訪問: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "啟動程序",
// 基于 ts-node 調試
"program": "${workspaceFolder}/node_modules/ts-node/dist/bin.js",
"args": [
"-P",
"${workspaceRoot}/tests/tsconfig.json",
"${workspaceRoot}/tests/app.ts", // 入口文件
]
}
]
}
文檔
文檔方面,簡陋一點的,可以直接使用 README,也可以用 gitbook。不過我個人方便比較推薦 vuepress。
遠程托管文檔方面,要么自建服務器,要么直接托管到 Github 的 Pages。
使用 vuepress 編寫文檔個人比較傾向于使用 vuepress 編寫文檔,是因為里面擴展 Markdown 擴展了許多豐富實用的語法,以及菜單結構的強大可配置。
這里我們討論的是在項目中集成文檔。
在項目根目錄新建目錄 /docs
npm i --save-dev vuepress
在項目的 package.json 中加入腳本
"scripts": {
"docs": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
在 /docs 新增文件 README.md,寫入以下內容:
--- home: true actionText: 開始使用 → actionLink: /readme footer: MIT Licensed | Copyright ? 2018-present linkFly features: - title: 快速 details: 快速創建庫 - title: 集成 details: 集成單元測試和自動化 doc 部署 - title: TypeScript details: TypeScript 支持 --- 集成了基礎工具的,使用 TypeScript 快速編寫一個應用庫
然后執行結合我們剛才配置的命令,執行 npm run docs,終端 shell 會輸出 vuepress 啟動的服務地址:
訪問地址,即可看到文檔頁面:
使用 github pages 托管文檔github pages 是 Github 提供的一個免費的頁面托管服務,我們可以將 vuexpress 編譯出來的文檔托管到上面。
Github Pages 服務和 Github 已經打通,可以從項目的 /docs 目錄自動部署,這也就是我們為什么要在項目里新建 /docs 目錄的原因。
首先,我們將項目中 pageage.json 的腳本進行更新:
"scripts": {
"docs:build": "vuepress build docs && cp -rf ./docs/.vuepress/dist/* ./docs && rm -r ./docs/.vuepress/dist"
}
這段腳本的大體意思就是先使用 vuepress 構建產出文檔的 HTML 文件(在 /docs/.vuepress/dist 目錄下),然后將 dist 目錄移動到 docs/ 目錄下,因為 Github Pages 在識別 docs/ 的時候只能識別 docs/index.html。
執行 npm run docs:build。
將本地的項目 push 到 Github 以后,打開該項目的 Setting:
在 Github Pages 配置項選擇 docs/ 文件夾:
然后訪問 https://
travis-ci 是一個持續集成服務,它可以用來自動部署和構建 Github 上的項目。
我們可以集成我們的單元測試。
在項目根目錄加入 .travis.yml,在 master 分支進行提交的時候自動運行 npm run test 命令(npm run test 命令配置參見 ts-jest 章節):
sudo: false language: node_js node_js: - "8" cache: directories: - node_modules branches: only: - master script: npm run test
打開 https://travis-ci.org/ 進行注冊或登錄。新增接入的項目:
選擇要打開持續集成的項目:
然后我們更新文檔或代碼,提交代碼到 Github。
稍等大概幾十秒,就可以在 travis-ci 里面看到自己的單元測試任務:
最后,在測試完畢的情況下,在 https://www.npmjs.com/ 進行注冊。
在 npm 的源是官方的(npm config set registry https://registry.npmjs.org/)情況下,執行 npm login 登錄 npm 以后,npm publish 發布包即可。
最后,為了迎合這篇文章,我編寫了一個可以開箱即用的庫模板:https://github.com/linkFly6/ts-lib-basic。
里面集成了這篇文章所闡述的所有內容。
前端開發 QQ 群:377786580
歡迎使用和了解金融出品的移動端組件庫 Mand-mobile。
原文首發于我的個人網站:聽說 - https://tasaid.com/,推薦在我的網站閱讀更多技術文章。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://www.hztianpu.com/yun/100649.html
摘要:弄了一個持續更新的筆記,可以去看看,鏈接地址此篇文章的地址使用兩年后值得嗎基礎筆記的地址可以也可以。使用,你可以使用抽象類等功能。有關抽象類的更多信息支持,和方法,只讀屬性。 弄了一個持續更新的github筆記,可以去看看,鏈接地址:Front-End-Basics 此篇文章的地址:使用TypeScript兩年后-值得嗎? 基礎筆記的github地址:https://githu...
摘要:框架是和應用程序的另一個測試和規范框架。它是為應用程序編寫自動測試的最有用的庫之一。數據庫是許多應用程序包括核心和應用程序不可分割的一部分,可能是進行單元測試時的最大障礙。 作為一名Java開發人員,我們從事不同的領域,從編寫核心Java代碼到創建JSP頁面、編寫RESTAPI,有時甚至創建Groovy腳本以實現構建自動化...
摘要:在,我們剛剛使用發布了我們的客戶端的新版本。得到了最多的提及,排在第二位。根據,這個許可證旨在保護他們免受專利巨魔的侵害。正在獲得更多開發者的支持,我們在開發過程中看到了這一點,讓我們更加相信,我們的選擇是對的。 showImg(https://segmentfault.com/img/bVbdxdq?w=1960&h=960);在Rever(www.reverscore.com),我...
閱讀 1757·2023-04-25 17:41
閱讀 3231·2021-11-22 15:08
閱讀 1039·2021-09-29 09:35
閱讀 1789·2021-09-27 13:35
閱讀 3564·2021-08-31 09:44
閱讀 2883·2019-08-30 13:20
閱讀 2154·2019-08-30 13:00
閱讀 2766·2019-08-26 12:12