运用 TypeScript 革新构建东西及测试用例

近来的一段时间一向在搞TypeScript,一个巨硬出品、给予JavaScript言语静态范例和编译的言语。
第一个完全运用TypeScript重构的纯Node.js项目已上线并稳固运转了。
第二个前后端的项目现在也在重构中,关于前端基于webpackTypeScript套路之前也有提到过:TypeScript在react项目中的实践

然则这些做完今后也总觉得缺了点儿什么 _(没有纵情)_:

《运用 TypeScript 革新构建东西及测试用例》
是的,依旧有五分之一的JavaScript代码存在于项目中,作为一个TypeScript的示例项目,表现的很不地道。
所以有没有可以将这些JavaScript代码也换成TypeScript呢?
答案肯定是有的,起首须要剖析这些代码都是什么:

  • Webpack打包时的设置文件
  • 一些简朴的测试用例(运用的mocha和chai)

知道了是哪些地方还在运用JavaScript,这件事儿就变得很优点理了,从构建东西(Webpack)最先,逐一击破,将这些悉数替换为TypeScript

Webpack 的 TypeScript 完成版本

在这8102年,很幸运,Webpack官方已支撑了TypeScript编写设置文件,文档地点
除了TypeScript之外还支撑JSXCoffeeScript的诠释器,在这就疏忽它们的存在了

依靠的装置

起首是要装置TypeScript相干的一套种种依靠,包含诠释器及该言语的中心模块:

npm install -D typescript ts-node

typescript为这个言语的中心模块,ts-node用于直接实行.ts文件,而不须要像tsc那样会编译输出.js文件。

ts-node helloworld.ts

由于要在TypeScript环境下运用Webpack相干的东东,所以要装置对应的types
也就是Webpack所对应的那些*.d.ts,用来通知TypeScript这是个什么对象,供应什么要领。

npm i -D @types/webpack

一些经常使用的pLugin都邑有对应的@types文件,可以简朴的经由历程npm info @types/XXX来搜检是不是存在

假如是一些小众的plugin,则可以须要本身建立对应的d.ts文件,比方我们一向在用的qiniu-webpack-plugin,这个就没有对应的@types包的,所以就本身建立一个空文件来通知TypeScript这是个啥:

declare module 'qiniu-webpack-plugin' // 就一个简朴的定义即可

// 假如另有其他的包,直接放到同一个文件就好了
// 文件名也没有要求,保证是 d.ts 末端即可

安排的位置没有什么限定,随意丢,平常发起放到types文件夹下

末了就是.ts文件在实行时的一些设置文件设置。
用来实行Webpack.ts文件对tsconfig.json有一些小小的要求。
compilerOptions下的target选项必需是es5,这个代表着输出的花样。
以及module要求挑选commonjs

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "esModuleInterop": true
  }
}

但平常来说,实行Webpack的同级目次都已存在了tsconfig.json,用于现实的前端代码编译,极可以两个设置文件的参数并不一样。
假如由于要运用Webpack去修正真正的代码设置参数肯定是不可取的。
所以我们就会用到这么一个包,用来转变ts-node实行时所依靠的设置文件:tsconfig-paths

Readme中发明了如许的说法:If process.env.TS_NODE_PROJECT is set it will be used to resolved tsconfig.json
Webpack的文档中一样也提到了这句,所以这是一个兼容的要领,在敕令运转时指定一个途径,在不影响原有设置的情况下建立一个供Webpack打包时运用的设置。

  1. 将上述的设置文件改名为别的称号,Webpack文档示例中为tsconfig-for-webpack-config.json,这里就直接沿用了
  2. 然后增加npm script以下
{
  "scripts": {
    "build": "TS_NODE_PROJECT=tsconfig-for-webpack-config.json webpack --config configs.ts"
  }
}

文件的编写

关于设置文件,从JavaScript切换到TypeScript现实上并不会有太大的修改,由于Webpack的设置文件大多都是写死的文本/常量。
许多范例都是自动天生的,基础可以不必手动指定,一个简朴的示例:

import { Configuration } from 'webpack'

const config: Configuration = {
  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
}

export default config

