运用 TypeScript 编写一个完美包括测试、文档和延续集成的库

这篇文章主假如报告怎样运用 TypeScript 编写一个完美,包含测试、文档、延续集成的库,涵盖了编写全部库所需要的手艺和东西,重要涵盖:

  1. 项目目次骨架
  2. TypeScript 设置
  3. 运用 jest 单元测试
  4. 运用 vuepress 编写文档
  5. 运用 github pages 布置文档
  6. 延续集成布置

原文首发于我的个人网站:据说 – 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 的,那末 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/node

tsconfig.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
    // 制止 /// <reference path=>,直接用 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-jest

ts-jestjest 的 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 即可看到单元测试效果。

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

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.ts

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

vscode 基于 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", // 进口文件
      ]
    }
  ]
}

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

文档

文档方面,大略一点的,可以直接运用 README,也可以用 gitbook。不过我个人轻易比较引荐 vuepress

长途托管文档方面,要么自建效劳器,要么直接托管到 Github 的 Pages。

运用 vuepress 编写文档

个人比较倾向于运用 vuepress 编写文档,是由于内里扩大 Markdown 扩大了很多雄厚有用的语法,以及菜单构造的壮大可设置。

这里我们议论的是在项目中集成文档。

  1. 在项目根目次新建目次 /docs
  2. npm i --save-dev vuepress
  3. 在项目标 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 启动的效劳地点:

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

接见地点,即可看到文档页面:

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

运用 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

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

在 Github Pages 设置项挑选 docs/ 文件夹:

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

然后接见 https://<USERNAME or GROUP>.gitlab.io/<REPO>/ 即可看到自动布置的文档。比方:https://linkfly6.github.io/ts-lib-basic/

运用延续集成效劳 travis-ci

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/ 举行注册或登录。新增接入的项目:

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

挑选要翻开延续集成的项目:

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

然后我们更新文档或代码,提交代码到 Github。

稍等也许几十秒,就可以在 travis-ci 内里看到本身的单元测试使命:

《运用 TypeScript 编写一个完美包括测试、文档和延续集成的库》

末了,在测试终了的情况下,在 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/,引荐在我的网站浏览更多手艺文章。

    原文作者:linkFly
    原文地址: https://segmentfault.com/a/1190000017745050
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