本文講述瞭如何將 JavaScript 專案遷移到 TypeScript 上,以及如何在專案中新增 TypeScript 配置,編寫 TypeScript 程式碼。
一、外掛安裝
安裝專案所需外掛,一般對應的模組都會有對應的 @types 外掛可以使用。不知道的是否需要安裝對應的 @types 外掛的話,可以到 TypeSearch 進行查詢。
# 安裝專案中使用的外掛
$ npm install typescript ts-jest ts-loader @types/enzyme @types/jest @types/node @types/react @types/react-dom --save-dev
# 安裝 tslint 相關外掛
$ npm install tslint tslint-config-prettier tslint-react --save
# 安裝 webpack 中對 typescript 支援的外掛
$ npm install fork-ts-checker-webpack-plugin tsconfig-paths-webpack-plugin --save-dev
複製程式碼
二、新增 tsconfig.json 配置檔案
在專案根目錄下新增 tsconfig.json 配置檔案。tsconfig.json檔案中指定了用來編譯這個專案的根檔案和編譯選項。
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "build/dist",
"module": "commonjs",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"experimentalDecorators": true
},
"exclude": [
"config",
"public",
"node_modules",
"build",
"dist",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts",
"jest.config.js"
],
"types": [
"typePatches"
]
}
複製程式碼
再新增一個 tsconfig.prod.json 檔案,用來在專案生產環境配置中使用。
tsconfig.prod.json
{
"extends": "./tsconfig.json"
}
複製程式碼
這裡直接繼承類
tsconfig.json
檔案中的內容。也可以新增一些不同的配置。
三、為專案新增 TsLint 配置檔案
在專案根目錄下新增 tslint.json 檔案。tslint.json 中配置了開發過程中的規則。
tslint.json
{
"extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
"defaultSeverity": "warning",
"rules": {
// 物件屬性是否按照順序進行編寫
"object-literal-sort-keys": false,
// jsx 中是否允許使用 lambda 語法
"jsx-no-lambda": false,
// 引入模組是否需要按照字母順序
"ordered-imports": false,
// 不允許列印 console
"no-console": false,
// 不允許隱式的依賴模組,比如引用別名中的模組
"no-implicit-dependencies": false,
// 是否必須使用 === 取代 ==
"triple-equals": false,
// 物件成員是否需要按照順序進行編寫
"member-ordering": false
},
"linterOptions": {
"exclude": [
"config/**/*.js",
"webpack/**/*.js",
"node_modules/**/*.ts",
"coverage/lcov-report/*.js",
"src/**/*.js",
"src/**/*.jsx"
]
}
}
複製程式碼
extends
:繼承了哪些規則defaultSeverity
:TsLint
嚴重性等級,可以是warning
或是error
rules
:配置規則,可以修改一些預設的TsLint
規則linterOptions.exclude
:排除掉不需要進行TsLint
檢查的檔案- 更多
TsLint
的規則配置可以參考 TsLint
四、在 webpack 配置檔案中新增 TypeScript 配置
在 webpack 開發環境中新增配置
使用外掛
在 webpack 配置檔案中使用外掛:
- 在 plugins 中使用 ForkTsCheckerWebpackPlugin 外掛
- 注意: 在 resolve.plugin 中使用 TsconfigPathsPlugin 外掛
webpack.config.dev.js
...
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
...
module.exports = {
...
plugins: [
new ForkTsCheckerWebpackPlugin({
async: false,
watch: path.resolve(__dirname, '../src'),
tsconfig: path.resolve(__dirname, '../tsconfig.json'),
tslint: path.resolve(__dirname, '../tslint.json')
})
],
resolve: {
...
plugins: [
new TsconfigPathsPlugin({ configFile: path.resolve(__dirname, '../tsconfig.json') })
],
...
}
}
複製程式碼
在 webpack 中新增 TypeScript 的 rules 配置
使用 ts-loader
webpack.config.dev.js
...
module.exports = {
...
rules: [
{
test: /\.(ts|tsx)$/,
include: path.resolve(__dirname, '../src'),
use: [
{
loader: require.resolve('ts-loader'),
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true
}
}
]
},
...
],
...
}
複製程式碼
在 webpack 生產環境中新增配置
使用方式和上面 在 webpack 開發環境中新增配置
的方式一致。唯一不同的就是在使用外掛的時候,將 tsconfig.json
修改為 tsconfig.prod.json
webpack.prod.config.js
module.exports = {
...
plugins: [
new ForkTsCheckerWebpackPlugin({
async: false,
watch: path.resolve(__dirname, '../src'),
tsconfig: path.resolve(__dirname, '../tsconfig.prod.json'),
tslint: path.resolve(__dirname, '../tslint.json')
})
],
resolve: {
...
plugins: [
new TsconfigPathsPlugin({ configFile: path.resolve(__dirname, '../tsconfig.prod.json') })
],
...
}
}
複製程式碼
五、遇到的問題
裝飾器使用問題
本來配置好的裝飾器,使用的好好的,配置完TypeScript
之後,卻發現編輯器對應檔案裡面報紅線錯誤提示:
Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.
複製程式碼
解決辦法:在根目錄下的 tsconfig.json
檔案裡面新增對應配置即可
tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true
}
}
複製程式碼
生命週期提示紅線報錯問題
使用函式方式建立元件沒有問題,使用類的方式建立時,生命週期函式下面都會報紅線提示錯誤:Parsing error: Unexpected token
。
解決辦法:將 VSCode 設定中的配置項進行修改即可
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
// 下面這個對使用 ts 編寫的 React 元件進行 ESLint 的檔案檢查暫時先去掉
// "typescriptreact"
]
複製程式碼
tsconfig.json 檔案內部報錯問題
tsconfig.json 檔案內部報錯,第一行大括號那裡就出現錯誤,錯誤提示類似下面這種:'c:/xxx/config/dev.js' is not under 'rootDir' 'c:/xxx/src'. 'rootDir' is expected to contain all source files."
JSON schema for the TypeScript compiler's configuration file
複製程式碼
這裡我 tsconfig.json
檔案中我配置的 rootDir
是 src
目錄,但是在 exclude
屬性裡,我沒有將 src
的同級目錄 config
給排除,所以就會提示這個錯誤,在 tsconfig.json
中新增配置即可:
tsconfig.json
{
"exclude": [
...
"config"
],
}
複製程式碼
出現類似的問題,提示哪個目錄不在 rootDir 目錄下,就將哪個目錄新增到 exclude 屬性裡。
webpack 中配置的別名,在 ts 檔案中不識別的問題
在 webpack 中為部分目錄配置了別名,可以直接目錄,會自動到對應目錄下尋找模組,在 js 檔案中可以正常使用,但是在 ts 檔案中卻會報錯:Cannot find module 'utils/xxx'
。
解決辦法:這時需要在 tsconfig.json
檔案中單獨配置 paths
列表,對對應的路徑進行對映:
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"src/*": [
"src/*"
],
"utils/*": [
"src/utils/*"
]
}
},
...
}
複製程式碼
這樣啟動專案就不會再報錯,但是在 ts 檔案裡還是會有紅線報錯提醒,此時還需要在 tslint.json
檔案中新增 rules 配置:
tslint.json
{
...
"rules": {
"no-implicit-dependencies": false
}
...
}
複製程式碼
TsconfigPathsPlugin
外掛位置配置錯誤問題
TsconfigPathsPlugin 外掛要配置在webpack 配置檔案中 resolve 屬性下的 plugins 裡,否則的話會有問題。比如,直接放在了 webpack 配置檔案中的 plugins 中就可能會出現兩個問題:
-
- 如果
tsconfig.json
檔案中compilerOptions
屬性下沒有配置baseUrl
屬性,就會提示Found no baseUrl in tsconfig.json, not applying tsconfig-paths-webpack-plugin
- 如果
-
- 然後配置 baseUrl 屬性 ,配置好之後還可能會報錯:`tsconfig-paths-webpack-plugin: No file system found on resolver. Please make sure you've placed the plugin in the correct part of the configuration. This plugin is a resolver plugin and should be placed in the resolve part of the Webpack configuration.
注意:所以 tsconfig-paths-webpack-plugin 外掛的位置一定要放在 webpack 配置檔案中 resolve 屬性下的 plugins 裡。
寫在後面
這就是目前在專案中新增的部分 TypeScript
以及 TsLint
配置。此時已經可以在專案中正常編寫 TypeScript
程式碼了。
如果大家在專案遷移的過程中如果遇到了別的問題,也可以拿出來交流探討一下。