Configuration是一个Webpack定义的接口(interface),用来范例一个对象的行动。
VS Code下按住Command + 单击可以直接跳转到细致的webpack.d.ts定义文件那边,可以看到细致的定义信息。
《运用 TypeScript 革新构建东西及测试用例》
种种经常使用的划定规矩都写在了这里,运用TypeScript的一个优点就是,当要完成一个功用时你不再须要去网站上查询应该要设置什么,可以直接翻看d.ts的定义。
假如解释写得充足圆满,基础可以当做文档来用了,而且在VS Code编辑器中另有动态的提醒,以及一些毛病的改正,比方上述的NODE_ENV的猎取,假如直接写process.env.NODE_ENV || 'development'是会抛出一个非常的,由于从d.ts中可以看到,关于mode只要三个有用值productiondevelopemntnone,而process.env.NODE_ENV明显只是一个字符串范例的变量。
《运用 TypeScript 革新构建东西及测试用例》
所以我们须要运用三元运算符保证传入的参数一定是我们想要的。

以及在编写的历程当中,假如有一些自定义的plugin之类的,可以在运用的历程当中会抛非常提醒说某个对象不是有用的Plugin对象,一个很简朴的要领,在对应的plugin后边增加一个as webpack.Plugin即可。

在这里TypeScript所做的只是静态的搜检,并不会对现实的代码实行形成任何影响,就算范例由于强行as而转变,也只是编译期的修正,在现实实行的JavaScript代码中照样弱范例的

在完成了上述的操纵后,再实行npm run XXX就可以直接运转TypeScript版本的Webpack设置咯。

探究时期的一件趣事

由于我的项目根目次已装置了ts-node,而前端项目是作为个中的一个文件夹存在的,所以就没有再次举行装置。
这就带来了一个使人吐血的题目。

起首悉数流程走完今后,我直接在敕令行中输入TS_NODE_PROJECT=XXX.json NODE_ENV=dev webpack --config ./webpack/dev.ts
圆满运转,然后将这行敕令放到了npm scripts中:

{
  "scripts": {
    "start": "TS_NODE_PROJECT=XXX.json NODE_ENV=dev webpack --config ./webpack/dev.ts"
  }
}

再次运转npm start,发明居然出错了-.-,提醒我说import语法不能被辨认,这个很明显就是没有运用我们在ts_NODE_PROJECT中指定的config文件。
刚最先并不知道题目出在哪,由于这个在敕令行中直接实行并没有任何题目。
时期曾疑心是不是是环境变量没有被准确设置,还运用了cross-env这个插件,以至将敕令写到了一个sh文件中举行实行。
但是题目依旧存在,厥后在一个群中跟小伙伴们聊起了这个题目,有人提出,__你是不是是全局装置了ts-node__。
搜检今后发明,果真是的,在敕令行实行时运用的是全局的ts-node,然则在npm scripts中运用的是当地的ts-node
在敕令行环境实行时还以为是会自动寻觅父文件夹node_modules下边的依靠,现实上是运用的全局包。
乖乖的在client-src文件夹下也装置了ts-node就处理了这个题目。
全局依靠害人。。

测试用例的革新

前边的Webpack改成TypeScript大多数缘由是由于强迫症而至。
然则测试用例的TypeScript革新则是一个能极大进步效力的操纵。

为何要在测试用例中运用 TypeScript

测试用例运用chai来编写,_(之前的Postman也是用的chai的语法)_
chai供应了一系列的语义化链式挪用来完成断言。
在之前的分享中也提到过,这么多的敕令你并不须要完全记着,只知道一个expect(XXX).to.equal(true)就够了。

然则如许的通篇to.equal(true)是巨丑非常的,而假如运用那些语义化的链式挪用,在不熟练的情况下很轻易就会获得:

Error: XXX.XXX is not a function

由于这确切有一个门坎题目,必需要写许多才记着挪用划定规矩,种种notincludes的操纵。
然则接入了TypeScript今后,这些题目都水到渠成了。
也是前边提到的,一切的TypeScript模块都有其对应的.d.ts文件,用来通知我们这个模块是做什么的,供应了什么可以运用。
也就是说在测试用例编写时,我们可以经由历程动态提醒来疾速的誊写断言,而不须要结合著文档去举行“翻译”。

