当咱们在开发维护一些工具类项目的时候,随着功能的丰富以及维护人员的变动,会致使代码的可持续维护性降低,所以须要一些其余工具来帮咱们提升代码质量,减小一些没必要要的错误。本篇咱们来介绍使用TS来作一些事情。html
TypeScript 是微软开发一款开源的编程语言,本质上是向 JavaScript 增长静态类型系统。它是 JavaScript 的超集,全部现有的 JavaScript 均可以不加改变就在其中使用。它是为大型软件开发而设计的,它最终编译产生 JavaScript,因此能够运行在浏览器、Node.js 等等的运行时环境。前端
首先TS的定位是静态类型语言,而不是类型检查器(对比flow)。 从开发工具提供的能力看也不只仅是类型检查,很直观的就是Intellisense over Compilation Error,当一段代码有问题(好比少写了字母)时,写完立刻就会有红色波浪线提示,而不是等到编译的时候才告诉你哪一行有问题。 所以使用TS提供的类型系统+静态分析检查+智能感知/提示,使大规模的应用代码质量更高,运行时bug更少,更方便维护。vue
虽然须要多写一些类型定义代码,但TS在WebStorm等IDE下能够作到智能提示,智能感知bug,同时咱们项目经常使用的一些第三方类库框架都有TS类型声明(@types管理),咱们也能够给那些没有TS类型声明的稳定模块写声明文件,这在团队协做项目中能够提高总体的开发效率。node
长期迭代维护的项目开发和维护的成员会有不少,人员的不稳定性和团队成员水平的差别的差别性,以及软件自己具备熵的特质,致使长期迭代维护的项目总会遇到可维护性逐渐下降的问题。而有了强类型约束和静态检查,以及智能IDE的帮助下,能够下降软件腐化的速度,提高可维护性。而且若是在重构代码时,强类型和静态类型检查会帮上大忙,必定程度上减小重构代价。(你们开发维护起来更安全、放心)。webpack
咱们如今的工具类项目不少bug都是因为一些调用方和被调用方的数据格式不匹配引发的。TS能够在编译期进行静态检查,能够在编写调试代码时就发现这些问题,而且IDE能够智能纠错,编码时就能提早感知bug的存在,咱们的线上运行时质量会更为稳定可控。git
flow用来作类型检查,好比vue就是用的flow,可是flow也有不少问题:es6
好比 Incompatible instantiation for T, T 是一个类型变量,可是你并不能迅速找到这个错误在哪里。github
运行 Flow是须要必定成本的。对于Mac 用户来讲很是幸运,经过 homebrew 能够安装预制的二进制包。但若是你须要本身编译它,你就先得创建一套 OCaml 开发环境。web
babel相比于tsc,首先定位是不一样的,babel是一种js预处理工具,理论上说彻底能够实现对ts的预处理,可是tsc对ts处理会更加精细。固然tsc 的功能没有 babel 多,扩展性也没有 babel 强。npm
咱们的开源脚手架builder-webpack4已经实践了几个月了,为了更好的维护,咱们决定迁移到ts。这中间踩了一些坑,但也积累了一些经验。
ts配置文件有不少配置项,可是对于咱们开发node工具来讲其实用到的并很少,咱们只须要关注模块化,编译路径和输出路径便可。 关于模块化,咱们但愿输出的是commonjs规范的,至于最终是es5/es6或是其余,因人而异,咱们须要配置的就是:
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es5",
"moduleResolution": "node"
}
复制代码
编译路径和输出路径,这里跟webpack相似,固然这里的编译路径是指定tsc编译哪些目录下的ts文件,不然编译会由于内容太多而报错。
"compilerOptions": {
"outDir": "lib" //输出路径
},
//编译目录
"include": [
"src/**/*"
],
复制代码
固然咱们还可能会指定types的路径
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
复制代码
对于多数的npm包来讲均可以经过安装@types/xxx来解决,好比node咱们就能够安装@types/node,固然也有一些@types并无作管理,那就须要咱们本身来写一下。举个例子,webpack处理html相关会用到一个插件“html-webpack-plugin”,它是做为一个模块来使用,那么只须要如下声明便可
declare module 'html-webpack-plugin';
复制代码
固然你可能会用到某些UMD的包(既能够当模块又能够做为全局变量使用):
declare namespace UMD{
//能够定义一些其余东西
}
复制代码
好比咱们有些方法须要修改一些参数,使用TypeScript 以后,把数据对应的 interface 改掉,而后从新编译一次,把编译失败的地方所有改掉就行了。 对于builder-webpack4来讲不少方法的参数都较为复杂,好比咱们生成构建配置文件的时候,webpack的配置老多了,天然是须要写个interface来控制,可是问题是若是别的模块调用这个方法又得重写一次?不用的,只要吧interface看成模块同样导出便可(固然你也能够把这些写到d.ts中,而后引入到对应的文件)。
export interface xxx{
[propName: string]: any
}
复制代码
当咱们开始盲写代码的时候,总会不可避免的有些小失误,那么利用IDE配合ts提供的工具就能够帮咱们提早发现一些问题;在编译调试中一样能够发现一些未触及的点。
咱们在调用方法的时候就知道这个方法须要哪些参数,固然若是类型写错了就立马会有红色波浪线标注出来(格外的扎眼)。
做为一种弱类型语言,js开发一些大型/持续维护项目的时候,常常会让人体验什么是“开发一时爽,重构火葬场”。
对于模块的导出
export default builderWebpack4;
复制代码
这个玩意编译出来实际上是这样子的
exports.default = builderWebpack4;
复制代码
可是对于别的调用方来讲并不能直接用,咱们想要的是
module.exports = builderWebpack4;
复制代码
因此源码中多加个指定就行了
module.exports = exports.default;
复制代码
固然对于项目内部间模块调用是不须要的,tsc构建会生成相关的hack
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var webpack_1 = __importDefault(require("webpack"));
复制代码
项目越大,越难以维护,所以对于多人写协做的大型项目有必要使用ts来提升代码质量。
对于一些长久运行的项目,既要保证它的稳定运行,又要保证项目交接便捷(可维护性),使用ts是目前来看最好选择。
使用nodejs/js写一些前端工具或者库的时候,一样是须要关注以上两点内容,并且工具类的项目影响范围较大,在开发维护中要更加谨慎,那么使用ts帮咱们尽可能减小一些低级错误是颇有必要的。
关注公众号:【IVWEB社区】,每周推送精品技术周刊 。