聊一聊工作中如何优雅的通过TDD方式来维护一个高质量的NPM包
背景
最近一直在采用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登录)
添加仓库:
现在我们在本地运行下
npm run semantic-release-prepare
如果你是widows系统,你当前可能需要运行
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 的工具
关于它正确姿势,可以参考阮老师这篇文章:(阮老师的文章很好,但不能全信^_^)
Commit message 和 Change log 编写指南
大家根据需要改一下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或者其它操作,自由度更大)
这里推荐两篇参考文章:
我为什么推荐Prettier来统一代码风格
用 husky 和 lint-staged 构建超溜的代码检查工作流
相关文章很多,大家自行翻看和过滤。
总结
先上张图:
项目链接
step-by-step-tdd,如果有帮助到大家,那就点个Star^_^。
项目的typedoc
项目npm地址
聊一聊工作中如何优雅的通过TDD方式来维护一个高质量的NPM包相关推荐
- spire.pdf转图片质量_工作了3年,我只服这5个高质量的办公网站,送给正在加班的你...
在职场中,想要提升自己的工作效率,除了学习各种与办公相关的知识以外,还需要几个办公网站协助自己一起完成,提高效率的同时还能加快完成每日的工作量,工作了5年,我只服这5个高质量的办公网站,送给正在奋斗的 ...
- 记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑
我通过这篇文章把今天工作中遇到的HTTP跨域和OPTION请求的一个坑记录下来. 场景是我需要在部署在域名a的Web应用里用JavaScript去消费一个部署在域名b的服务器上的服务.域名b上的服务也 ...
- 服务总线yali测试_中国信登加快技术测试体系建设支撑系统高质量运行
↑ 点击上方蓝字关注我们 为支撑中国信登信息系统高质量运行,提升服务我国信托行业综合能力,中国信登加快技术测试体系建设,从信息系统建设的事前.事中和事后入手,在信息系统的功能测试.非功能测试及软件全生 ...
- videojs中文文档详解_你的项目需要一个高质量README文档!
来源丨续渊 juejin.im/post/5cdd09556fb9a0323968b033 先叨叨几句 无论在公司内部,还是在开源社区,我们在接触一个新项目的时候,基本上都会先去看README.一 ...
- FPGA找工作写简历,你离高薪offer只差一个高端项目,提供工程源码和技术支持
这里写目录标题 1.前言 2.你或许很菜 3.工程源码 4.技术支持 5.工程源码和技术支持获取方式 1.前言 如果你是即将毕业的学生或是想转行做FPGA的工程师,你都会面临一个问题,那就是找工作,找 ...
- 奉劝那些刚参加工作的学弟学妹们:这20个高质量的学习网站越早知道越好(建议收藏)!!
这些学习网站越早知道越好,建议收藏,悄悄努力,然后惊艳所有人!! 大家好,我是冰河~~ 今年的五一假期总共五天,比往年假期略微长点.其实,抓住这个假期,好好巩固下自己欠缺的某个知识点,提升下自己的技能 ...
- 外业精灵,在水土流失监测野外调查工作中的应用
常规的水土流失野外调查技术已难以满足现阶段区域水土流失监测工作的需求. 为探索高效.精准.高质量的水土流失数据采集技术,作者以山东沂蒙山泰山国家级重点治理区蒙阴县为例,以小流域或公里网格为调查单元,通 ...
- 【设计模式】谈谈我们工作中的23个设计模式
ID 标题 地址 1 设计模式面试题(总结最全面的面试题) https://writer.blog.csdn.net/article/details/127910080 2 Java基础知识面试题(总 ...
- 30+ 个工作中常用到的前端小知识
1. JS为什么单线程 一个简单的原因就是,js在设计之初只是进行一些简单的表单校验,这完全不需要多线程,单线程完全可以胜任这项工作.即便后来前端发展迅速,承载的能力越来越多,也没有发展到非多线程不可 ...
最新文章
- python关系运算符中表示不等于的关系运算符_Python学习之------运算符表达式(关系运算符,逻辑运算符,三元表达式,成员关系)...
- php 第三方DB库NOTORM
- js 闭包的用法详解
- 20179214 2017-2018 2《网络攻防实践》第七周学习总结
- 应用程序的并行配置不正确_阿里架构师:天天高并发,达不到百万以上并发都不叫高并发...
- 科研工作者的神器-zotero论文管理工具
- 定时任务的实现原理,看完就能手撸一个!
- C#综合揭秘——深入分析委托与事件(上)
- 数据库原理—数据库基础(二)
- git-osc自己定义控件之:CircleImageView
- 【渝粤教育】国家开放大学2018年春季 0550-21T素描(一) 参考试题
- java square类_java – 处理大类
- SVD 详解 与 spark实战
- 深信服桌面云取消聚合口后的影响
- 如何举报YouTube视频和评论
- google 浏览器同步
- 关于VMware虚拟机萌新使用教程
- TensorRT加速应用
- 铃铛子训练营 | 我的感悟(二)
- Mac中python程序打包成mac-App应用程序
热门文章
- 【pytorch】拟合sin函数
- android+布局分块,android的List View的Item布局问题
- linux监测cpu 内存,Linux中CPU与内存性能监测.docx
- c#加粗代码_RichTextBox,怎么用c#代码根据Index和Length指定的范围的内容进行变色或加粗处理?...
- Spring-JDBC表情符号不能存入数据库
- linux基础知识_压缩—进程管理-网络管理-ftp-nfs-ssh-scp
- java 分析jstack日志_望闻问切使用jstack和jmap剖析java进程各种疑难杂症
- RabbitMQ(八):SpringBoot 整合 RabbitMQ(三种消息确认机制以及消费端限流)
- Springboot swagger2教程
- 在vscode中统一vue编码风格的方法