《运用 TypeScript 革新构建东西及测试用例》
《运用 TypeScript 革新构建东西及测试用例》

运用体式格局

假如是之前有写过mochachai的童鞋,基础上修正文件后缀+装置对应的@types即可。
可以直接跳到这里来:最先编写测试剧本
然则假如对测试用例感兴趣,然则并没有运用过的童鞋,可以看下边的一个基础步骤。

装置依靠

  1. TypeScript相干的装置,npm i -D typescript ts-node
  2. Mochachai相干的装置,npm i -D mocha chai @types/mocha @types/chai
  3. 假如须要涉及到一些API的要求,可以分外装置chai-httpnpm i -D chai-http @types/chai-http

环境的依靠就已完成了,假如分外的运用一些其他的插件,记得装置对应的@types文件即可。
假如有运用ESLint之类的插件,可以会提醒modules必需存在于dependencies而非devDependencies
这是ESLint的import/no-extraneous-dependencies划定规矩致使的,针对这个,我们现在的计划是增加一些破例:

import/no-extraneous-dependencies:
  - 2
  - devDependencies:
    - "**/*.test.js"
    - "**/*.spec.js"
    - "**/webpack*"
    - "**/webpack/*"

针对这些目次下的文件/文件夹不举行校验。_是的,webpack的运用也会碰到这个题目_

最先编写测试剧本

假如是对原有的测试剧本举行修正,无外乎修正后缀、增加一些必要的范例声明,不会对逻辑形成任何修正。

一个简朴的示例

// number-comma.ts
export default (num: number | string) => String(num).replace(/\B(?=(\d{3})+$)/g, ',')

// number-comma.spec.ts
import chai from 'chai'
import numberComma from './number-comma'

const { expect } = chai

// 测试项
describe('number-comma', () => {
  // 子项目1
  it('`1234567` should transform to `1,234,567`', done => {
    expect(numberComma(1234567)).to.equal('1,234,567')
    done()
  })

  // 子项目2
  it('`123` should never transform', done => {
    const num = 123
    expect(numberComma(num)).to.equal(String(num))
    done()
  })
})

假如全局没有装置mocha,记得将敕令写到npm script中,或许经由历程下述体式格局实行

./node_modules/mocha/bin/mocha -r ts-node/register test/number-comma.spec.ts

# 假如直接如许写,会抛出非常提醒 mocha 不是敕令
mocha -r ts-node/register test/number-comma.spec.ts

mocha有一点儿比较好的是供应了-r敕令来让你手动指定实行测试用例剧本所运用的诠释器,这里直接设置为ts-node的途径ts-node/register,然后就可以在后边直接跟一个文件名(或许是一些通配符)。

现在我们在项目中批量实行测试用例的敕令以下:

{
  "scripts": {
    "test": "mocha -r ts-node/register test/**/*.spec.ts"
  }
}

npm test可以直接挪用,而不须要增加run敕令符,相似的另有startbuild等等

一键实行今后就可以获得我们想要的效果了,再也不必忧郁一些代码的修改会影响到其他模块的逻辑了 (条件是认真写测试用例)

《运用 TypeScript 革新构建东西及测试用例》

小结

做完上边两步的操纵今后,我们的项目就完成了100%的TypeScript化,在任何地方享用静态编译语法所带来的优点。
附上更新后的代码含量截图:

《运用 TypeScript 革新构建东西及测试用例》

近来针对TypeScript做了许多事变,从Node.jsReact以及此次的WebpackMocha+Chai
TypeScript由于其存在一个编译的历程,极大的下降了代码出bug的可以性,进步顺序的稳固度。
周全切换到TypeScript更是可以下降在两种语法之间相互切换时所带来的不必要的斲丧,祝人人搬砖兴奋。

之前关于 TypeScript 的笔记

一个完全的 TypeScript 示例

typescript-example

迎接列位来议论关于TypeScript运用上的一些题目,针对庄重的觉得不足之处也迎接指出。

参考资料

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