目录
TypeScript & React
TS开发环境的搭建
tsconfig.json
webpack.config.js
babel.config.js
.eslintrc.js
差异:
{
"compilerOptions": {
"outDir": "./",
"target": "esnext",
"allowJs": true,
"noEmit": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"experimentalDecorators": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"jsx": "react",
"sourceMap": true,
"pretty": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
},
},
"typeRoots": [
"node_modules/@types",
"src/types"
],
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist",
"**/*.spec.ts"
],
}
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const devPort = parseInt(process.env.port, 10) || 8065;
module.exports = (env) => {
const publicPath = '';
const buildPath = './build';
const config = {
mode: env.prod ? 'production' : 'development',
entry: {
app: path.join(__dirname, './src/index.tsx'),
},
devServer: {
historyApiFallback: true,
contentBase: path.join(__dirname, buildPath),
port: devPort,
hot: true,
disableHostCheck: true,
},
output: {
path: path.join(__dirname, buildPath),
pathinfo: true,
filename: env.prod || env.test ? '[name].[hash].js' : '[name].js',
publicPath: `${publicPath}/`,
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
},
module: {
rules: [
{
test: /(\.ts|\.tsx)$/,
exclude: /(node_modules)/,
use: [
{
// 新增支持ts编译
loader: 'babel-loader',
},
],
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
},
],
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.ENV': env.dev,
}),
new webpack.LoaderOptionsPlugin({ options: {} }),
new HtmlWebpackPlugin({
title: 'React & TypeScript',
template: path.join(__dirname, './src/view/index.html'),
inject: true,
hash: false,
filename: 'index.html',
publicPath: '',
}),
],
devtool: 'source-map',
watch: true,
};
return config;
};
module.exports = (api) => {
api.cache(true);
const plugins = [
require('@babel/plugin-transform-runtime'),
[require('@babel/plugin-proposal-decorators'), { legacy: true }],
[require('@babel/plugin-proposal-class-properties'), { loose: true }],
require('@babel/plugin-proposal-export-default-from'),
// require("react-hot-loader/babel"),
];
const presets = [
[
require('@babel/preset-env'),
{
modules: false,
useBuiltIns: 'usage',
corejs: { version: 3, proposals: true },
},
],
[require('@babel/preset-react')],
// 插件将ts、tsx转译为js
[require('@babel/preset-typescript')],
];
return {
plugins,
presets,
};
};
const path = require('path');
module.exports = {
root: true,
// 新增ts的编译
parser: '@typescript-eslint/parser',
extends: [
'airbnb-typescript',
'airbnb/hooks',
// 新增tslint推荐
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
// 新增@typescript-eslint配置项
plugins: ['@typescript-eslint', 'jsx-a11y', 'import', 'react-hooks'],
parserOptions: {
ecmaVersion: 2019,
sourceType: 'module',
// 关联ts配置文境
project: './tsconfig.json',
},
settings: {
'import/resolver': {
webpack: {
config: {
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
},
},
},
},
},
env: {
browser: true,
},
globals: {
window: true,
ENV: true,
},
rules: {
indent: ['error', 2],
quotes: ['error', 'single'],
semi: ['error', 'always'],
'no-console': 1,
'arrow-parens': 0,
'no-shadow': 'off',
'react/jsx-filename-extension': 'off',
'react/jsx-props-no-spreading': 0,
// 自定义规则
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 0,
'import/extensions': [
'error',
'ignorePackages',
{
ts: 'never',
tsx: 'never',
js: 'never',
jsx: 'never',
json: 'never',
},
],
'import/no-unresolved': [2, { commonjs: true, amd: true }],
},
};