背景
最近一直在采用TDD(测试驱动开发)的方式来维护公司内部的一套通用业务逻辑。
既然是应用到公司实际项目中的,那就不能随随便便搭个脚手架来完成了。
调研过程中,发现TypeScript library starter和团队的技术堆栈契合的不错。
因为笔者现有团队中的小伙伴项目中均采用typescript,react(ie7运行时切换为qreact),redux,jest等)进行开发。(不坑队友,选starter还是要符合团队的技术堆栈)
这个Starter还是比较完善的,目前也一直处于迭代中。
为了保证我们的代码高质量和可维护,它使用了不少的工具。(当然我们可以根据团队需要,增删^_^)
至于它工具链中包含的RollupJS,Jest,Prettier,TSLint,TypeDoc,Travis, Coveralls,Semantic release,Commitizen,Conventional changelog,Husky等更多详细信息,大家可以去它们的github或者google去了解。
NPM Scripts
在这里,我们把重点放在NPM Scripts上面,看看这些个工具组成的开发工作流:
首先,我们按照README的步骤拉取并初始化项目:
git clone https://github.com/alexjoverm/typescript-library-starter.git step-by-step-tdd
cd step-by-step-tdd
npm install
(通过yarn安装也是可以的,淘宝源啥大家都知道哈)
NPM包安装完成后,会出现一个问答(主要是确认下你项目的名字,错了可以直接在项目中改):
世界正在改变,我们来检测并更新下包(一般情况下,升级包不会影响原有项目。):
现在,我们来一行一行看脚本:
lint
npm run lint
"lint": "tslint -t codeFrame 'src/**/*.ts' 'test/**/*.ts'"
不用多说,这是用来保证代码风格的,配套项目中一般会有tslint.json文件。(毕竟代码更多是给人看的)
-t codeFrame
(就是指定tslint错误输出风格,这里是codeFrame),官网是这么解释的:
build & prebuild
"prebuild": "rimraf dist"
(编译前删掉之前生成的dist文件夹。)
npm run build
(编译ts为各种js模块规范)
"build": "tsc --module commonjs --outDir dist/lib && rollup -c rollup.config.ts && typedoc --out dist/docs --target es6 --theme minimal --mode file src"
- 根据tsconfig.json采用tsc生成commonjs规范的模块
- 根据tsconfig.json采用rollup生成es规范和umd规范的模块
- 使用typedoc生成文档
Javscript Modules
关于Javascript模块的好文(有很多,大家可以自行google)
- 使用 AMD、CommonJS 及 ES Harmony 编写模块化的 JavaScript
- JavaScript 模块化入门Ⅰ:理解模块
- JavaScript 模块化入门Ⅱ:模块打包构建
- JavaScript Module Pattern
- JavaScript模块化编程简史
npm start
npm start
(rollup监控编译src目录下文件,开发阶段使用。不过我觉得开发的时候用npm run test:watch就够了)
"start": "rollup -c rollup.config.ts -w"
npm test
npm test
(单元测试)
"test": "jest"
npm run test:watch
(单元测试监控模式,基本上开发时用它就够了)
jest配置说明
针对这个starter所配的jest说明:
我们来解释下这些个选项:"transform"
:node不认识ts,所以需要编译后执行"testRegex"
:正则匹配要测试的文件"moduleFileExtensions"
:设置文件扩展名,配置后,(import|require)相关文件不需要加啥(.ts,.tsx,.js)后缀"coveragePathIgnorePatterns"
:忽略不需要收集代码覆盖率的文件夹中的文件"coverageThreshold"
:这个选项用来设代码覆盖率(code coverage)收集的最小执行阈值"global"
:标识符,全局设置(也可以针对路径,单个文件来设置)"branches"
:分支覆盖率(branch coverage):是否每个if代码块都执行了?"functions"
:函数覆盖率(function coverage):是否每个函数都调用了?"lines"
:行覆盖率(line coverage):是否每一行都执行了?"statements"
:是否每个语句都执行了?
"collectCoverage"
:此项配置指示是否收集测试时的覆盖率信息。"mapCoverage"
: 在这里ts编译器产生source map,Jest在输出覆盖率报告时, 将尝试使用它们来映射出源代码的代码覆盖率,并检查阈值。
npm test:prod
(检查代码风格,运行单元测试并生成代码覆盖率报告。)
"test:prod": "npm run lint && npm run test -- --coverage --no-cache"
实战TDD
第一步,我们来确定我们要解决的问题(我这里的是根据babel对Preact中JSX语法的转换,来写一个简单h函数)
我们打开这个链接,会看到如下代码:
大家如果看过Preact h函数的源码,大家就会发现它实质上返回的是一个VNode实例,它包含4个属性:
有了输入和输出,我们就可以撸起袖子上手干啦(gif):
根据测试用例断点调试源码
我们打开vscode官网所提供的项目-->>debugging-jest-tests,把它里面launch.json给拖过来(一行都不用改它的),如下:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Jest All",
"program": "${workspaceRoot}/node_modules/jest/bin/jest",
"args": ["--runInBand"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
},
{
"type": "node",
"request": "launch",
"name": "Jest Current File",
"program": "${workspaceRoot}/node_modules/jest/bin/jest",
"args": ["${file}"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
复制代码
注意这里的选择:
按F5执行断点调试的gif:
推送到github并自动发布
-
进入npm官网,注册一个账号(很简单,就不演示了)
-
进入Travis CI(持续集成,我司用的是gitlab CI),点击右上角的:
可以先同步下项目,点击: 找到你的项目(我这里是这个) -
进入coveralls(一个根据单元测试导出的数据进行分析,展现代码覆盖率的一个工具。这里,同样是使用github登录)
添加仓库: -
现在我们在本地运行下
如果你是widows系统,你当前可能需要运行npm run semantic-release-prepare
npm install --global --production windows-build-tools
编辑
package.json
中的repository.url
"author": "Kirk.Wang <kirk.w.wang@gmail.com>", "repository": { "type": "git", "url": "https://github.com/Kirk-Wang/step-by-step-tdd" //这里替换成你自己的就好了 } 复制代码
-
根据提示,我们运行:
npm install -g semantic-release-cli
semantic-release-cli setup
-
因为我这里创建的是一个空白项目,并没有git init:
-
首先,我执行下
git remote add origin git@github.com:Kirk-Wang/step-by-step-tdd.git
-
我根据自身需要编辑下.git/config这个件
-
然后检查下
gh-pages-publish.ts
(因为我们要自动发布我们的typedoc到githup pages上) -
我们看下Starter提供的
.travis.yml
,大家就清楚了,如下:language: node_js branches: only: - master - /^greenkeeper/.*$/ cache: yarn: true directories: - node_modules notifications: email: false node_js: - node script: - npm run test:prod && npm run build after_success: - npm run report-coverage - npm run deploy-docs - npm run semantic-release 复制代码
-
我们接着执行:
git add .
npm run commit
-->"commit": "git-cz"
(因为我们要执行一个工具命令,用来规范我们的commit-message)Commitizen,一个撰写合格 Commit message 的工具
关于它正确姿势,可以参考阮老师这篇文章:(阮老师的文章很好,但不能全信^_^)
-
大家根据需要改一下README.md
-
我们终于可以执行:
git push
step-by-step-tdd typedoc因为我这里有在github上绑定域名,所以这个项目的gh-pages会自动在这下面。
关于gh-pages,很简单,看下文档就会了。
Prettier & Husky & lint-staged
-
Prettier(统一代码风格神器)
-
Husky(Git Hooks 管理神器)
-
lint-staged(通常和Husky配合,提交前使用做Code Linting,Prettier或者其它操作,自由度更大)
-
这里推荐两篇参考文章:
用 husky 和 lint-staged 构建超溜的代码检查工作流
相关文章很多,大家自行翻看和过滤。
总结
先上张图:
项目链接
step-by-step-tdd,如果有帮助到大家,那就点个Star^_^。