本文首发自慕课网,想了解更多IT干货内容,程序员圈内热闻,欢迎关注! 作者慕课网精英讲师黄轶 前言 前端这些年发展非常迅速,社区里涌现了一堆优秀的轮子,比如Vue、React、Angular、jQuery、axios等,它们解决着不同领域下的问题。使用这些轮子能极大地帮助我们提升生产力,有些人甚至基于这些轮子二次开发了一些轮子,比如elementui、antdesign等组件库。我们在享受这些轮子给我们带来的便利的时候,有时候也需要面临一些问题:某些轮子不能满足我们自己的特殊业务需求,找不到合适的轮子等。因此我们不仅要会使用轮子,也需要有造轮子的能力。 前端技术发展越来越迅速,其中TypeScript更是受到了越来越多的开发者的青睐,在GitHub上搜索star数大于1w的项目,我们可以看到很多知名的开源项目如vscode、angular、antdesign、ionic、deno等都使用TypeScript开发,其中上升最快的Vue。js3。0也正在用TypeScript重构,尤老师都忍不住发出了真香的言论。 TypeScript的火爆程度大有成为下一代前端开发语言的趋势,TypeScript作为JavaScript语言的超集,它为JavaScript添加了可选择的类型标注,大大增强了代码的可读性和可维护性。同时,它提供最新和不断发展的JavaScript特性,能让我们建立更健壮的组件。 越来越多的轮子将用TypeScript开发和重构,我们如果想造轮子,也应该使用TypeScript这把利器。 如何开始 我们造轮子首先会初始化一个项目,但需要配置一大堆东西,比如package。json、。editorconfig、。gitignore等,还包括一些构建工具如rollup、webpack以及它们的配置。 当我们使用TypeScript去写一个项目的时候,还需要配置TypeScript的编译配置文件tsconfig。json以及tslint。json文件。 这些茫茫多的配置往往会让一个想从零开始写项目的同学望而却步,如果有一个脚手架工具帮我们生成好这些初始化文件该多好。好在确实有这样的工具,接下来我们的主角TypeScriptlibrarystarter隆重登场。TypeScriptlibrarystarter 它是一个开源的TypeScript开发基础库的脚手架工具,可以帮助我们快速初始化一个TypeScript项目,我们可以去它的官网地址学习和使用它。使用方式gitclonehttps:github。comalexjovermtypescriptlibrarystarter。gittsaxioscdtsaxiosnpminstall 先通过gitclone把项目代码拉下来到我们的tsaxios目录,然后运行npminstall安装依赖,并且给项目命名,我们仍然使用tsaxios。 安装好依赖后,我们先来预览一下这个项目的目录结构。目录文件介绍 TypeScriptlibrarystarter生成的目录结构如下:CONTRIBUTING。mdLICENSEREADME。mdcodeofconduct。mdnodemodulespackagelock。jsonpackage。jsonrollup。config。tsrollup配置文件src源码目录test测试目录tools发布到GitHuppages以及发布到npm的一些配置脚本工具tsconfig。jsonTypeScript编译配置文件tslint。jsonTypeScriptlint文件优秀工具集成 使用TypeScriptlibrarystarter创建的项目集成了很多优秀的开源工具:使用RollupJS帮助我们打包。使用Prettier和TSLint帮助我们格式化代码以及保证代码风格一致性。使用TypeDoc帮助我们自动生成文档并部署到GitHubpages。使用Jest帮助我们做单元测试。使用Commitizen帮助我们生成规范化的提交注释。使用Semanticrelease帮助我们管理版本和发布。使用husky帮助我们更简单地使用githooks。使用Conventionalchangelog帮助我们通过代码提交信息自动生成changelog。 这里我们列举了很多工具,感兴趣的同学们可以点开他们的链接对这些工具做进一步学习。 工欲善其事必先利其器,我们现在已经搭好了一个项目的雏形,接下来就要开始编写轮子的代码了。 轮子的设计 一般轮子的特点,专注于做某一块事情,为了更直观和具体,我们以一个非常知名的前端开源库axios为例,站在轮子制造者的角度上,来讨论一下一个优秀的轮子是如何设计出来的。核心功能 axios核心专注于发送http请求,并且在此基础了扩展了很多实用和好用的feature,如下:在浏览器端使用XMLHttpRequest对象通讯在Node。js端使用httprequest通讯支持PromiseAPI支持请求和响应的拦截器支持请求数据和响应数据的转换支持请求的取消JSON数据的自动转换客户端防止XSRF 对于轮子的使用者,这些feature能让我们知道轮子是做什么的,而对于轮子的制造者,这些feature就是我们的需求。对于这些需求,我们可以划分一下优先级:优先实现在浏览器端的请求发送逻辑,实现一些基础功能如请求发送和响应,PromiseAPI,请求数据和响应数据的转换,JSON数据自动转换以及一些异常情况处理;接着再去扩展拦截器、配置化、请求取消等复杂功能,然后扩展一些简单的功能如客户端防止XSRF、上传等;最后开发axios在Node。js端的扩展。 我们的编码的思路也就是按优先级的重要程度依次去开发上述功能。接口设计 一个轮子是否优秀,首先取决于它是否好用,使用是否方便,五六年前,还是jQuery的时代,jQuery就提供了一个非常好用的设计,抢占了大部分市场。当年百度也出了一个类似的库叫tangram,创建一个DOM对象需要写Baidu。T。createDOM(xxx),而jQuery只需要(xxx)即可,高下立判。 axios设计也是非常简单,直接axios(config)就可以完成一个请求的发送了,为了减少config中的配置参数,还提供了axios。get、axios。post等接口。为了方便用户拿到响应结果,axios支持了PromiseAPI,我们可以通过axios(config)。then(res{})的方式拿到响应对象。 axios可以支持非常多的feature,完全得益于config配置参数,对于feature的扩展,我们既可以通过扩展axios的实例或者静态方法来实现,也可以扩展config的字段来实现,原则是怎么方便用户使用怎么来。生命周期 axios本质上就是发送一个请求,拿到响应结果,中途可以去对配置参数、请求数据和响应数据处理,同时也支持一些拦截器的调用,因此我们可以画出它的生命周期图示。 通过生命周期图示我们可以清晰地了解一个axios工作流程。轮子开发 综上所述,axios既是一个函数,又是一个接口,即是一个实例对象,也拥有一些静态方法,如果我们使用TypeScript开发,该如何设计axios的类型?另外,axios对外提供的非常多的API接口、配置参数,我们又该如何使用TypeScript定义这些类型呢?根据生命周期图示,我们可以按流程中的行为去拆分功能模块,我们如何使用TypeScript做模块拆分和管理的,哪些模块又可以被抽成基础公共模块呢?在实现整个axios库的过程中,如何不断做代码的优化、抽象和封装?如何使用策略模式实现配置合并?拦截器的Promise链如何设计?如何通过异步分离实现取消功能?单元测试 一个优秀的轮子,一定会有单元测试,单元测试是轮子的质量保证,甚至还有测试驱动开发的开发模式。很多同学对单元测试一直处于一种听说过,但没用过的状态。其实写单元测试并不难,首先我们要保证所有工具方法、辅助函数的测试完整性;然后要保证feature的测试完整性,保证每一个feature的各种情况都能测到。一个检测测试完整性的常用手段是看测试的覆盖率,通常我们会要求测试覆盖率达到90以上。 单元测试有一个非常大的好处是你可以放心地对你现有的代码做新feature的开发,以及代码的重构,而不用担心代码的改动影响已有功能,我们可以很容易地通过跑单元测试检测我们改动的代码是否有问题。 目前前端测试的框架有很多,我比较推荐Jest,它是一个几乎零配置的测试框架,非常易于上手,由facebook团队维护,质量也能得到保证。新课程就是使用Jest来编写axios的单元测试,你会学到很多编写单元测试的方法和技巧,对单元测试感兴趣的同学可以来学习咯。 总结 TypeScript在类型方面的约束,以及提供很多好用的现代JavaScript语法特性,非常适合用它去造一个轮子,当然也非常适合开发大型复杂前端项目。前端的趋势会越来越复杂,TypeScript这个技术栈在未来一定会变成前端必须掌握的开发技能。 至于造轮子,能不能设计好用的轮子,轮子能不能满足复杂的需求,对你的JavaScript内功、代码设计能力都是有很高的要求,造轮子的过程就是一个内功修炼的过程。所以,如果你不满足于做一个熟练工,一个螺丝钉,想提升自己的核心竞争力,那么从今天开始,拿起TypeScript做一个轮子的制造者。 欢迎关注慕课网,发现更多IT圈优质内容,分享干货知识,帮助你成为更好的程序员!