跳到主要内容

React Typescript Babel Eslint Prettier

2025年01月03日
柏拉文
越努力,越幸运

一、认识


搭建一个 生产可用的 React 项目,不仅需要关注代码质量、规范、可维护性和性能,还要考虑到项目的可扩展性、优化和团队协作。在基于 ReactTypeScriptBabelESLintPrettierWebpack 的前提下,以下是一个具有高标准、高规范的 React 项目的搭建流程和最佳实践。

  1. React + TypeScript:使用 ReactTypeScript 开发,享受类型安全和更好的开发体验。

  2. Babel:编译 JavaScriptTypeScript,确保兼容性。

  3. ESLint:对代码进行静态分析,确保代码规范,集成 Git hook 实现提交前检测。

  4. Prettier:自动格式化代码,确保代码风格一致。

  5. Webpack:打包工具,用于构建生产版本和开发环境。

  6. Commit 规范:使用 commitlinthusky 确保提交信息符合规范。

二、初始化


首先,初始化一个新的项目目录,并使用 npmyarn 或者 pnpm 初始化项目。

mkdir react-ts-webpack
cd react-ts-webpack
npm init -y

三、项目结构


四、安装依赖


# 安装 ReactReact 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

# 安装 BabelBabel 插件
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

# 安装 ESLintPrettier 相关依赖
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.jswebpack.dev.jswebpack.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 文件中的 commitlintlint-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;
}

六、项目构建