大家好,我是若川。歡迎加我微信?ruochuan12,長期交流學習。今天分享一篇技術熱點,眾所周知,前不久vue3不打算支持IE11,vue2將支持composition API,現在vue2用ts重構,試問:還學得動嘛^_^。點擊下方卡片關注我,或者查看源碼等系列文章。學習源碼整體架構系列、年度總結、JS基礎系列
事情起源于 4 月 7 號晚上,尤雨溪在推特說,Vue2 收到了一個將整個代碼庫遷移到 TypeScript 的 PR。

去 Github 圍觀了一下chore: move to typescript 這個 PR[1],基本上是 10w 行級別代碼量的改動,把整個 Vue2 的代碼庫從原先的 flow 類型系統全部遷移到了 TypeScript,包括代碼、構建系統、各種 lint 工具等等,恐怖的戰斗力!

這個 PR 的貢獻者是 Carlos Rodrigues[2],以下是他的自我介紹:
Fullstack developer, interested in @vuejs, @dotnet and @nodejs.
Typescript ?????♂?
Consultant ??????♂?
全棧開發工程師,Vue.js、dotnet、Node.js 的愛好者。
TypeScript 魔法師 ?????♂?
顧問 ??????♂?。
起源
Vue2 為什么最開始選擇 Flow 作為類型系統?其實在一個 2016 年的知乎問題Vue 2.0 為什么選用 Flow 進行靜態代碼檢查而不是直接使用 TypeScript?[3]里,尤雨溪已經詳細說明了這個問題,以下是當時他的回答:
這個選擇最根本的還是在于工程上成本和收益的考量。
Vue 2.0 本身在初期的快速迭代階段是用 ES2015 寫的,整個構建工具鏈也沿用了 Vue 1.x 的基于 ES 生態的一套(Babel, ESLint, Webpack, Rollup...),全部換 TS 成本過高,短期內并不現實。
相比之下 Flow 對于已有的 ES2015 代碼的遷入/遷出成本都非常低:
可以一個文件一個文件地遷移,不需要一竿子全弄了。
Babel 和 ESLint 都有對應的 Flow 插件以支持語法,可以完全沿用現有的構建配置;
更貼近 ES 規范。除了 Flow 的類型聲明之外,其他都是標準的 ES。萬一哪天不想用 Flow 了,用 babel-plugin-transform-flow-strip-types 轉一下,就得到符合規范的 ES。
在需要的地方保留 ES 的靈活性,并且對于生成的代碼尺寸有更好的控制力 (rollup / 自定義 babel 插件)
不過在 2018 年的時候,尤大更新了回答,真香定律再現:

也正因如此,Vue3 從一開始就選擇了 TypeScript 作為類型系統。
困擾
那么也許有人要問,Vue2 不是已經穩定了嗎,何必再大費周章的把這么多代碼遷移到 TypeScript 中呢?其實在之前 Vue3 放棄 IE11 的 RFC 中就有提及,之后還是會為 Vue 2.7 去加入一些和 Vue3 語法更類似的功能:
把 @vue/composition-api plugin[4]合并進 Vue2。這會讓使用 Composition API 開發的庫同時支持 Vue2 和 Vue3。
單文件組件(SFC)中的script setup[5]語法。
emits
選項。提升 TypeScript 類型支持。
在 Vite 中正式支持 Vue 2(目前通過非官方插件[6])
而這些功能的開發和適配,如果繼續用 flow 的話,勢必會帶來一些割裂的開發體驗。一些已經用 TS 開發好的庫,也沒辦法做代碼的合并。事實上 Twitter 也有網友提出了這個問題,PR 作者進行了回答:

簡單來說,就是為 Vue 2.7 的開發做準備,尤其是 composition-api 的代碼合并。
具體內容
先看作者對這次更新的簡單描述:

代碼格式化風格更新。
重構。
構建相關的改動。
代碼庫更新為 TypeScript 編寫。
值得一提的是,更換成 TS 之后,生成的代碼體積都有少量的增加,作者猜測是 TS 加入了一些 runtime 的代碼導致的:

第一個 Commit 中,作者把代碼的類型全部改成 .ts,移除文件開頭 flow 的標記,并且把類型的語法全部替換成 TypeScript:

作者用 TS 的 import type
語法重構了類型導入,我個人也比較喜歡這樣導入類型,更有助于區分導入的內容:

單測工具的更新,以及 TS 的支持,利用 ts-loader 做編譯:

RollUp 版本的一次大升級:

ESLint 也需要一些改動,使用 @typescript-eslint/parser
,繼承的一些推薦預設也改為 @typescript-eslint/eslint-recommended
。

CI 中原本 flow 的類型檢測,也改成使用 tsc --noEmit
做 TS 的類型檢查。

評價
可怕的是,這個如此龐大的 PR 是作者在幾天內完成的,這戰斗力簡直是驚人。
Twitter 的評論中有人提問:“把如此巨大的代碼庫遷移到 TypeScript 需要多長時間?”
作者回答:在幾小時內重命名文件,把 flow types 重寫成 TS 類型并修復錯誤,之后的幾天主要是忙構建、測試相關的工作。

對此,外國推友也表示很震驚:
“你簡直是個機器”:
“他生活的宇宙中,1 小時可以頂我們 24 小時,或者也可能他是用光速在敲代碼”
CamiloR:“太棒了,很高興核心團隊之外,也有人付出如此多的努力”
Carlos:“我就是核心團隊的成員 ????”
總結
不得不感嘆,十倍工程師是真實存在的……這樣一次巨型代碼庫遷移只花了短短幾天時間,其實也體現出作者在 TS 生態、構建以及測試相關方面的熟悉程度。
感謝 Vue 核心團隊成員們夸張的戰斗力,給前端界帶來這么優秀的框架而且持續迭代和優化。
Vue 3 雖然是未來,但是 Vue 2 也不會被放棄,遷移到 TS 以后的 Vue 2 具有更強的代碼可移植性,一定會綻放出更多精彩。
參考資料
[1]
chore: move to typescript 這個 PR: https://github.com/vuejs/vue/pull/12001/commits
[2]Carlos Rodrigues: https://twitter.com/pikax_dev
[3]Vue 2.0 為什么選用 Flow 進行靜態代碼檢查而不是直接使用 TypeScript?: https://www.zhihu.com/question/46397274/answer/101193678
[4]@vue/composition-api plugin: https://github.com/vuejs/composition-api
[5]script setup: https://github.com/vuejs/rfcs/pull/227
[6]非官方插件: https://github.com/underfin/vite-plugin-vue2
最近組建了一個江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你進群。
·················?若川出品?·················
今日話題
今天分享一個chrome瀏覽器標簽預覽功能,打開chrome://flags,搜索tab hover Card Images,改成Enabled就開啟啦,快試試吧。歡迎分享、收藏、點贊、在看我的公眾號文章~
一個愿景是幫助5年內前端人走向前列的公眾號
可加我個人微信 ruochuan12,長期交流學習
推薦閱讀
我在阿里招前端,我該怎么幫你?(現在還能加我進模擬面試群)
如何拿下阿里巴巴 P6 的前端 Offer
點擊上方卡片關注我,或者查看源碼等系列文章。
學習源碼整體架構系列、年度總結、JS基礎系列