成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用 TypeScript 改造構(gòu)建工具及測(cè)試用例

Cristic / 3459人閱讀

摘要:第一個(gè)完全使用重構(gòu)的純項(xiàng)目已經(jīng)上線并穩(wěn)定運(yùn)行了。測(cè)試用例的改造前邊的改為大多數(shù)原因是因?yàn)閺?qiáng)迫癥所致。但是測(cè)試用例的改造則是一個(gè)能極大提高效率的操作。

最近的一段時(shí)間一直在搞TypeScript,一個(gè)巨硬出品、賦予JavaScript語言靜態(tài)類型和編譯的語言。
第一個(gè)完全使用TypeScript重構(gòu)的純Node.js項(xiàng)目已經(jīng)上線并穩(wěn)定運(yùn)行了。
第二個(gè)前后端的項(xiàng)目目前也在重構(gòu)中,關(guān)于前端基于webpackTypeScript套路之前也有提到過:TypeScript在react項(xiàng)目中的實(shí)踐。

但是這些做完以后也總感覺缺了點(diǎn)兒什么 _(沒有盡興)_:


是的,依然有五分之一的JavaScript代碼存在于項(xiàng)目中,作為一個(gè)TypeScript的示例項(xiàng)目,表現(xiàn)的很不純粹。
所以有沒有可能將這些JavaScript代碼也換成TypeScript呢?
答案肯定是有的,首先需要分析這些代碼都是什么:

Webpack打包時(shí)的配置文件

一些簡(jiǎn)單的測(cè)試用例(使用的mocha和chai)

知道了是哪些地方還在使用JavaScript,這件事兒就變得很好解決了,從構(gòu)建工具(Webpack)開始,逐個(gè)擊破,將這些全部替換為TypeScript。

Webpack 的 TypeScript 實(shí)現(xiàn)版本

在這8102年,很幸福,Webpack官方已經(jīng)支持了TypeScript編寫配置文件,文檔地址。
除了TypeScript以外還支持JSXCoffeeScript的解釋器,在這就忽略它們的存在了

依賴的安裝

首先是要安裝TypeScript相關(guān)的一套各種依賴,包括解釋器及該語言的核心模塊:

npm install -D typescript ts-node

typescript為這個(gè)語言的核心模塊,ts-node用于直接執(zhí)行.ts文件,而不需要像tsc那樣會(huì)編譯輸出.js文件。

ts-node helloworld.ts

因?yàn)橐?b>TypeScript環(huán)境下使用Webpack相關(guān)的東東,所以要安裝對(duì)應(yīng)的types
也就是Webpack所對(duì)應(yīng)的那些*.d.ts,用來告訴TypeScript這是個(gè)什么對(duì)象,提供什么方法。

npm i -D @types/webpack

一些常用的pLugin都會(huì)有對(duì)應(yīng)的@types文件,可以簡(jiǎn)單的通過npm info @types/XXX來檢查是否存在

如果是一些小眾的plugin,則可能需要自己創(chuàng)建對(duì)應(yīng)的d.ts文件,例如我們一直在用的qiniu-webpack-plugin,這個(gè)就沒有對(duì)應(yīng)的@types包的,所以就自己創(chuàng)建一個(gè)空文件來告訴TypeScript這是個(gè)啥:

declare module "qiniu-webpack-plugin" // 就一個(gè)簡(jiǎn)單的定義即可

// 如果還有其他的包,直接放到同一個(gè)文件就行了
// 文件名也沒有要求,保證是 d.ts 結(jié)尾即可

放置的位置沒有什么限制,隨便丟,一般建議放到types文件夾下

最后就是.ts文件在執(zhí)行時(shí)的一些配置文件設(shè)置。
用來執(zhí)行Webpack.ts文件對(duì)tsconfig.json有一些小小的要求。
compilerOptions下的target選項(xiàng)必須是es5,這個(gè)代表著輸出的格式。
以及module要求選擇commonjs。

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

但一般來講,執(zhí)行Webpack的同級(jí)目錄都已經(jīng)存在了tsconfig.json,用于實(shí)際的前端代碼編譯,很可能兩個(gè)配置文件的參數(shù)并不一樣。
如果因?yàn)橐褂?b>Webpack去修改真正的代碼配置參數(shù)肯定是不可取的。
所以我們就會(huì)用到這么一個(gè)包,用來改變ts-node執(zhí)行時(shí)所依賴的配置文件:tsconfig-paths

