前言 之前寫過一篇舊React項目安裝並使用TypeScript的文章: "在React舊項目中安裝並使用TypeScript的實踐" 。 博客里使用awesome typescript loader對Typescript代碼進行檢測和轉換。 而這幾天又修改了一下自己的腳手架,使用@babel/pr ...
前言
之前寫過一篇舊React項目安裝並使用TypeScript的文章:在React舊項目中安裝並使用TypeScript的實踐。
博客里使用awesome-typescript-loader對Typescript代碼進行檢測和轉換。
而這幾天又修改了一下自己的腳手架,使用@babel/preset-typescript來處理Typescript。
回顧awesome-typescript-loader方案
談@babel/preset-typescript的優越性之前,還是先說下awesome-typescript-loader方案是如何對TypeScript進行處理的。
首先我們需要知道TypeScript是一個將TypeScript轉換為指定版本JS代碼的編譯器,而Babel同樣是一個將新版本JS新語法轉換為低版本JS代碼的編譯器。
所以我們之前的方案每次修改了一點代碼,都會將TS代碼傳遞給TypeScript轉換為JS,然後再將這份JS代碼傳遞給Babel轉換為低版本JS代碼。
因此我們需要配置兩個編譯器,並且每次做了一點更改,都會經過兩次編譯。
@babel/preset-typescript方案
介紹這個方案之前,我需要列出我參考的一篇譯文:[譯] TypeScript 和 Babel:一場美麗的婚姻。
這裡提到這是 TypeScript 和 Babel 團隊長達一年的官方合作成果,所以至少我們不用擔心這是個野生方案會爛尾。
核心提煉一下:@babel/preset-typescript和@babel/preset-react類似,是將特殊的語法轉換為JS。
但是有點區別的是,@babel/preset-typescript是直接移除TypeScript,轉為JS,這使得它的編譯速度飛快。
並且只需要管理Babel一個編譯器就行了,因為我將腳手架中的typescript庫卸載後,依然可以完美運行。
而且重要的是你寫的TypeScript不會再進行類型檢測,使得你改動代碼後中斷運行的頁面。
所以,檢測呢?
我寫TypeScript就是用來搞類型檢測的啊,你安裝了TypeScript,寫了TS代碼然後再用@babel/preset-typescript移除不是多此一舉嗎?
不,並不是多此一舉。
還記得前面那篇譯文嗎?
它的方案是使用ESLint,用@typescript-eslint配置ESLint來達到檢測的目的。
而我們的方案呢?
我們是高貴的VSCode玩家,咱們自帶TS檢測,所以這一步咱們可以略過。
一些缺陷
上方譯文中提到了此方案的以下四個缺陷:
- Namespace語法不推薦,改用標準的 ES6 module(import/export)。
- 不支持
x 語法轉換類型,改用x as newtype。 - const 枚舉
- 歷史遺留風格的 import/export 語法。比如:import foo = require(...) 和 export = foo。
第1條和第4條不用,而且已經過時了。
第2條缺陷改一下語法就好了,這個語法會直接提示語法報錯,很好改,問題不大。
第3條缺陷已經沒有了,親測可用。
替換步驟
要使用@babel/preset-typescript,務必確保你是Babel7+。
如果不是Babel7+用戶,可以考慮運行下麵的兩條命令升級:
npm install babel-upgrade -g
babel-upgrade --write
然後我們安裝:
npm i --save @babel/preset-typescript
然後將之前在webpack中配置解析tsx的部分去掉,改為:
module: {
rules: [
//...
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
}
}
//...
]
}
Ant Design的按需載入
必須要把這個東西單獨拎出來說,太坑了。
之前的方案咱們使用的是ts-import-plugin來處理的。
所以下意識我覺得這個地方會很麻煩,網上搜各種方案。
然而必然是沒有答案的,要麼就是ts-import-plugin,要麼就是和create-react-app結合在一起的那種。
實際上咱們只需要升級一下babel-plugin-import到最新就可以了。
我之前就是因為babel-plugin-import版本太低,導致只對js文件有效,對ts文件無效。
然後配置一下babel-plugin-import即可:
module: {
rules: [
//...
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
],
plugins: [
['import', { libraryName: 'antd', style: 'css' }], // `style: true` 會載入 less 文件
],
}
}
//...
]
}
總結
這次升級花的最多時間就在ant-design的按需載入上,其它的東西其實都很好配置,無非是知識點零散些罷了。
說實話很感謝那篇譯文,但是讀起來還是覺得有點生硬。
所以另外一個花時間的點,就是如何有條理地把為什麼升級闡述清楚。
這裡再附上參考項目:腳手架項目。