github 代码仓库: https://github.com/lbbbboom/react-code-standardization

环境准备

  • Node v20.18.0
  • Pnpm v9.12.3
  • Vite v6.0.3
  • VS Code 插件下载安装
    • ESLint
    • Stylelint
    • Prettier - Code formatter

Vite

vite 版本:6.0.3

使用 Vite 脚手架搭建项目

  1. pnpm create vite react-code-lint --template react-ts
  • 根目录下创建.vscode文件夹
    • extensions.json - 用于放vscode扩展插件
    • settings.json - 用于设置vscode的基本配置(项目配置会覆盖本地)
  • 删除.gitignore里的.vscode/*!.vscode/extensions.json
    • 目的:做到同一项目相同配置,保证风格统一

添加.vscode 文件夹内容

extensions.json

在.vscode 文件夹下创建extensions.json 文件,添加以下代码

  1. {
  2. "recommendations": [
  3. "dbaeumer.vscode-eslint",
  4. "esbenp.prettier-vscode",
  5. "stylelint.vscode-stylelint"
  6. ]
  7. }

settings.json

在.vscode 文件夹下创建 settings.json 文件,添加以下代码

  1. {
  2. "editor.codeActionsOnSave": {
  3. "source.fixAll": "explicit",
  4. "source.fixAll.eslint": "explicit",
  5. "source.fixAll.stylelint": "explicit"
  6. },
  7. "editor.formatOnSave": true,
  8. "editor.defaultFormatter": "esbenp.prettier-vscode",
  9. // 配置stylelint检查的文件类型范围
  10. "stylelint.validate": ["css", "scss", "sass"],
  11. "stylelint.enable": true,
  12. "css.validate": false,
  13. "scss.validate": false,
  14. "[scss]": {
  15. "editor.defaultFormatter": "esbenp.prettier-vscode"
  16. },
  17. "[css]": {
  18. "editor.defaultFormatter": "esbenp.prettier-vscode"
  19. }
  20. }

Eslint

版本:9.16.0 ➡️

Tip:v9 版本后使用的 eslint 文件命名为eslint.config.js,文件配置项也与之前有所不同

  1. // ...
  2. "scripts": {
  3. // ...
  4. "lint": "eslint .", // 检测eslint
  5. "lint:fix": "eslint . --fix" // 根据eslint规则修复
  6. }
  7. // ...

尝试输入命令:

  • pnpm lint检查规则
  • pnpm lint:fix修复规则

(一)新增排序插件

代码规范(2025年最新一版) - 图1

  • 安装依赖
  1. pnpm add eslint-plugin-import eslint-import-resolver-alias -D

eslint-plugin-import此插件旨在支持 ES2015+ (ES6+) 导入/导出语法的 linting,并防止文件路径和导入名称拼写错误的问题。ES2015+ 静态模块语法旨在提供的所有优点均已在编辑器中标记出来。

  • eslint.config.js文件中写入(eslint-plugin-import)
  1. // ...
  2. rules: {
  3. // ...
  4. "import/order": [
  5. "error",
  6. {
  7. // 对导入模块进行分组,分组排序规则如下
  8. groups: [
  9. "builtin", // 内置模块
  10. "external", // 外部模块
  11. "parent", // 父节点依赖
  12. "sibling", // 兄弟依赖
  13. "internal", // 内部引用
  14. "index", // index文件
  15. "type", //类型文件
  16. "unknown", // 未知依赖
  17. ],
  18. //通过路径自定义分组
  19. pathGroups: [
  20. {
  21. pattern: "@/**", // 把@开头的应用放在external分组后面
  22. group: "external",
  23. position: "after", // 定义组的位置,after、before
  24. },
  25. {
  26. pattern: "react*", // 在规定的组中选其一,index、sibling、parent、internal、external、builtin、object、type、unknown
  27. group: "builtin",
  28. position: "before",
  29. },
  30. ],
  31. // 是否开启独特组,用于区分自定义规则分组和其他规则分组
  32. distinctGroup: true,
  33. // 每个分组之间换行
  34. "newlines-between": "always",
  35. // 相同分组排列规则 按字母升序排序
  36. alphabetize: { order: "asc",caseInsensitive: true },
  37. },
  38. ],
  39. },

eslint-import-resolver-alias这是一个简单的 Node.js 模块导入解析插件eslint-plugin-import,支持原生 Node.js 模块解析、模块别名/映射和自定义文件扩展名。

  • eslint.config.js文件中写入(eslint-import-resolver-alias)
  1. // ...
  2. settings: {
  3. "import/resolver": {
  4. // eslint-import-resolver-alias 可以解决绝对路径的问题
  5. alias: {
  6. map: [
  7. ["", "./public"], // <-- this line
  8. ["@", "./src"], // <-- this line
  9. ],
  10. extensions: [".js", ".jsx", ".ts", ".tsx", ".svg"],
  11. },
  12. },
  13. },
  14. // ...

Prettier

版本:3.4.2 ➡️

Prettier:是一个代码格式化工具,支持多种编程语言。它可以自动格式化代码,使其符合一致的风格标准

  • 安装依赖
  1. pnpm add prettier eslint-config-prettier eslint-plugin-prettier -D
  • 添加.prettierrc.cjs文件,输入以下代码配置
  1. /** .prettierrc.js
  2. * 在VSCode中安装prettier插件 打开插件配置填写`.prettierrc.js` 将本文件作为其代码格式化规范
  3. * 在本文件中修改格式化规则,不会同时触发改变ESLint代码检查,所以每次修改本文件需要重启VSCode,ESLint检查才能同步代码格式化
  4. * 需要相应的代码格式化规范请自行查阅配置,下面为默认项目配置
  5. */
  6. module.exports = {
  7. // plugins: ["prettier-plugin-tailwindcss"],
  8. // 一行最多多少个字符
  9. printWidth: 90,
  10. // 指定每个缩进级别的空格数
  11. tabWidth: 2,
  12. // 使用制表符而不是空格缩进行
  13. useTabs: false,
  14. // 在语句末尾是否需要分号
  15. semi: true,
  16. // 是否使用单引号
  17. singleQuote: false,
  18. // 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
  19. quoteProps: "as-needed",
  20. // 在JSX中使用单引号而不是双引号
  21. jsxSingleQuote: false,
  22. // 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>",默认none
  23. trailingComma: "es5",
  24. // 在对象文字中的括号之间打印空格
  25. bracketSpacing: true,
  26. // jsx 标签的反尖括号需要换行
  27. jsxBracketSameLine: false,
  28. // 在单独的箭头函数参数周围包括括号 always:(x) => x \ avoid:x => x
  29. arrowParens: "always",
  30. // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
  31. rangeStart: 0,
  32. rangeEnd: Infinity,
  33. // 指定要使用的解析器,不需要写文件开头的 @prettier
  34. requirePragma: false,
  35. // 不需要自动在文件开头插入 @prettier
  36. insertPragma: false,
  37. // 使用默认的折行标准 always\never\preserve
  38. proseWrap: "preserve",
  39. // 指定HTML文件的全局空格敏感度 css\strict\ignore
  40. htmlWhitespaceSensitivity: "css",
  41. // Vue文件脚本和样式标签缩进
  42. vueIndentScriptAndStyle: false,
  43. //在 windows 操作系统中换行符通常是回车 (CR) 加换行分隔符 (LF),也就是回车换行(CRLF),
  44. //然而在 Linux 和 Unix 中只使用简单的换行分隔符 (LF)。
  45. //对应的控制字符为 "\n" (LF) 和 "\r\n"(CRLF)。auto意为保持现有的行尾
  46. // 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
  47. endOfLine: "auto",
  48. };