Readme中發(fā)現(xiàn)了這樣的說法:If process.env.TS_NODE_PROJECT is set it will be used to resolved tsconfig.json。
Webpack的文檔中同樣也提到了這句,所以這是一個(gè)兼容的方法,在命令運(yùn)行時(shí)指定一個(gè)路徑,在不影響原有配置的情況下創(chuàng)建一個(gè)供Webpack打包時(shí)使用的配置。

將上述的配置文件改名為其它名稱,Webpack文檔示例中為tsconfig-for-webpack-config.json,這里就直接沿用了

然后添加npm script如下

{
  "scripts": {
    "build": "TS_NODE_PROJECT=tsconfig-for-webpack-config.json webpack --config configs.ts"
  }
}
文件的編寫

關(guān)于配置文件,從JavaScript切換到TypeScript實(shí)際上并不會(huì)有太大的改動(dòng),因?yàn)?b>Webpack的配置文件大多都是寫死的文本/常量。
很多類型都是自動(dòng)生成的,基本可以不用手動(dòng)指定,一個(gè)簡(jiǎn)單的示例:

import { Configuration } from "webpack"

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

export default config

Configuration是一個(gè)Webpack定義的接口(interface),用來規(guī)范一個(gè)對(duì)象的行為。
VS Code下按住Command + 單擊可以直接跳轉(zhuǎn)到具體的webpack.d.ts定義文件那里,可以看到詳細(xì)的定義信息。

各種常用的規(guī)則都寫在了這里,使用TypeScript的一個(gè)好處就是,當(dāng)要實(shí)現(xiàn)一個(gè)功能時(shí)你不再需要去網(wǎng)站上查詢應(yīng)該要配置什么,可以直接翻看d.ts的定義。
如果注釋寫得足夠完善,基本可以當(dāng)成文檔來用了,而且在VS Code編輯器中還有動(dòng)態(tài)的提示,以及一些錯(cuò)誤的糾正,比如上述的NODE_ENV的獲取,如果直接寫process.env.NODE_ENV || "development"是會(huì)拋出一個(gè)異常的,因?yàn)閺?b>d.ts中可以看到,關(guān)于mode只有三個(gè)有效值production、developemntnone,而process.env.NODE_ENV顯然只是一個(gè)字符串類型的變量。

所以我們需要使用三元運(yùn)算符保證傳入的參數(shù)一定是我們想要的。

以及在編寫的過程中,如果有一些自定義的plugin之類的,可能在使用的過程中會(huì)拋異常提示說某個(gè)對(duì)象不是有效的Plugin對(duì)象,一個(gè)很簡(jiǎn)單的方法,在對(duì)應(yīng)的plugin后邊添加一個(gè)as webpack.Plugin即可。

在這里TypeScript所做的只是靜態(tài)的檢查,并不會(huì)對(duì)實(shí)際的代碼執(zhí)行造成任何影響,就算類型因?yàn)閺?qiáng)行as而改變,也只是編譯期的修改,在實(shí)際執(zhí)行的JavaScript代碼中還是弱類型的

在完成了上述的操作后,再執(zhí)行npm run XXX就可以直接運(yùn)行TypeScript版本的Webpack配置咯。

探索期間的一件趣事

因?yàn)槲业捻?xiàng)目根目錄已經(jīng)安裝了ts-node,而前端項(xiàng)目是作為其中的一個(gè)文件夾存在的,所以就沒有再次進(jìn)行安裝。
這就帶來了一個(gè)令人吐血的問題。

首先全部流程走完以后,我直接在命令行中輸入TS_NODE_PROJECT=XXX.json NODE_ENV=dev webpack --config ./webpack/dev.ts
完美運(yùn)行,然后將這行命令放到了npm scripts中:

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

再次運(yùn)行npm start,發(fā)現(xiàn)竟然出錯(cuò)了-.-,提示我說import語法不能被識(shí)別,這個(gè)很顯然就是沒有應(yīng)用我們?cè)?b>ts_NODE_PROJECT中指定的config文件。
剛開始并不知道問題出在哪,因?yàn)檫@個(gè)在命令行中直接執(zhí)行并沒有任何問題。
期間曾經(jīng)懷疑是否是環(huán)境變量沒有被正確設(shè)置,還使用了cross-env這個(gè)插件,甚至將命令寫到了一個(gè)sh文件中進(jìn)行執(zhí)行。
然而問題依然存在,后來在一個(gè)群中跟小伙伴們聊起了這個(gè)問題,有人提出,__你是不是全局安裝了ts-node__。
檢查以后發(fā)現(xiàn),果然是的,在命令行執(zhí)行時(shí)使用的是全局的ts-node,但是在npm scripts中使用的是本地的ts-node。
在命令行環(huán)境執(zhí)行時(shí)還以為是會(huì)自動(dòng)尋找父文件夾node_modules下邊的依賴,其實(shí)是使用的全局包。
乖乖的在client-src文件夾下也安裝了ts-node就解決了這個(gè)問題。
全局依賴害人。。

