JavaScript 項目遷移到 TypeScript 步驟以及遇到的問題

本文講述瞭如何將 JavaScript 項目遷移到 TypeScript 上,以及如何在項目中添加 TypeScript 配置,編寫 TypeScript 代碼。javascript

1、插件安裝

安裝項目所需插件,通常對應的模塊都會有對應的 @types 插件可使用。不知道的是否須要安裝對應的 @types 插件的話,能夠到 TypeSearch 進行查找。java

# 安裝項目中使用的插件
$ 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
複製代碼

2、添加 tsconfig.json 配置文件

在項目根目錄下添加 tsconfig.json 配置文件。tsconfig.json文件中指定了用來編譯這個項目的根文件和編譯選項。node

tsconfig.jsonreact

{
  "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 文件,用來在項目生產環境配置中使用。webpack

tsconfig.prod.jsongit

{
  "extends": "./tsconfig.json"
}
複製代碼

這裏直接繼承類 tsconfig.json 文件中的內容。也能夠添加一些不一樣的配置。es6


3、爲項目添加 TsLint 配置文件

在項目根目錄下添加 tslint.json 文件。tslint.json 中配置了開發過程當中的規則。github

tslint.jsonweb

{
  "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:繼承了哪些規則
  • defaultSeverityTsLint 嚴重性等級,能夠是 warning 或是 error
  • rules:配置規則,能夠修改一些默認的 TsLint 規則
  • linterOptions.exclude:排除掉不須要進行 TsLint 檢查的文件
  • 更多 TsLint 的規則配置能夠參考 TsLint

4、在 webpack 配置文件中添加 TypeScript 配置

在 webpack 開發環境中添加配置

使用插件

在 webpack 配置文件中使用插件:typescript

  • 在 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') })
        ],
        ...
    }
}
複製代碼

5、遇到的問題

裝飾器使用問題

裝飾器使用問題
原本配置好的裝飾器,使用的好好的,配置完 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 文件內部報錯問題
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 文件中我配置的 rootDirsrc 目錄,可是在 exclude 屬性裏,我沒有將 src 的同級目錄 config 給排除,因此就會提示這個錯誤,在 tsconfig.json 中添加配置便可:

tsconfig.json

{
  "exclude": [
    ...
    "config"
  ],
}
複製代碼

出現相似的問題,提示哪一個目錄不在 rootDir 目錄下,就將哪一個目錄添加到 exclude 屬性裏。

webpack 中配置的別名,在 ts 文件中不識別的問題

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 中就可能會出現兩個問題:

    1. 若是 tsconfig.json 文件中 compilerOptions 屬性下沒有配置 baseUrl 屬性,就會提示 Found no baseUrl in tsconfig.json, not applying tsconfig-paths-webpack-plugin
    1. 而後配置 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 代碼了。

若是你們在項目遷移的過程當中若是遇到了別的問題,也能夠拿出來交流探討一下。

相關文章
相關標籤/搜索