【23-08】最新从0-1搭建 react 18 + antd 5 + vite 4.4 + typescript 5 + husky 企业级项目详细流程

在构建企业级项目时,合理的项目结构、清晰的代码组织和规范的开发流程非常重要,本文将带您深入了解从零开始搭建 React 18 企业级项目的详细过程。我们将结合 Ant Design 5、Vite 4.4、TypeScript 4.5 以及众多必备的开发工具如 Husky、ESLint、Stylelint 和 Commitizen,以确保您在开发过程中拥有一套完整的工具链,帮助你快速构建现代化的 Web 应用。

初始化项目

打开终端,cd到你要存储该项目的文件夹下,使用 vite 提供的 react 模板创建项目

执行命令

bash 复制代码
pnpm create vite@latest your-project-name -- --template react

your-project-name替换为你的项目名,执行完毕后进入项目,运行

bash 复制代码
pnpm run dev

你的项目已经初始化好了,点击即可访问

bash 复制代码
  VITE v4.4.7  ready in 805 ms

   Local:   http://127.0.0.1:5173/
   Network: use --host to expose
   press h to show help

校验工具

接下来我们一步步来添加检验工具

Eslint

初始化好的项目里是自带eslint校验的,大家可以根据自己的习惯进行更改或直接保持原样。

假设我们要替换自己习惯的规范,例如 eslint-config-mature ,该规范包集eslint、stylelint、prettier规范于一身,集各大厂百家之长,免去安装各种包的繁杂操作,用起来很方便

bash 复制代码
pnpm install eslint eslint-config-mature eslint-plugin-import --save-dev

// 把prettier也装上
pnpm install prettier eslint-plugin-prettier --save-dev

修改后的eslintrc文件

js 复制代码
module.exports = {
  root: true,
  env: { browser: true, es2023: true },
  extends: [
    'plugin:react/recommended',
    'eslint-config-mature/prettier', // 主要用于格式化模板,优先级应更低
    'eslint-config-mature',
    'eslint-config-mature/ts',
    'plugin:react-hooks/recommended',
  ],
  ignorePatterns: ['dist', '.eslintrc.cjs'],
  parser: '@typescript-eslint/parser',
  plugins: ['react-refresh'],
  rules: {
    'react-refresh/only-export-components': [
      'warn',
      { allowConstantExport: true },
    ],
    "react/react-in-jsx-scope": 0,
    "react/display-name": 0,
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  }
}

Stylelint

安装相关包,如果使用 scss 的话需要额外安装 ylelint-scss stcss-scss

bash 复制代码
pnpm add stylelint stylelint-config-recess-order stylelint-scss postcss-scss -D

stylelintrc 配置

js 复制代码
module.exports = {
  extends: [
    'stylelint-config-recess-order',
    'eslint-config-mature/stylelint/style',
    'eslint-config-mature/stylelint/style-scss',
  ],
  ignoreFiles: [
    '**/*.js',
    '**/*.cjs',
    '**/*.jsx',
    '**/*.tsx',
    '**/*.ts',
    "node_modules/",
    "dist/",
    "public/",
    "docs/",
  ],
  overrides: [
    {
      files: ["**/*.scss"],
      customSyntax: "postcss-scss", // 支持 scss
    },
  ],
  rules: {

  },
};

手动lint

package.json 的 scripts 里添加

bash 复制代码
    "lint": "yarn lint:eslint && yarn lint:stylelint",
    "lint:eslint": "eslint -c .eslintrc.cjs --ext .ts,.tsx,.js src --fix --report-unused-disable-directives --max-warnings 0",
    "lint:stylelint": "stylelint src/**/*.{html,css,scss} --fix --max-warnings 0",

运行 npm run lint 即可进行代码检查,如果你不想自动修复问题,可以把 --fix 去掉

推荐安装 eslint 和 stylelint 的 vscode 插件,可以实时提示并支持保存自动修复等功能。

