准备工作
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
创建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
,以兼容老式模块,统一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
类型检测。
继续修改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时可以不用
// 否则建议使用,以方便发现错误
new ForkTsCheckerNotifierWebpackPlugin({
title: 'TypeScript',
excludeWarnings: true,
skipSuccessful: true,
}),
]
};
Step 5 Prettier
在项目根目录下创建配置文件.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
创建配置文件
在项目根目录下创建.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相关校验规则
"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
就可以了。