前端這些年發展很是迅速,社區裏涌現了一堆優秀的輪子,好比Vue、React、Angular、jQuery、axios 等,它們解決着不一樣領域下的問題。使用這些輪子能極大地幫助咱們提高生產力,有些人甚至基於這些輪子二次開發了一些輪子,好比 element-ui、ant-design 等組件庫。咱們在享受這些輪子給咱們帶來的便利的時候,有時候也須要面臨一些問題:某些輪子不能知足咱們本身的特殊業務需求,找不到合適的輪子等。所以咱們不只要會使用輪子,也須要有造輪子的能力。html
2019 年,前端技術發展愈來愈迅速,其中 TypeScript 更是受到了愈來愈多的開發者的青睞,在 GitHub 上搜索 star 數大於 1w 的項目,咱們能夠看到不少知名的開源項目如 vscode、angular、ant-design、ionic、deno 等都使用 TypeScript 開發,19 年上升最快的 Vue.js 3.0 也正在用 TypeScript 重構,尤老師都忍不住發出了 「真香」 的言論。前端
TypeScript 的火爆程度大有成爲下一代前端開發語言的趨勢,TypeScript 做爲 JavaScript 語言的超集,它爲 JavaScript 添加了可選擇的類型標註,大大加強了代碼的可讀性和可維護性。同時,它提供最新和不斷髮展的 JavaScript 特性,能讓咱們創建更健壯的組件。node
愈來愈多的輪子將用 TypeScript 開發和重構,咱們若是想造輪子,也應該使用 TypeScript 這把利器。webpack
咱們造輪子首先會初始化一個項目,但須要配置一大堆東西,好比 package.json
、.editorconfig
、.gitignore
等,還包括一些構建工具如 rollup
、webpack
以及它們的配置。ios
當咱們使用 TypeScript 去寫一個項目的時候,還須要配置 TypeScript 的編譯配置文件 tsconfig.json
以及 tslint.json
文件。git
這些茫茫多的配置每每會讓一個想從零開始寫項目的同窗望而卻步,若是有一個腳手架工具幫咱們生成好這些初始化文件該多好。好在確實有這樣的工具,接下來咱們的主角 TypeScript library starter
隆重登場。github
它是一個開源的 TypeScript 開發基礎庫的腳手架工具,能夠幫助咱們快速初始化一個 TypeScript 項目,咱們能夠去它的官網地址學習和使用它。web
git clone https://github.com/alexjoverm/typescript-library-starter.git ts-axioscd ts-axios
npm install
複製代碼
先經過 git clone
把項目代碼拉下來到咱們的 ts-axios
目錄,而後運行 npm install
安裝依賴,而且給項目命名,咱們仍然使用 ts-axios
。typescript
安裝好依賴後,咱們先來預覽一下這個項目的目錄結構。npm
TypeScript library starter
生成的目錄結構以下:
├── CONTRIBUTING.md
├── LICENSE ├── README.md
├── code-of-conduct.md
├── node_modules
├── package-lock.json
├── package.json
├── rollup.config.ts // rollup 配置文件
├── src // 源碼目錄
├── test // 測試目錄
├── tools // 發佈到 GitHup pages 以及 發佈到 npm 的一些配置腳本工具
├── tsconfig.json // TypeScript 編譯配置文件
└── tslint.json // TypeScript lint 文件
複製代碼
使用 TypeScript library starter
建立的項目集成了不少優秀的開源工具:
這裏咱們列舉了不少工具,感興趣的同窗們能夠點開他們的連接對這些工具作進一步學習。
工欲善其事必先利其器,咱們如今已經搭好了一個項目的雛形,接下來就要開始編寫輪子的代碼了。
通常輪子的特色,專一於作某一塊事情,爲了更直觀和具體,咱們以一個很是知名的前端開源庫 axios 爲例,站在輪子製造者的角度上,來討論一下一個優秀的輪子是如何設計出來的。
axios
核心專一於發送 http 請求,而且在此基礎了擴展了不少實用和好用的 feature,以下:
對於輪子的使用者,這些 feature 能讓咱們知道輪子是作什麼的,而對於輪子的製造者,這些 feature 就是咱們的需求。對於這些需求,咱們能夠劃分一下優先級:優先實如今瀏覽器端的請求發送邏輯,實現一些基礎功能如請求發送和響應,Promise API,請求數據和響應數據的轉換,JSON 數據自動轉換以及一些異常狀況處理;接着再去擴展攔截器、配置化、請求取消等複雜功能,而後擴展一些簡單的功能如客戶端防止 XSRF、上傳等;最後開發 axios 在 Node.js 端的擴展。
咱們的編碼的思路也就是按優先級的重要程度依次去開發上述功能。
一個輪子是否優秀,首先取決於它是否好用,使用是否方便,五六年前,仍是 jQuery 的時代,jQuery 就提供了一個很是好用的 $
設計,搶佔了大部分市場。當年百度也出了一個相似的庫叫 tangram,建立一個 DOM 對象須要寫 Baidu.T.createDOM(xxx)
,而 jQuery 只須要 $(xxx)
便可,高下立判。
axios
設計也是很是簡單,直接 axios(config)
就能夠完成一個請求的發送了,爲了減小 config
中的配置參數,還提供了 axios.get
、axios.post
等接口。爲了方便用戶拿到響應結果,axios
支持了 Promise API
,咱們能夠經過 axios(config).then(res =>{})
的方式拿到響應對象。
axios
能夠支持很是多的 feature,徹底得益於 config
配置參數,對於 feature 的擴展,咱們既能夠經過擴展 axios 的實例或者靜態方法來實現,也能夠擴展 config
的字段來實現,原則是怎麼方便用戶使用怎麼來。
axios 本質上就是發送一個請求,拿到響應結果,中途能夠去對配置參數、請求數據和響應數據處理,同時也支持一些攔截器的調用,所以咱們能夠畫出它的生命週期圖示。
經過生命週期圖示咱們能夠清晰地瞭解一個 axios 工做流程。
綜上所述, axios
既是一個函數,又是一個接口,便是一個實例對象,也擁有一些靜態方法,若是咱們使用 TypeScript 開發,該如何設計 axios
的類型?另外,axios
對外提供的很是多的 API 接口、配置參數,咱們又該如何使用 TypeScript 定義這些類型呢?根據生命週期圖示,咱們能夠按流程中的行爲去拆分功能模塊,咱們如何使用 TypeScript 作模塊拆分和管理的,哪些模塊又能夠被抽成基礎公共模塊呢?在實現整個 axios 庫的過程當中,如何不斷作代碼的優化、抽象和封裝?如何使用策略模式實現配置合併?攔截器的 Promise 鏈如何設計?如何經過異步分離實現取消功能?
面對上述問題,不知道你心中是否有答案,若是你尚未想到或者對 axios
的實現感興趣,不妨來學習個人新課 《TypeScript 從零重構 axios 庫》,來一塊兒對 axios 庫抽絲剝繭,使用 TypeScript 一步步去實現一個完整的 axios
庫。
一個優秀的輪子,必定會有單元測試,單元測試是輪子的質量保證,甚至還有測試驅動開發的開發模式。不少同窗對單元測試一直處於一種據說過,但沒用過的狀態。其實寫單元測試並不難,首先咱們要保證全部工具方法、輔助函數的測試完整性;而後要保證 feature 的測試完整性,保證每個 feature 的各類狀況都能測到。一個檢測測試完整性的經常使用手段是看測試的覆蓋率,一般咱們會要求測試覆蓋率達到 90% 以上。
單元測試有一個很是大的好處是你能夠放心地對你現有的代碼作新 feature 的開發,以及代碼的重構,而不用擔憂代碼的改動影響已有功能,咱們能夠很容易地經過跑單元測試檢測咱們改動的代碼是否有問題。
目前前端測試的框架有不少,我比較推薦 Jest,它是一個幾乎零配置的測試框架,很是易於上手,由 facebook 團隊維護,質量也能獲得保證。新課程就是使用 Jest 來編寫 axios
的單元測試,你會學到不少編寫單元測試的方法和技巧,對單元測試感興趣的同窗能夠來學習咯。
TypeScript 在類型方面的約束,以及提供不少好用的現代 JavaScript 語法特性,很是適合用它去造一個輪子,固然也很是適合開發大型複雜前端項目。前端的趨勢會愈來愈複雜,TypeScript 這個技術棧在將來必定會變成前端必須掌握的開發技能。
至於造輪子,能不能設計好用的輪子,輪子能不能知足複雜的需求,對你的 JavaScript 內功、代碼設計能力都是有很高的要求,造輪子的過程就是一個內功修煉的過程。因此,若是你不知足於作一個熟練工,一個螺絲釘,想提高本身的核心競爭力,那麼從今天開始,拿起 TypeScript 作一個輪子的製造者。