測(cè)試用例的改造

前邊的Webpack改為TypeScript大多數(shù)原因是因?yàn)閺?qiáng)迫癥所致。
但是測(cè)試用例的TypeScript改造則是一個(gè)能極大提高效率的操作。

為什么要在測(cè)試用例中使用 TypeScript

測(cè)試用例使用chai來編寫,_(之前的Postman也是用的chai的語法)_
chai提供了一系列的語義化鏈?zhǔn)秸{(diào)用來實(shí)現(xiàn)斷言。
在之前的分享中也提到過,這么多的命令你并不需要完全記住,只知道一個(gè)expect(XXX).to.equal(true)就夠了。

但是這樣的通篇to.equal(true)是巨丑無比的,而如果使用那些語義化的鏈?zhǔn)秸{(diào)用,在不熟練的情況下很容易就會(huì)得到:

Error: XXX.XXX is not a function

因?yàn)檫@確實(shí)有一個(gè)門檻問題,必須要寫很多才能記住調(diào)用規(guī)則,各種notincludes的操作。
但是接入了TypeScript以后,這些問題都迎刃而解了。
也是前邊提到的,所有的TypeScript模塊都有其對(duì)應(yīng)的.d.ts文件,用來告訴我們這個(gè)模塊是做什么的,提供了什么可以使用。
也就是說在測(cè)試用例編寫時(shí),我們可以通過動(dòng)態(tài)提示來快速的書寫斷言,而不需要結(jié)合著文檔去進(jìn)行“翻譯”。


使用方式

如果是之前有寫過mochachai的童鞋,基本上修改文件后綴+安裝對(duì)應(yīng)的@types即可。
可以直接跳到這里來:開始編寫測(cè)試腳本
但是如果對(duì)測(cè)試用例感興趣,但是并沒有使用過的童鞋,可以看下邊的一個(gè)基本步驟。

安裝依賴

TypeScript相關(guān)的安裝,npm i -D typescript ts-node

Mocha、chai相關(guān)的安裝,npm i -D mocha chai @types/mocha @types/chai

如果需要涉及到一些API的請(qǐng)求,可以額外安裝chai-http,npm i -D chai-http @types/chai-http

環(huán)境的依賴就已經(jīng)完成了,如果額外的使用一些其他的插件,記得安裝對(duì)應(yīng)的@types文件即可。
如果有使用ESLint之類的插件,可能會(huì)提示modules必須存在于dependencies而非devDependencies
這是ESLint的import/no-extraneous-dependencies規(guī)則導(dǎo)致的,針對(duì)這個(gè),我們目前的方案是添加一些例外:

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

針對(duì)這些目錄下的文件/文件夾不進(jìn)行校驗(yàn)。_是的,webpack的使用也會(huì)遇到這個(gè)問題_

開始編寫測(cè)試腳本

如果是對(duì)原有的測(cè)試腳本進(jìn)行修改,無外乎修改后綴、添加一些必要的類型聲明,不會(huì)對(duì)邏輯造成任何修改。

一個(gè)簡(jiǎn)單的示例
// 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

// 測(cè)試項(xiàng)
describe("number-comma", () => {
  // 子項(xiàng)目1
  it("`1234567` should transform to `1,234,567`", done => {
    expect(numberComma(1234567)).to.equal("1,234,567")
    done()
  })

  // 子項(xiàng)目2
  it("`123` should never transform", done => {
    const num = 123
    expect(numberComma(num)).to.equal(String(num))
    done()
  })
})

如果全局沒有安裝mocha,記得將命令寫到npm script中,或者通過下述方式執(zhí)行

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

# 如果直接這樣寫,會(huì)拋出異常提示 mocha 不是命令
mocha -r ts-node/register test/number-comma.spec.ts

mocha有一點(diǎn)兒比較好的是提供了-r命令來讓你手動(dòng)指定執(zhí)行測(cè)試用例腳本所使用的解釋器,這里直接設(shè)置為ts-node的路徑ts-node/register,然后就可以在后邊直接跟一個(gè)文件名(或者是一些通配符)。

目前我們?cè)陧?xiàng)目中批量執(zhí)行測(cè)試用例的命令如下:

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

npm test可以直接調(diào)用,而不需要添加run命令符,類似的還有startbuild等等

一鍵執(zhí)行以后就可以得到我們想要的結(jié)果了,再也不用擔(dān)心一些代碼的改動(dòng)會(huì)影響到其他模塊的邏輯了 (前提是認(rèn)真寫測(cè)試用例)