Tip:.prettierrc.cjs修改了相关格式化配置规则,ESLint代码不会立即去检查报红,Ctrl+Shift+P 打开命令面板,输入Restart Extension Host重启扩展宿主,等待加载一会儿,就能同步更新了。也可以暴力直接重启打开vscode软件。

eslint-config-prettier:这个配置是为了让 ESLint 和 Prettier 更好地协作。它关闭了所有可能与 Prettier 冲突的 ESLint 规则。使用这个配置可以确保 Prettier 的格式化规则优先于 ESLint 的风格规则,从而避免两者之间的冲突。

eslint-plugin-prettier:

这个插件将 Prettier 作为一个 ESLint 规则来运行。这样,你可以在 ESLint 的输出中看到 Prettier 的格式化问题。通过这种方式,你可以在使用 ESLint 时同时检查代码的格式化问题,并在开发过程中及时修复。

添加eslint-plugin-prettier 配置

eslint.config.js文件下添加以下代码,这样就会将prettier 与 eslint 融合在一起了

  1. import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
  2. export default tseslint.config(
  3. { ignores: ["dist"] },
  4. {
  5. // ...
  6. }
  7. eslintPluginPrettierRecommended
  8. );
  • 这时候使用 eslint修复的时候会读取 prettier 的配置进行修复代码

