React Typescript Babel Eslint Prettier
2025年01月03日
一、认识
搭建一个 生产可用的 React
项目,不仅需要关注代码质量、规范、可维护性和性能,还要考虑到项目的可扩展性、优化和团队协作。在基于 React
、TypeScript
、Babel
、ESLint
、Prettier
、Webpack
的前提下,以下是一个具有高标准、高规范的 React
项目的搭建流程和最佳实践。
-
React + TypeScript
:使用React
和TypeScript
开发,享受类型安全和更好的开发体验。 -
Babel
:编译JavaScript
和TypeScript
,确保兼容性。 -
ESLint
:对代码进行静态分析,确保代码规范,集成Git hook
实现提交前检测。 -
Prettier
:自动格式化代码,确保代码风格一致。 -
Webpack
:打包工具,用于构建生产版本和开发环境。 -
Commit
规范:使用commitlint
和husky
确保提交信息符合规范。
二、初始化
首先,初始化一个新的项目目录,并使用 npm
或 yarn
或者 pnpm
初始化项目。
mkdir react-ts-webpack
cd react-ts-webpack
npm init -y
三、项目结构
四、安装依赖
# 安装 React 和 React DOM
npm install react react-dom
# 安装 TypeScript 和类型声明
npm install typescript @types/react @types/react-dom
# 安装 Webpack 及相关插件
npm install webpack webpack-cli webpack-dev-server html-webpack-plugin webpack-merge
# 安装 Babel 和 Babel 插件
npm install babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
# 安装开发相关工具
npm install --save-dev ts-loader source-map-loader clean-webpack-plugin mini-css-extract-plugin css-loader sass-loader sass style-loader
# 安装 ESLint 和 Prettier 相关依赖
npm install eslint prettier eslint-plugin-react eslint-plugin-react-hooks eslint-config-prettier eslint-plugin-prettier eslint-webpack-plugin
# 安装用于Git提交检测的工具
npm install --save-dev husky lint-staged commitlint @commitlint/config-conventional
五、文件配置
5.1 配置 Babel
在项目根目录下创建 .babelrc
文件,设置 Babel
配置。
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
"react-refresh/babel"
]
}
5.2 配置 ESLint
在项目根目录下创建 .eslintrc.json
配置文件:
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"jsx": true
},
"plugins": [
"react",
"react-hooks",
"@typescript-eslint",
"prettier"
],
"rules": {
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"prettier/prettier": "error",
"@typescript-eslint/explicit-module-boundary-types": "off"
}
}
5.3 配置 Webpack
创建 webpack.common.js
,webpack.dev.js
和 webpack.prod.js
配置文件。
webpack.common.js
— 公共配置
const path = require('path');
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(scss|sass)$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(png|jpg|gif|svg)$/,
use: ['file-loader'],
}
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html',
favicon: './public/favicon.ico',
}),
new ESLintPlugin({ // 配置 ESLint 插件
extensions: ['ts', 'tsx'], // 只检查 TypeScript 文件
exclude: 'node_modules', // 排除 node_modules
failOnError: true, // 当 ESLint 检查失败时,构建失败
}),
],
};
webpack.dev.js
— 开发环境配置
const path = require('path');
const { merge } = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
module.exports = merge(commonConfig, {
mode: 'development',
devtool: 'cheap-module-source-map',
devServer: {
contentBase: path.resolve(__dirname, 'dist'),
hot: true,
open: true,
port: 3000,
},
plugins: [
new ReactRefreshWebpackPlugin(),
],
});
webpack.prod.js
— 生产环境配置
const { merge } = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = merge(commonConfig, {
mode: 'production',
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [
new TerserWebpackPlugin(),
new CssMinimizerPlugin(),
],
splitChunks: {
chunks: 'all',
},
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
}),
],
});
5.4 配置 Prettier
创建 .prettierrc
文件:
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"tabWidth": 2,
"printWidth": 80
}
5.5 配置 TypeScript
在项目根目录下创建 tsconfig.json
文件。
{
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"lib": ["DOM", "ESNext"],
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"moduleResolution": "node",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"noEmitOnError": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
5.6 配置 package.json
在 package.json
中添加以下命令:
{
"scripts": {
"start": "webpack serve --mode development",
"build": "webpack --mode production",
"lint": "eslint src/**/*.{ts,tsx}",
"format": "prettier --write src/**/*.{ts,tsx}",
"test": "echo \"Write tests!\" && exit 0"
}
}
配置 package.json
文件中的 commitlint
和 lint-staged
配置:
"lint-staged": {
"src/**/*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"commitlint": {
"extends": ["@commitlint/config-conventional"]
}
5.7 配置 global.d.ts
declare module "*.css" {
const content: { [className: string]: string };
export default content;
}
declare module "*.module.css" {
const content: { [className: string]: string };
export default content;
}
declare module "*.scss" {
const content: { [className: string]: string };
export default content;
}
declare module "*.module.scss" {
const content: { [className: string]: string };
export default content;
}
declare module "*.less" {
const content: { [className: string]: string };
export default content;
}
declare module "*.module.less" {
const content: { [className: string]: string };
export default content;
}