小結(jié)

做完上邊兩步的操作以后,我們的項(xiàng)目就實(shí)現(xiàn)了100%的TypeScript化,在任何地方享受靜態(tài)編譯語法所帶來的好處。
附上更新后的代碼含量截圖:

最近針對(duì)TypeScript做了很多事情,從Node.js、React以及這次的WebpackMocha+Chai。
TypeScript因?yàn)槠浯嬖谝粋€(gè)編譯的過程,極大的降低了代碼出bug的可能性,提高程序的穩(wěn)定度。
全面切換到TypeScript更是能夠降低在兩種語法之間互相切換時(shí)所帶來的不必要的消耗,祝大家搬磚愉快。

之前關(guān)于 TypeScript 的筆記

TypeScript在node項(xiàng)目中的實(shí)踐

TypeScript在react項(xiàng)目中的實(shí)踐

一個(gè)完整的 TypeScript 示例

typescript-example

歡迎各位來討論關(guān)于TypeScript使用上的一些問題,針對(duì)穩(wěn)重的感覺不足之處也歡迎指出。

參考資料

ts-node

configuration-languages | webpack

mochajs

chaijs

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97309.html

相關(guān)文章

  • 前端每周清單第 11 期:Angular 4.1支持TypeScript 2.3,Vue 2.3優(yōu)化

    摘要:斯坦福宣布使用作為計(jì)算機(jī)課程的首選語言近日,某位有年教學(xué)經(jīng)驗(yàn)的斯坦福教授決定放棄,而使用作為計(jì)算機(jī)入門課程的教學(xué)語言。斯坦福官方站點(diǎn)將它們新的課程描述為是最流行的構(gòu)建交互式的開發(fā)語言,本課程會(huì)用講解中的實(shí)例。 前端每周清單第 11 期:Angular 4.1支持TypeScript 2.3,Vue 2.3優(yōu)化服務(wù)端渲染,優(yōu)秀React界面框架合集 為InfoQ中文站特供稿件,首發(fā)地址為...

    warkiz 評(píng)論0 收藏0
  • 前端每周清單半年盤點(diǎn)之 JavaScript 篇

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。背后的故事本文是對(duì)于年之間世界發(fā)生的大事件的詳細(xì)介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎...

    Vixb 評(píng)論0 收藏0
  • 快速 TypeScript 化 lodash 中的 throttle & debounce

    摘要:背景需要包寫起來爽,然而如果遇到?jīng)]有現(xiàn)成的化的工具函數(shù),就需要自己想辦法弄出一份類型聲明文件了。最為重要的是,這種遷移方面我們可以隨意自定義化中所需要的工具函數(shù),遷移粒度都可以由自己控制。 1、背景 1.1、需要 TS 包 TypeScript 寫起來爽,然而如果遇到?jīng)]有現(xiàn)成的 TS 化的工具函數(shù),就需要自己想辦法弄出一份類型聲明文件了。 前兩天要寫的小工具庫(Typescript 語...

    lewinlee 評(píng)論0 收藏0
  • 做一個(gè)合格的前端,gulp資源大集合

    摘要:承接前一篇做一個(gè)合格的前端,自動(dòng)化構(gòu)建工具入門教程故而整理了如下插件資源大全。接下來我會(huì)逐一開源觀點(diǎn)網(wǎng)開發(fā)過程中的前后端技術(shù),如全文索引自定義富文本編輯器圖片上傳壓縮水印等等。 承接前一篇《做一個(gè)合格的前端,gulp自動(dòng)化構(gòu)建工具入門教程》故而整理了如下gulp插件資源大全。**【我的新作觀點(diǎn)網(wǎng):http://www.guandn.com (觀點(diǎn)網(wǎng)是一個(gè)獵獲新奇、收獲知識(shí)、重在獨(dú)立思考...

    Baoyuan 評(píng)論0 收藏0
  • Vue源碼之目錄結(jié)構(gòu)

    摘要:運(yùn)行時(shí)用來創(chuàng)建實(shí)例渲染并處理虛擬等的代碼。基本上就是除去編譯器的其它一切。版本可以通過標(biāo)簽直接用在瀏覽器中。為這些打包工具提供的默認(rèn)文件是只有運(yùn)行時(shí)的構(gòu)建。為瀏覽器提供的用于在現(xiàn)代瀏覽器中通過直接導(dǎo)入。 Vue版本:2.6.9 源碼結(jié)構(gòu)圖 ├─ .circleci // 包含CircleCI持續(xù)集成/持續(xù)部署工具的配置文件 ├─ .github ...

    freewolf 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<