最近考慮到老項目代碼的可維護性以及穩定性,決定引入ts作規範檢測。由於介紹的東西比較基礎,若是介紹的不對,麻煩指正。css
TypeScript 是 JavaScript 的一個超集,主要提供了類型系統和對 ES6 的支持。網上關於ts的學習資料不少,這裏不作詳細介紹。可參考的學習網站:html
cnpm i typescript ts-loader --save-dev
複製代碼
在項目根目錄下添加 tsconfig.json 文件。tsconfig.json 文件用來指定ts的編譯選項。配置可參考:typescript.bootcss.com/tsconfig-js…react
項目工程 tsconfig.json 文件配置以下:(僅作參考)webpack
{ "compilerOptions": { "baseUrl": ".", "experimentalDecorators": true, "emitDecoratorMetadata": true, "noEmitOnError": true, "target": "esnext", "module": "esnext", "strict": true, "allowJs": true, "noEmit": false, "noImplicitThis": true, "esModuleInterop": true, "sourceMap": true, "moduleResolution": "node" }, "include": [ "src/**/*", "types" ], "exclude": [ "node_modules", "build" ] } 複製代碼
webpack.config.js 打包文件修改,新增對.ts文件的打包配置。ios
module.exports = { entry: { app: ['@babel/polyfill', './src/main.ts'] } } 複製代碼
tsx針對react項目文件的支持,由於咱們的工程基於vue開發,支持.ts文件就能夠了。web
module.exports = { resolve: { extensions: ['.js', '.vue', '.json', '.css', '.ts'] } } 複製代碼
使用ts-loader來轉換ts文件。vue-router
module.exports = { module: { rules: [ { test: /\.ts?$/, loader: 'ts-loader', exclude: /node_modules/, options: { appendTsSuffixTo: [/\.vue$/], } } ] } } 複製代碼
cnpm i @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-typescript eslint-plugin-typescript --save-dev
複製代碼
@typescript-eslint/parser ts文件解析器typescript
@typescript-eslint/eslint-plugin 版本號須要與@typescript-eslint/parser的版本一致,解析器相關的配置選項
eslint-config-typescript 針對ts項目配置的eslint檢測規範
.eslintrc配置文件修改,支持對ts的文件的校驗。通過屢次調整,咱們工程的 .eslintrc 配置文件以下:
{ "parserOptions": { "parser": "@typescript-eslint/parser", "project": "./tsconfig.json", "extraFileExtensions": [".vue"], "ecmaVersion": 2017, "sourceType": "module", "ecmaFeatures": { "modules": true } }, "env": { "jest": true, "browser": true }, "settings": { "import/resolver": { "node": { "extensions": [".js", ".jsx", ".ts", ".tsx", ".eslintrc"] }, "webpack": { "config": { "resolve": { "alias": { "src": "src" } } } } } }, "plugins": [ "vue", "babel", "@typescript-eslint" ], "extends": [ "eslint:recommended", "plugin:vue/base", "typescript", "standard" ], "rules": { "func-names": 0, "one-var": [1, "never"], "prefer-const": 1, "no-unused-expressions": 1, "new-cap": 2, "prefer-arrow-callback": 2, "arrow-body-style": 0, "max-len": [ 1, { "code": 200, "ignoreStrings": true, "ignoreUrls": true, "ignoreRegExpLiterals": true } ], "consistent-return": "off", "default-case": 2, "prefer-rest-params": 2, "no-script-url": 0, "no-console": [ 2, { "allow": ["info", "error", "warn", "log"] } ], "no-duplicate-imports": 2, "newline-per-chained-call": 2, "no-underscore-dangle": 2, "eol-last": 2, "no-useless-rename": 2, "class-methods-use-this": 0, "prefer-destructuring": 0, "no-unused-vars": 0, "@typescript-eslint/no-unused-vars": 1, "no-plusplus": 0, "import/prefer-default-export": 0, "import/no-dynamic-require": 2, "@typescript-eslint/no-var-requires": 2, "no-use-before-define": [ "error", { "functions": false } ], "@typescript-eslint/no-use-before-define": 0, "@typescript-eslint/explicit-function-return-type": 0, "@typescript-eslint/interface-name-prefix": 0, "no-invalid-this": 0, "babel/no-invalid-this": 2, "no-await-in-loop": "off", "array-callback-return": "off", "no-restricted-syntax": "off", "@typescript-eslint/no-explicit-any": 0, "import/no-extraneous-dependencies": 0, "import/no-unresolved": 0, "@typescript-eslint/explicit-member-accessibility": 0, "@typescript-eslint/no-object-literal-type-assertion": 0, "no-param-reassign": [ 2, { "props": false } ], "generator-star-spacing": "off", "indent": [2, 4, { "SwitchCase": 1 }], "eqeqeq": 0, "no-else-return": 2, "arrow-parens": 0, "space-before-function-paren": ["error", "never"], "comma-dangle": [2, "never"], "semi": [2, "always"] } } 複製代碼
注意"extends": ["plugin:vue/base"], 只能選擇vue/base,不能用vue/recommend。否則會有規則衝突。
項目配置好後,開始對老代碼進行改造,來支持ts的語法檢測。
項目中總會依賴一些資源包,或是本身開發的一些組件,這些文件須要補充聲明文件,聲明文件就是將多個聲明語句放在一塊兒,這些聲明文件可統一放到一個目錄裏。這個目錄須要包含在 tsconfig.json 文件的include裏。
ms工程在根目錄下新建 types 目錄,目前包含 vue.d.ts, request.d.ts, dialog.d.ts, base.d.ts 等文件。
須要在ts環境下識別vue文件,須要添加 vue.d.ts 全局聲明文件,例子以下:
import VueRouter, { Route } from 'vue-router'; import RequestAxios from './request'; declare module '*.vue' { import Vue from 'vue'; export default Vue; } declare module 'vue/types/vue' { interface Vue { $router: VueRouter; $route: Route; $request: RequestAxios; .... } } 複製代碼
vue文件的改造,只改造js部分,代碼大體修改以下:
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'; @Component({ components: { .... } }) export default class MyComponent extends Vue { // prop @Prop({ default: () => {} }) readonly pageInfo !: any // data private showAnimation : boolean = true; // watch @Watch('showModuleIndex') onShowModuleIndexChanged(newValue: any) { this.$emit('input', newValue); } // computed get list() { const { page, cityList } = this; return page.cityList.split(',').map( cityId => cityList.find(c => String(c.id) === cityId) ); } // mounted private mounted() :void { this.initEditor(); } // methods private initEditor() :void { .... } } </script> 複製代碼
將文件後綴名更改成.ts,而後加上類型就能夠了。
大部分都是eslint校驗時的報錯,按照提示修復就能夠了。
參考連接: www.yodfz.com/detail/43/w…
"vue/html-indent": [2, 4] eslint這條規則去掉
"plugin:vue/base"與"plugin:vue/recommend"的區別
...
項目改造過程當中,大部分時間都是在查配置兼容問題,配置這塊解決了,改造起來速度仍是挺快的。雖然前期會有一些改形成本,可是長遠來看,仍是有意義的。畢竟不少代碼類型上的問題在開發階段就能夠暴露,不用等到運行時才發現了。