準備工作
git clone git@git.gaiaworks.cn:fe/thanos-template-public.git
git clone git@git.gaiaworks.cn:fe/walle-template-mocker.git
請大家先下載代碼,并將thanos-template-public切換至typescript-demo分支,安裝包,并運行
Step 1 升級
npx @pandora/upgrade
將組件庫升級至最新版本
Step 2 i18next
由于i18next包進行了大版本的升級,我們需要進行一些修改
reactI18nextModule => initReactI18next
translate => withTranslation
Step 3 tsconfig.json
創(chuàng)建tsconfig.json配置文件
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"strictNullChecks": false,
"module": "commonjs",
"target": "ESNext",
"jsx": "react",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowSyntheticDefaultImports": true, // 允許使用 ES2015 默認的 import 風格
"esModuleInterop": true, // 可調用的CommonJS模塊必須被做為默認導入,在已有的“老式”模塊模式之間保證最佳的互通性
"moduleResolution": "node",
"allowJs": true
},
"include": [
"./src/**/*"
],
"files": [
"./node_modules/tsx-control-statements/index.d.tsx",
"./node_modules/hrone-react/src/typings/index.d.ts"
]
}
這里,我們將tsx-control-statements和組件庫中的定義文件./node_modules/hrone-react/src/typings/index.d.ts加入files中。
并將esModuleInterop設為true,以兼容老式模塊,統(tǒng)一import風格為import XX from 'XX'。
你可以在這里了解更多關于tsconfig.json文件的說明。
Step 4 webpack
修改webpack.config.js文件
module.exports = {
context: __dirname,
entry: './src/index.tsx',
output: {
filename: 'bundle.js',
path: `${__dirname}/dist`
},
// Enable sourcemaps for debugging webpack's output.
devtool: "#source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: ['.js', '.ts', '.tsx']
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'babel-loader'.
{
test: /\.tsx?$/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-typescript'],
plugins: [['@babel/plugin-transform-typescript', { allowNamespaces: true }]],
},
include: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules/hrone-react'),
path.resolve(__dirname, '../../hrone-react/src'),
],
},
]
}
};
這里我們使用@babel/plugin-transform-typescript插件來處理TypeScript。
那么,TypeScript的類型檢測怎么辦呢?不是相當于廢了嗎?這里我們使用 fork-ts-checker-webpack-plugin來啟用TypeScript類型檢測。
繼續(xù)修改webpack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');
module.exports = {
// ...
plugins: [
new ForkTsCheckerWebpackPlugin({
// 將async設為false,可以阻止Webpack的emit以等待類型檢查器/linter,并向Webpack的編譯添加錯誤。
async: false
}),
// 將TypeScript類型檢查錯誤以彈框提示
// 如果fork-ts-checker-webpack-plugin的async為false時可以不用
// 否則建議使用,以方便發(fā)現錯誤
new ForkTsCheckerNotifierWebpackPlugin({
title: 'TypeScript',
excludeWarnings: true,
skipSuccessful: true,
}),
]
};
Step 5 Prettier
在項目根目錄下創(chuàng)建配置文件.prettierrc.js
module.exports = {
printWidth: 120,
tabWidth: 4,
singleQuote: true,
semi: true,
trailingComma: 'es5',
bracketSpacing: true,
jsxBracketSameLine: true,
arrowParens: 'always',
parser: 'typescript'
};
我們引入prettier來自動化格式代碼
Step 6 ESLint
創(chuàng)建配置文件
在項目根目錄下創(chuàng)建.eslintrc.js文件進行配置:
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
'plugin:react/recommended',
'plugin:jsx-control-statements/recommended',
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
'prettier/react'
],
"settings": {
"react": {
"version": "detect",
}
},
plugins: ['@typescript-eslint', 'react', 'jsx-control-statements', 'prettier'],
env: {
browser: true,
node: true,
es6: true,
mocha: true,
'jsx-control-statements/jsx-control-statements': true
},
globals: {
$: true
},
rules: {
'prettier/prettier': 1,
'@typescript-eslint/indent': ['error', 4, { VariableDeclarator: 4, SwitchCase: 1 }],
'@typescript-eslint/no-unused-vars': 0,
"@typescript-eslint/interface-name-prefix": 0,
"@typescript-eslint/explicit-member-accessibility": 0,
"@typescript-eslint/no-triple-slash-reference": 0,
"@typescript-eslint/ban-ts-ignore": 0,
"@typescript-eslint/no-this-alias": 0,
"@typescript-eslint/triple-slash-reference": ['error', { "path": "always", "types": "never", "lib": "never" }],
'no-console': ['warn', { allow: ['warn', 'error'] }],
"eqeqeq": ['warn', 'always'],
"prefer-const": ['error', {"destructuring": "all", "ignoreReadBeforeAssign": true}],
// React相關校驗規(guī)則
"react/jsx-indent": [2, 4],
"react/jsx-no-undef": [2, { allowGlobals: true }],
"jsx-control-statements/jsx-use-if-tag": 0
}
};
由于TypeScript 官方決定全面采用 ESLint,我們引入ESLint來進行代碼檢測。
強制校驗和格式化
安裝
npm install --save-dev husky lint-staged
修改 package.json
{
"name": "project-name",
// ...
"scripts": {
"eslint": "eslint --ext .tsx,.ts --fix ./src", // 需要在這里指定校驗.tsx,.ts后綴的文件
},
"husky": {
"hooks": {
// git commit 前強制代碼格式化和代碼校驗
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{ts,tsx}": [
"npm run eslint",
"prettier .prettierrc.js --write",
"git add"
]
}
}
Step 7 將代碼改為TypeScript
現在所有的配置都已做好,我們只要將我們的代碼一步步改為TypeScript就可以了。