Stylelint

版本:16.11.0 ➡️

  • 安装相关依赖(使用Scss样式预处理器)
  1. pnpm add stylelint stylelint-scss stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-scss stylelint-order -D
  1. stylelint(16.11.0):
    Stylelint 是一个强大的现代 CSS 样式检查工具。它可以帮助你检测和修复 CSS、SCSS 和其他样式语言中的错误和不一致。
    它提供了丰富的规则集,可以自定义以满足项目的特定需求。
  2. stylelint-scss(6.10.0):
    这个插件为 Stylelint 提供了对 SCSS 语法的支持。它增加了许多专门用于 SCSS 的规则,帮助你保持 SCSS 代码的质量和一致性。
  3. stylelint-config-recommended-scss(14.1.0):
    这是一个 Stylelint 的配置包,提供了一组推荐的 SCSS 规则。它是一个基础配置,帮助你快速开始使用 Stylelint 检查 SCSS 代码。
  4. stylelint-config-standard(36.0.1):
    这个配置包提供了一组标准的 CSS 规则,适用于大多数项目。它帮助你确保 CSS 代码符合行业标准的最佳实践。
  5. stylelint-config-standard-scss(14.0.0):
    这是 stylelint-config-standard 的扩展,专门为 SCSS 提供标准规则。它结合了标准 CSS 和 SCSS 的最佳实践。
  6. stylelint-order(6.0.4):
    这个插件为 Stylelint 提供了 CSS 属性排序的功能。它允许你定义属性的排序规则,帮助你保持样式代码的可读性和一致性。
  • 在根目录新增文件 .stylelintignore
  1. # .stylelintignore
  2. # 旧的不需打包的样式库
  3. *.min.css
  4. # 其他类型文件
  5. *.js
  6. *.jpg
  7. *.png
  8. *.eot
  9. *.ttf
  10. *.woff
  11. *.json
  12. # 测试和打包目录
  13. /test/
  14. /dist/
  15. /node_modules/
  16. /lib/
  • 在根目录新增文件 .stylelintrc.cjs
  1. module.exports = {
  2. extends: [
  3. 'stylelint-config-standard',
  4. 'stylelint-config-standard-scss',
  5. 'stylelint-config-recommended-scss',
  6. ],
  7. plugins: ['stylelint-scss', 'stylelint-order'],
  8. rules: {
  9. 'no-irregular-whitespace': true,
  10. // 指定样式的排序
  11. 'order/properties-order': [
  12. [
  13. 'content',
  14. 'position',
  15. 'top',
  16. 'right',
  17. 'bottom',
  18. 'left',
  19. 'z-index',
  20. 'display',
  21. 'vertical-align',
  22. 'flex',
  23. 'flex-grow',
  24. 'flex-shrink',
  25. 'flex-basis',
  26. 'flex-direction',
  27. 'flex-flow',
  28. 'flex-wrap',
  29. 'grid',
  30. 'grid-area',
  31. 'grid-template',
  32. 'grid-template-areas',
  33. 'grid-template-rows',
  34. 'grid-template-columns',
  35. 'grid-row',
  36. 'grid-row-start',
  37. 'grid-row-end',
  38. 'grid-column',
  39. 'grid-column-start',
  40. 'grid-column-end',
  41. 'grid-auto-rows',
  42. 'grid-auto-columns',
  43. 'grid-auto-flow',
  44. 'grid-gap',
  45. 'grid-row-gap',
  46. 'grid-column-gap',
  47. 'gap',
  48. 'row-gap',
  49. 'column-gap',
  50. 'align-content',
  51. 'align-items',
  52. 'align-self',
  53. 'justify-content',
  54. 'justify-items',
  55. 'justify-self',
  56. 'order',
  57. 'float',
  58. 'clear',
  59. 'object-fit',
  60. 'overflow',
  61. 'overflow-x',
  62. 'overflow-y',
  63. 'overflow-scrolling',
  64. 'clip',
  65. //
  66. 'box-sizing',
  67. 'width',
  68. 'min-width',
  69. 'max-width',
  70. 'height',
  71. 'min-height',
  72. 'max-height',
  73. 'margin',
  74. 'margin-top',
  75. 'margin-right',
  76. 'margin-bottom',
  77. 'margin-left',
  78. 'padding',
  79. 'padding-top',
  80. 'padding-right',
  81. 'padding-bottom',
  82. 'padding-left',
  83. 'border',
  84. 'border-spacing',
  85. 'border-collapse',
  86. 'border-width',
  87. 'border-style',
  88. 'border-color',
  89. 'border-top',
  90. 'border-top-width',
  91. 'border-top-style',
  92. 'border-top-color',
  93. 'border-right',
  94. 'border-right-width',
  95. 'border-right-style',
  96. 'border-right-color',
  97. 'border-bottom',
  98. 'border-bottom-width',
  99. 'border-bottom-style',
  100. 'border-bottom-color',
  101. 'border-left',
  102. 'border-left-width',
  103. 'border-left-style',
  104. 'border-left-color',
  105. 'border-radius',
  106. 'border-top-left-radius',
  107. 'border-top-right-radius',
  108. 'border-bottom-right-radius',
  109. 'border-bottom-left-radius',
  110. 'border-image',
  111. 'border-image-source',
  112. 'border-image-slice',
  113. 'border-image-width',
  114. 'border-image-outset',
  115. 'border-image-repeat',
  116. 'border-top-image',
  117. 'border-right-image',
  118. 'border-bottom-image',
  119. 'border-left-image',
  120. 'border-corner-image',
  121. 'border-top-left-image',
  122. 'border-top-right-image',
  123. 'border-bottom-right-image',
  124. 'border-bottom-left-image',
  125. //
  126. 'background',
  127. 'background-color',
  128. 'background-image',
  129. 'background-attachment',
  130. 'background-position',
  131. 'background-position-x',
  132. 'background-position-y',
  133. 'background-clip',
  134. 'background-origin',
  135. 'background-size',
  136. 'background-repeat',
  137. 'color',
  138. 'box-decoration-break',
  139. 'box-shadow',
  140. 'outline',
  141. 'outline-width',
  142. 'outline-style',
  143. 'outline-color',
  144. 'outline-offset',
  145. 'table-layout',
  146. 'caption-side',
  147. 'empty-cells',
  148. 'list-style',
  149. 'list-style-position',
  150. 'list-style-type',
  151. 'list-style-image',
  152. //
  153. 'font',
  154. 'font-weight',
  155. 'font-style',
  156. 'font-variant',
  157. 'font-size-adjust',
  158. 'font-stretch',
  159. 'font-size',
  160. 'font-family',
  161. 'src',
  162. 'line-height',
  163. 'letter-spacing',
  164. 'quotes',
  165. 'counter-increment',
  166. 'counter-reset',
  167. '-ms-writing-mode',
  168. 'text-align',
  169. 'text-align-last',
  170. 'text-decoration',
  171. 'text-emphasis',
  172. 'text-emphasis-position',
  173. 'text-emphasis-style',
  174. 'text-emphasis-color',
  175. 'text-indent',
  176. 'text-justify',
  177. 'text-outline',
  178. 'text-transform',
  179. 'text-wrap',
  180. 'text-overflow',
  181. 'text-overflow-ellipsis',
  182. 'text-overflow-mode',
  183. 'text-shadow',
  184. 'white-space',
  185. 'word-spacing',
  186. 'word-wrap',
  187. 'word-break',
  188. 'overflow-wrap',
  189. 'tab-size',
  190. 'hyphens',
  191. 'interpolation-mode',
  192. //
  193. 'opacity',
  194. 'visibility',
  195. 'filter',
  196. 'resize',
  197. 'cursor',
  198. 'pointer-events',
  199. 'user-select',
  200. //
  201. 'unicode-bidi',
  202. 'direction',
  203. 'columns',
  204. 'column-span',
  205. 'column-width',
  206. 'column-count',
  207. 'column-fill',
  208. 'column-gap',
  209. 'column-rule',
  210. 'column-rule-width',
  211. 'column-rule-style',
  212. 'column-rule-color',
  213. 'break-before',
  214. 'break-inside',
  215. 'break-after',
  216. 'page-break-before',
  217. 'page-break-inside',
  218. 'page-break-after',
  219. 'orphans',
  220. 'widows',
  221. 'zoom',
  222. 'max-zoom',
  223. 'min-zoom',
  224. 'user-zoom',
  225. 'orientation',
  226. 'fill',
  227. 'stroke',
  228. //
  229. 'transition',
  230. 'transition-delay',
  231. 'transition-timing-function',
  232. 'transition-duration',
  233. 'transition-property',
  234. 'transform',
  235. 'transform-origin',
  236. 'animation',
  237. 'animation-name',
  238. 'animation-duration',
  239. 'animation-play-state',
  240. 'animation-timing-function',
  241. 'animation-delay',
  242. 'animation-iteration-count',
  243. 'animation-direction',
  244. 'animation-fill-mode',
  245. ],
  246. {
  247. unspecified: 'bottom',
  248. severity: 'error',
  249. },
  250. ],
  251. },
  252. }
  • 打开命令面板重启一下扩展宿主,可以看到App.css文件报红
  • 添加脚本命令行
  1. // ...
  2. "scripts": {
  3. // ...
  4. "stylelint": "stylelint ./**/*.{css,scss}",
  5. "stylelint:fix": "stylelint ./**/*.{css,scss} --fix",
  6. },
  7. // ...

