最近的一段时间一直在搞TypeScript,一个巨硬出品、赋予JavaScript语言静态类型和编译的语言。
第一个完全使用TypeScript重构的纯Node.js项目已经上线并稳定运行了。
第二个前后端的项目目前也在重构中,关于前端基于webpackTypeScript套路之前也有提到过:TypeScript在react项目中的实践。

但是这些做完以后也总感觉缺了点儿什么 (没有尽兴)


是的,依然有五分之一的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的一个好处就是,当要实现一个功能时你不再需要去网站上查询应该要配置什么,可以直接翻看d.ts的定义。
如果注释写得足够完善,基本可以当成文档来用了,而且在VS Code编辑器中还有动态的提示,以及一些错误的纠正,比如上述的NODE_ENV的获取,如果直接写process.env.NODE_ENV || 'development'是会抛出一个异常的,因为从d.ts中可以看到,关于mode只有三个有效值productiondevelopemntnone,而process.env.NODE_ENV显然只是一个字符串类型的变量。

所以我们需要使用三元运算符保证传入的参数一定是我们想要的。

以及在编写的过程中,如果有一些自定义的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文件,用来告诉我们这个模块是做什么的,提供了什么可以使用。
也就是说在测试用例编写时,我们可以通过动态提示来快速的书写断言,而不需要结合着文档去进行“翻译”。


使用方式

如果是之前有写过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', () => {// 子项目1it('`1234567` should transform to `1,234,567`', done => {expect(numberComma(1234567)).to.equal('1,234,567')done()})// 子项目2it('`123` should never transform', done => {const num = 123expect(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等等

一键执行以后就可以得到我们想要的结果了,再也不用担心一些代码的改动会影响到其他模块的逻辑了 (前提是认真写测试用例)

小结

做完上边两步的操作以后,我们的项目就实现了100%的TypeScript化,在任何地方享受静态编译语法所带来的好处。
附上更新后的代码含量截图:

最近针对TypeScript做了很多事情,从Node.jsReact以及这次的WebpackMocha+Chai
TypeScript因为其存在一个编译的过程,极大的降低了代码出bug的可能性,提高程序的稳定度。
全面切换到TypeScript更是能够降低在两种语法之间互相切换时所带来的不必要的消耗,祝大家搬砖愉快。

之前关于 TypeScript 的笔记

  • TypeScript在node项目中的实践
  • TypeScript在react项目中的实践

一个完整的 TypeScript 示例

typescript-example

欢迎各位来讨论关于TypeScript使用上的一些问题,针对稳重的感觉不足之处也欢迎指出。

参考资料

  • ts-node
  • configuration-languages | webpack
  • mochajs
  • chaijs

转载于:https://www.cnblogs.com/jiasm/p/9577715.html

使用 TypeScript 改造构建工具及测试用例相关推荐

  1. 前端构建工具_构建工具

    前端构建工具 深度JavaScript (Deep JavaScript) Choosing a development tool based on its popularity isn't a ba ...

  2. 快70倍!新一代JS构建工具:ESBuild SWC浅析

    首先, ESBuild & swc是什么? ESBuild[1]是基于Go语言开发的JavaScript Bundler, 由Figma前CTO Evan Wallace开发, 并且也被Vit ...

  3. gulp前端自动化构建工具:常用插件介绍及使用

      Gulp是基于Node.js的一个构建工具(自动任务运行器),开发者可以使用它构建自动化工作流程(前端集成开发环境).一些常见.重复的任务,例如:网页自动刷新.CSS预处理.代码检测.压缩图片.等 ...

  4. pika开源:替代WebPack的全新JS构建工具

    在过去几年中,JavaScript打包已经从一种生产环境优化手段演变成几乎所有Web App都必不可少的构建步骤.不管你喜欢与否,打包器已经给Web开发带来了巨大的复杂性,这是个不争的事实. 为什么要 ...

  5. npm run buil构建后页面白屏_从Npm Script到Webpack,6种常见的前端构建工具对比

    从Npm Script到Webpack,6种常见的前端构建工具对比 小编说:历史上先后出现了一系列构建工具,它们各有优缺点.由于前端工程师很熟悉JavaScript,Node.js又可以胜任所有构建需 ...

  6. vue怎么使用eval_Webpack 构建工具手把手教你怎么用

    Webpack:构建工具​ 介绍 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构建 ...

  7. 前端构建工具gulp之基本介绍

    1.基本介绍 gulp.js是一个自动化构建工具,是自动化项目的构建利器.可以对网站的资源进行优化,将开发过程中一些重复的任务通过执行命令自动完成.这样能很大的提高我们的工作效率. gulp.js是基 ...

  8. 前端构建工具之争——Webpack vs Gulp 谁会被拍死在沙滩上

    阅读目录 理想的前端开发流程 Gulp 为何物 webpack 又是从哪冒出来的 结论 文章有点长,总共 1800 字,阅读需要 18 分钟.哈哈,没耐心的直接戳我到高潮部分. 理想的前端开发流程 在 ...

  9. 时下最流行前端构建工具Webpack 入门总结

    作者:wenjuanrao,腾讯 PCG 前端开发工程师 最近梳理了下以前 webpack 的相关开发经验,整理和总结了一份入门笔记,欢迎大家围观和批评指正. 随着 web 应用越来越复杂和庞大,前端 ...

最新文章

  1. Linux基础命令使用
  2. 线上直播 | NVIDIA TensorRT在神经机器翻译中的应用
  3. 获得最新纪录 sql
  4. mysql将查到的数据删除_MySQL数据库的基本操作——增、删、改、查
  5. 老码农90%的程序员都是瞎努力!这份路线教你成为高手
  6. Git 有时候推送以及拉去不了代码解决方式(二)
  7. Centos 6.5 安装 Nginx+MySQL+PHP
  8. 《现代操作系统》精读与思考笔记 第一章 引论
  9. java版电子商务spring cloud分布式微服务b2b2c社交电商(一)服务的注册与发现(Eureka)...
  10. 强烈推荐 | 算法/深度学习/NLP面试笔记
  11. 类文件Android 代码混淆 以及 反编译 的实现类文件
  12. 人工智能知识体系的学习路线(南京大学人工智能学院本科生培养体系)
  13. Ubuntu 安装 GMSSL
  14. 百度地图的经纬度转高德地图的经纬度
  15. 番茄助手(Visual Assist X)过期的应对方法
  16. ADNI以及study design简介
  17. 中国会展业大数据中心在贵阳成立
  18. 图形学课设 塔防游戏
  19. 福建计算机会考几分过,福建会考合格的标准是什么?
  20. 小六六读Effective记录

热门文章

  1. vba里面的日期数据转换异常(Format error)(使用IsDate方法部分解决)
  2. 端口停止使用_我停止使用
  3. TCP流量控制与拥塞控制区别
  4. 怎样在sqlite3上执行SQL语句
  5. 过年回家,走之前留一个用GDI+实现的略缩图控件
  6. Linux-Android启动之zImage生成过程详解
  7. 计算机组成原理的实验课心得,计算机组成原理移位控制实验心得.docx
  8. sql server cdc 清理_基于CDC技术的ElasticSearch索引同步机制
  9. visual studio 调试python_Visual Studio Code Python 调试设置
  10. 主管护士需要考计算机和英语吗,2020主管护师改为机考,一定要注意这些问题!...