husky

每次手动去运行命令检查太麻烦了,而且也很考验小伙伴的自觉性。

husky 是一个 Git 钩子(Git hooks)工具,它可以让你在 Git 事件发生时执行脚本,进行代码格式化、测试等操作。

常见的钩子

  • pre-commit:在执行 Git commit 命令之前触发,用于在提交代码前进行代码检查、格式化、测试等操作。
  • commit-msg:在提交消息(commit message)被创建后,但提交操作尚未完成之前触发,用于校验提交消息的格式和内容。
  • pre-push:在执行 Git push 命令之前触发,用于在推送代码前进行额外检查、测试等操作。

具体的使用步骤如下:

  1. 启用git 钩子 输入以下命令
bash 复制代码
pnpm pkg set scripts.prepare="husky install"

安装成功后会在 package.json 文件中 script 中生成命令

注意!如未自动生成需手动添加,将以下内容粘贴到 package.json 文件中

json 复制代码
// package.json
{
  "scripts": {
    "prepare": "husky install"
  }
}
  1. 执行如下代码,创建.husky目录,
bash 复制代码
pnpm run prepare 

执行成功后,项目中会生成一个 .husky 目录

  1. 添加命令到pre-commit 钩子

给 pre-commit 钩子添加 npx lint-staged 命令

bash 复制代码
npx husky add .husky/pre-commit "npx lint-staged"

lint-staged下面有详细介绍

lint-staged

lint-staged 可以让你在 Git 暂存(staged)区域中的文件上运行脚本,通常用于在提交前对代码进行格式化、静态检查等操作。

可以在项目中使用 lint-staged 配合 husky 钩子来执行针对暂存文件的脚本。

安装

bash 复制代码
pnpm add lint-staged -D 

package.json 文件中添加以下配置:

json 复制代码
  "lint-staged": {
    "src/**/*.{js,jsx,ts,tsx}": [
      "eslint --max-warnings 0"
    ],
    "src/**/*.{vue,less,postcss,css,scss}": [
      "stylelint --max-warnings 0"
    ]
  }

src/**/*.{js,ts,vue,tsx}为校验暂存区、指定目录下的文件类型,可以根据自己需要配置。

现在,在代码提交时就会自动执行 npx lint-staged 命令校验代码。

注意: 没有 --fix 参数,某些场景下自动修复会导致代码莫名其妙的bug,如果自动修复了你可能都不知道就合了

Commitizen 交互式提交

Commitizen 是一个用于规范化提交信息的工具,它能够帮助项目团队创建一致、易读的 Git 提交消息。通过使用 Commitizen,你可以确保提交信息按照预定义的规范格式化,方便后续查看和管理项目历史记录。

使用步骤:

  1. 运行以下命令,安装 Commitizen 和 Commitizen 适配器,比如 cz-conventional-changelog
bash 复制代码
pnpm add commitizen cz-conventional-changelog -D 
  1. 安装完成后,在 package.json 中添加一个 config.commitizen 的字段,并设置它的值为 cz-conventional-changelog
json 复制代码
"config": {
  "commitizen": {
    "path": "cz-conventional-changelog"
  }
}
  1. package.json 中的 scripts 字段中添加一个 commit 的命令。 示例如下:
json 复制代码
"scripts": {
  "commit": "git-cz"
}

执行 npm run commit 就可以进行交互式提交了。

commitlint

Commitizen是用来创建规范化提交的,如果项目成员没有使用 npm run commit 来提交,而是直接使用 git commit 的话还是有可能生成不规范提交的,所以还需要对最终的提交格式做一下校验,接下来添加提交格式校验,安装:

bash 复制代码
pnpm add commitlint -D

pnpm add @commitlint/config-conventional -D

// 添加 commit-msg 钩子
npx husky add .husky/commit-msg "npx commitlint --config .commitlintrc.cjs -E HUSKY_GIT_PARAMS"

