背景
開門見山,我的項目是基於react的,希望在新的功能上使用Typescript,並逐步修改之前的代碼,所以我需要同時支持(TS|TSX
)和(JS|JSX
)。你可能不需要同時支持TS和JS,本文會同時給出兩種情況的解決要點。
方法
Typescript通常是要轉換
成Javascript來執行的,這是一種語法轉換。Typescript本身具有編譯器,可以根據tsconfig.json
來進行編譯。當我們使用Webpack進行打包編譯的時候,我們需要相應的loader
,Webpack官網推薦了ts-loader
。而社區也有awesome-typescript-loader
,它針對ts-loader
做了一些優化,將類型檢查和代碼生成分離到單獨進程中,另外,它還可以直接集成babel
。最後祭出大殺器,Babel本身是非常強大的語法轉換工具,在babel7之後開始支持typescript。
綜上,目前轉換Typescript有三種常用的方式:
- 經典的
ts-loader
awesome-typescript-loader
babel7
之後已經支持的@babel/preset-typescript
ts-loader
1. 支持JS|JSX|TS|TSX
-
首先我們需要配置tsconfig.json,以下是關鍵配置(我省略掉了其他配置):
{ "compilerOptions": { "moduleResolution": "node", "module": "ESNEXT", "target": "es6", "jsx": "preserve", "esModuleInterop": true } }
ts-loader
配合babel-loader
的時候jsx
必須是preserve
。 -
然後配置webpack的loader
{ test: /\.(js|jsx)$/, exclude: /node-modules/, loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false } }, { test: /\.(ts|tsx)$/, exclude: /node-modules/, use: [ 'babel-loader', 'ts-loader' ] }
2. 僅支持TS|TSX
- tsconfig.json關鍵配置
{ "compilerOptions": { "module": "commonjs", "target": "es5", "jsx": "react", "esModuleInterop": true } }
- webpack中只需要配置ts-loader即可
{ test: /\.(ts|tsx)$/, exclude: /node-modules/, loader: 'ts-loader' }
awsome-typescript-loader
1. 支持JS|JSX|TS|TSX
- tsconfig配置和ts-loader一樣。
{ "compilerOptions": { "moduleResolution": "node", "module": "ESNEXT", "target": "es6", "jsx": "preserve", "esModuleInterop": true } }
- babel配置(這裏只展示presets部分)
"presets": [ "@babel/preset-env", "@babel/preset-react" ],
- webpack配置
{ test: /\.(js|jsx)$/, exclude: /node-modules/, loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false } }, { test: /\.(ts|tsx)$/, exclude: /node-modules/, use: [ { loader: 'awesome-typescript-loader', options: { useBabel: true, babelCore: '@babel/core' } } ] }
2. 僅支持TS|TSX
- tsconfig的配置和ts-loader的方式一樣。
{ "compilerOptions": { "module": "commonjs", "target": "es5", "jsx": "react", "esModuleInterop": true } }
- webpack配置
{ test: /\.(ts|tsx)$/, exclude: /node-modules/, loader: 'awesome-typescript-loader' }
babel-loader
如果你是用的是babel7+
,這種方案通用於JS|JSX|TS|TSX
,如果你不需要JS|JSX,也可以使用這種方案,無需更改配置。webpack在打包時只需要運行babel編譯器即可,不會出現與typescript編譯器搶佔資源的情況。
- 修改babel配置,這裏我用的是
.babelrc
,這裏只展示presets
部分,presets是自下而上執行的,所以第一步就會經過typescript的轉換。"presets": [ "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript" ]
- webpack配置
{ test: /\.(js|jsx|ts|tsx)$/, exclude: /node-modules/, loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false } },