Husky

版本:9.1.7 ➡️

Husky 是一个用于管理 Git 钩子的工具。它可以帮助你在特定的 Git 操作(如提交、推送等)之前或之后自动运行脚本,从而确保代码质量和一致性

  • 安装依赖
  1. pnpm add husky -D
  • package.json添加脚本命令
  1. // ...
  2. "scripts": {
  3. // ...
  4. "prepare": "husky install"
  5. },
  6. // ...
  • 生成 husky
  1. pnpm exec husky init
  • 更新修改 pre-commit 文件
  1. pnpm run lint:fix && pnpm run stylelint:fix
  • 执行 Git 提交命令
  1. git add .
  2. git commit -m 'feat: init'
  • 可以看到提交的时候帮我们检查并修复不规范的代码

代码规范(2025年最新一版) - 图2

Commitlint

@commitlint/cli(19.6.0):

Commitlint 是一个用于检查 Git 提交信息的工具。@commitlint/cli 是其命令行接口,允许你在命令行中运行 Commitlint。

@commitlint/config-conventional(19.6.0):

这是 Commitlint 的一个配置包,提供了一组基于 Angular 提交信息规范的规则。

cz-git(1.11.0):

cz-git 是一个交互式的提交信息生成工具,基于 Commitizen 适配器。它提供了一个命令行界面,帮助开发者按照预定义的格式生成提交信息。