如果你全局安装commitlint的话,可以不使用 npx 命令

创建配置文件 .commitlintrc.cjs

js 复制代码
/**
  feat:新增功能
  fix:修复bug
  docs:文档更新
  style: 代码格式修改
  refactor: 重构代码
  test: 测试用例修改
  build: 构建系统或包依赖修改
  ci: CI/CD 配置修改
  chore: 其他杂项修改
  revert: 回滚到上一版本
  perf: 性能优化
 */

module.exports = {

  // 使用 @commitlint/config-conventional规则
  extends: ['@commitlint/config-conventional'],

  // 定义验证规则
  rules: {

    // header最大94字符
    'header-max-length': [0, 'always', 94],

    // subject不能为空
    'subject-empty': [2, 'never'],

    // type的类型必须在指定范围内
    'type-enum': [
      2,
      'always',
      ['build', 'ci', 'chore', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test']
    ],

    // type不能为空
    "type-empty": [2, 'never'],

    // type必须小写
    "type-case": [2, "always", 'lowerCase'],

    // scope 不能为空
    "scope-empty": [0, "never"],

    // scope 必须小写
    "scope-case": [2, "always", "lowerCase"],

    // scope 不限制类型
    "scope-enum": [2, "always", []]

  }

};

一般建议保持 scope 强制和小写校验,但允许为空。这样可以鼓励使用 scope 来细分提交分类,但不强制要求。给予一定灵活性。

当 scope 非必填时,可以在提交时按需要填写,比如:

bash 复制代码
feat(home): add new parser
feat: add new feature

第一条指定了 scope,第二条未指定也能通过校验。

以上只是最基础的配置,可以根据团队实际情况自行更改,例如在提交信息时带上需求编号等。

另外提交类型中的 style 是一个通用的概念:

commit message 中的style表示的是不影响代码逻辑的修改,比如:

  • 代码空格
  • 格式化
  • 缺失分号
  • 代码注释

等与程序逻辑无关的修改。

另外一些文档也将style解释为代码风格的修改。

所以更准确的理解是"风格修改",而不是具体指CSS。

相比之下,如果是修改CSS样式表,建议使用下面两种类型:

  • feat:新增样式特性
  • fix:修复样式问题

如果修改的只是空格、格式化等与逻辑无关的变化,才使用style类型。当然,style也可以具体表示CSS修改,需要看团队自己的约定。

其他自定义校验

除了使用一些现成的npm包外,我们也可以自己写一些规则, husky 提供了钩子,我们在钩子里添加要执行的逻辑即可。

自定义 husky 校验-校验分支名

在校验代码格式之前,我们还想先看一下分支名是否符合要求,而不是让大家可以随心所欲,团队合作的项目尤其推荐哦。

假设我们要求的分支名格式为 feat_name_summary

在.husky 目录下新建目录custom,加入文件 branch-check.sh,文件内容为:

sh 复制代码
// .husky/custom/branch-check.sh

#!/bin/bash

# 获取当前所在的 Git 分支名
branch_name=$(git symbolic-ref --short HEAD)

# 分支名规则
pattern="^(fix|feat)_[a-z]{2,}_([a-zA-Z0-9]+)$"

# 正则不匹配就错误提示
if [[ ! $branch_name =~ $pattern ]]; then
  echo "Error: Invalid branch name. Branch name must match '(fix|feat)_(名字缩写如lyl等)_(具体改动如addcoupon)' format."
  exit 1
fi

分支名规则根据实际情况自行修改。

然后在pre-commit中加入这个脚本,在校验代码之前

bash 复制代码
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 校验分支
. "$(dirname -- "$0")/custom/branch-check.sh"

# 校验代码
npx lint-staged

完成后,以后再提交时就会校验一下分支是否符合规范

自定义 husky 校验-校验文件注释

为了项目更好的可读性和可维护性,在文件开头写一下注释,告诉别人这个文件是干嘛的是很有必要的,减少小伙伴的阅读和维护成本。

看下效果:

js 复制代码
/**
 * @description 封装表单相关行为
 */

// balabala

当然,还有自动生成文件注释的插件,还会额外带上什么 author 、 updateTime 之类的大家感兴趣可以自己研究。

那具体怎么搞?

依旧在 .husky 下新建文件 custom/desc-check.sh ,注意,我们只校验src目录下的文件

bash 复制代码
#!/bin/bash

# 获取 git 暂存区中 src 目录下所有 js、ts 和 tsx 文件
files=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^src/.*\.(js|ts|tsx)$')

# 遍历文件列表
for file in $files; do
  # 检查文件的前 10 行中是否包含针对整个文件的 @description 注释
  if ! head -n 10 "$file" | awk '/\/\*\*/,/\*\//{if(/@description/){found=1;exit}}END{exit !found}'; then
    # 如果不存在,则输出错误信息并退出脚本
    echo "Error: $file 必须在文件开头包含指定的jsdoc注释属性 @description xxx"
    exit 1
  fi
done

然后在pre-commit中加入这个脚本,在校验代码之前

bash 复制代码
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# 校验分支
. "$(dirname -- "$0")/custom/branch-check.sh"

# 校验文件注释
. "$(dirname -- "$0")/custom/desc-check.sh"

# 校验代码
npx lint-staged

ok,赶快试试吧!!!

除了在 husky 钩子上做文章外,还可以从 eslint 入手,让你实时得到校验反馈,而不只是提交时才警告。

自定义 eslint 校验-校验文件注释

卖个关子,敬请期待~

自动化

自动生成changelog

使用 Commitizen 后,可以结合标准的 changelog 生成器自动生成 changelog。

常用的工作流程是:

  1. 在 commit 时使用 Commitizen 生成符合规范的 commit message。

  2. 安装标准的 changelog 生成器,比如 conventional-changelog-cli:

    pnpm install conventional-changelog-cli -D

  3. 在 package.json 中添加生成 changelog 的 npm script:

json 复制代码
{
  "scripts": {
    "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0" 
  }  
}

这里使用 conventional-changelog 工具,格式为 angular,并读取 CHANGELOG.md 生成日志。

  1. 运行 npm run changelog 即可自动生成 changelog,如:
md 复制代码
## 1.0.0 (2023-07-03)

### Features

* add new feature xxx
* implement xxx

### Bug Fixes

* fix xxx bug

conventional-changelog 命令各个参数的含义如下:

  • -p:angular:使用angular预设的格式来解析commit消息
  • -i: CHANGELOG.md:指定读取和写入的日志文件名为 CHANGELOG.md
  • -s: 生成的日志中只包含提交的subject,去除body等详细信息
  • -r 0:最新版本开始生成日志,0表示当前版本

所以整条命令的意思是:

使用angular格式解析commit消息, 读取和写入 CHANGELOG.md 文件, 只包含subject信息, 从当前版本(0)开始重新生成完整日志。

conventional-changelog 还支持其他参数:

  • -v:生成的日志中包含commit的hash值
  • --release-count num:生成的日志中包含的发布版本数量
  • -c config.js:使用自定义的配置文件
  • -n output.md:写入自定义文件

等等。可以根据需要调整参数,生成符合项目需求的changelog。

修改 scripts 的 commit 后可以在提交后自动执行 npm run changelog,但是一般情况下你可能更需要手动执行。

json 复制代码
 "commit": "git-cz && npm run changelog",

自动更新版本号

该命令会自动生成版本号标签,并在package.json文件中更新版本号。

以下是npm version命令的常用选项和用法:

更新版本号选项:

npm version major: 增加主版本号(例如从1.2.3增加到2.0.0)。

npm version minor: 增加次版本号(例如从1.2.3增加到1.3.0)。

npm version patch: 增加修订版本号(例如从1.2.3增加到1.2.4)。

自定义版本号:

npm version 1.2.3: 将版本号设置为指定的版本号(例如1.2.3)。

预发布版本(Prerelease):

npm version premajor: 增加主版本号,并标记为预发布版本(例如从1.2.3增加到2.0.0-0)。

npm version preminor: 增加次版本号,并标记为预发布版本(例如从1.2.3增加到1.3.0-0)。

npm version prepatch: 增加修订版本号,并标记为预发布版本(例如从1.2.3增加到1.2.4-0)。

npm version prerelease: 将当前版本标记为预发布版本(例如从1.2.3增加到1.2.4-0)。

注意: 配合 husky 和 changelog 使用时一般情况下我们只需要更新版本号,而不需要自动创建标签,所以需要机上 --no-git-tag-version,这样就不会创建 Git 标签,从而避免触发 Husky 钩子。

bash 复制代码
npm version patch --no-git-tag-version

项目结构完善

使用 antd 组件库

csharp 复制代码
pnpm add antd

具体使用方法可直接参考官方文档 ant.design/docs/react/...

添加页面和组件

src下创建pages目录和components目录,用于存放页面和组件

添加路由

安装 react-router-dom

bash 复制代码
pnpm add react-router-dom

src 目录下新建 src/router/index.tsx

tsx 复制代码
/**
 * @description 路由配置
 */

import { createBrowserRouter } from 'react-router-dom';
import Index from '../pages/index/index';

const router = createBrowserRouter([
  {
    path: '/',
    Component: Index,
  },
]);
export default router;

App.tsx 修改一下

tsx 复制代码
/**
 * @description App容器
 */

import { RouterProvider } from 'react-router-dom';
import router from './router/index.tsx';
import './App.css';

function App() {
  return <RouterProvider router={router} />;
}

export default App;

App只添加了路由页面,你可以根据自己的需求添加Layout、Foter之类的组件。

项目配置

alias

js 复制代码
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  plugins: [react()],
})