czg(1.11.0):

czg 是 cz-git 的一个命令行工具,提供了更友好的用户界面和功能,帮助开发者生成符合规范的提交信息。

  • 安装依赖
  1. pnpm add @commitlint/cli @commitlint/config-conventional cz-git czg -D
  • 在 package.json 文件中添加
  1. "commitizen": {
  2. "path": "node_modules/cz-git"
  3. }
  • 项目根目录添加commitlint.config.cjs文件夹
  1. /** @type {import('cz-git').UserConfig} */
  2. module.exports = {
  3. ignores: [(commit) => commit.includes("init")],
  4. extends: ["@commitlint/config-conventional"],
  5. rules: {
  6. "body-leading-blank": [2, "always"],
  7. "footer-leading-blank": [1, "always"],
  8. "header-max-length": [2, "always", 108],
  9. "subject-empty": [2, "never"],
  10. "type-empty": [2, "never"],
  11. "subject-case": [0],
  12. "type-enum": [
  13. 2,
  14. "always",
  15. [
  16. "feat",
  17. "fix",
  18. "docs",
  19. "style",
  20. "refactor",
  21. "perf",
  22. "test",
  23. "build",
  24. "ci",
  25. "chore",
  26. "revert",
  27. "wip",
  28. "workflow",
  29. "types",
  30. "release",
  31. ],
  32. ],
  33. },
  34. prompt: {
  35. messages: {
  36. type: "选择你要提交的类型 :",
  37. scope: "选择一个提交范围[可选]:",
  38. customScope: "请输入自定义的提交范围 :",
  39. subject: "请简要描述提交 :\n",
  40. body: '填写更加详细的变更描述[可选]。使用 "|" 换行 :\n',
  41. breaking: '列举非兼容性重大的变更[可选]。使用 "|" 换行 :\n',
  42. footerPrefixsSelect: "选择关联issue前缀[可选]:",
  43. customFooterPrefixs: "输入自定义issue前缀 :",
  44. footer: "列举关联issue [可选] 例如: #31, #I3244 :\n",
  45. confirmCommit: "是否提交或修改commit ?",
  46. },
  47. types: [
  48. { value: "feat", name: "feat: ✨ 新增功能", emoji: "✨" },
  49. { value: "fix", name: "fix: 🐛 修复缺陷", emoji: "🐛" },
  50. { value: "docs", name: "docs: 📝 文档变更", emoji: "📝" },
  51. {
  52. value: "style",
  53. name: "style: 💄 代码格式",
  54. emoji: "💄",
  55. },
  56. {
  57. value: "refactor",
  58. name: "refactor: 🔨 代码重构",
  59. emoji: "🔨",
  60. },
  61. { value: "perf", name: "perf: ⚡️ 性能优化", emoji: "⚡️" },
  62. {
  63. value: "test",
  64. name: "test: ✅ 测试",
  65. emoji: "✅",
  66. },
  67. {
  68. value: "build",
  69. name: "build: 📦️ 打包构建",
  70. emoji: "📦️",
  71. },
  72. { value: "ci", name: "ci: 👷 CI 配置变更", emoji: "👷" },
  73. { value: "revert", name: "revert: ⏪️ 代码回退", emoji: "⏪️" },
  74. {
  75. value: "chore",
  76. name: "chore: 🚀 构建/工程依赖/工具",
  77. emoji: "🚀",
  78. },
  79. { value: "wip", name: "wip: 🚧 正在开发中", emoji: "🚧" },
  80. { value: "workflow", name: "workflow: 🎯 工作流程改进", emoji: "🎯" },
  81. ],
  82. useEmoji: true,
  83. scopes: [],
  84. customScopesAlign: "bottom",
  85. emptyScopesAlias: "empty",
  86. customScopesAlias: "custom",
  87. allowBreakingChanges: ["feat", "fix"],
  88. skipQuestions: ["scope", "body", "breaking", "footerPrefix", "footer"], // 自定义选择指定的问题不显示
  89. },
  90. };
  • package.json 中添加脚本
  1. "scripts": {
  2. // ...
  3. "commit": "czg"
  4. },
  • .husky 中新增 commit-msg 文件
  1. #!/usr/bin/env sh
  2. . "$(dirname -- "$0")/_/husky.sh"
  3. npx --no -- commitlint --edit $1
  • 输入命令
  1. pnpm commit

lint-staged

15.2.10

lint-staged 是一个工具,用于在 Git 暂存文件上运行 linters(代码检查工具)。它的主要作用是提高代码质量和开发效率。以下是 lint-staged 的一些关键功能和作用:

  • 安装依赖
  1. pnpm add lint-staged -D
  • 修改pre-commit文件
  1. npx lint-staged

执行

  1. git add .
  2. pnpm commit
  • 完成

代码规范(2025年最新一版) - 图3

参考资料