server

js 复制代码
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  plugins: [react()],

  // 本地开发服务
  server: {
    host: true, // host设置为true才可以使用network的形式,以ip访问项目
    port: 5173, // 端口号
    // open: true, // 自动打开浏览器
    strictPort: true, // 如果端口已占用直接退出
    // 接口代理服务器
    proxy: {
      '/api': {
        target: 'http://jsonplaceholder.typicode.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },

})

总结

在这篇文章里,我们详细了解了从零开始搭建 React 企业级项目的步骤和流程,某些流程方法是在其他项目如Vue中也通用的。

地基已经搭好,剩下的大家可以自由发挥了,后续有任何更佳实践我会持续补充或更新,争取让这套模板永不落伍~

大家有什么建议或建议或想法欢迎评论区交流。

相关推荐
bin91535 分钟前
前端JavaScript导出excel,并用excel分析数据,使用SheetJS导出excel
前端·javascript·excel
Rattenking14 分钟前
node - npm常用命令和package.json说明
前端·npm·json
Easonmax14 分钟前
【HTML5】html5开篇基础(1)
前端·html·html5
For. tomorrow18 分钟前
Vue3中el-table组件实现分页,多选以及回显
前端·vue.js·elementui
布瑞泽的童话1 小时前
无需切换平台?TuneFree如何搜罗所有你爱的音乐
前端·vue.js·后端·开源
白鹭凡1 小时前
react 甘特图之旅
前端·react.js·甘特图
打野赵怀真1 小时前
你有看过vue的nextTick源码吗?
前端·javascript
2401_862886781 小时前
蓝禾,汤臣倍健,三七互娱,得物,顺丰,快手,游卡,oppo,康冠科技,途游游戏,埃科光电25秋招内推
前端·c++·python·算法·游戏
书中自有妍如玉1 小时前
layui时间选择器选择周 日月季度年
前端·javascript·layui