【脚手架】从0到1搭建React18+TS4.x+Webpack5项目(三)代码质量和git提交规范

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 【脚手架】从0到1搭建React18+TS4.x+Webpack5项目(三)代码质量和git提交规范

微信图片_20230612194326.pngflag:每月至少产出三篇高质量文章~

欢迎关注我的另外几篇文章:

微信图片_20230612194359.png可能想要玩的技术栈:

  • 按需加载
  • dark theme
  • I18n
  • ......
  • 静态资源:图片、fontsMedia、数据资源(JSONcsvtsvexcel)......
  • React-Admin、可视化大屏、响应式、代码生成、低代码
  • 权限:React-Admin(RBAC) + GoReact-Admin(RBAC) + Node
  • 接口 mock
  • 性能优化
  • 工具层面:热更新、资源压缩、代码分离(动态导入、懒加载、预加载等)、缓存……
  • 代码层面:大组件拆分、全局状态管理、组件封装、re-render

上篇文章,我们做了项目的一些基础功能配置,本篇主要讲代码质量和git提交规范。

本篇文章代码:react18-ts4-webpack5-starter - branch:cha-03

1、前言

一套完善的开发环境配置可以极大的提升开发效率,提高代码质量,方便多人合作,以及后期的项目迭代和维护。所以说,前端代码格式规范和语法检测的工具可以提高代码的质量和可读性,减少低级错误和维护成本,提高团队的协作效率和开发效率,是非常有必要的。

1.1 代码格式规范和语法检测工具

  1. EditorConfigEditorConfig 是一个用于统一编辑器和 IDE 的配置文件的工具。它可以帮助团队协作中的开发人员保持一致的编码风格,无论他们使用的是哪个编辑器或 IDE。EditorConfig 支持配置文件的语法规则、缩进、换行符、字符编码等,可以通过在项目中添加一个 .editorconfig 文件来使用。
  2. ESLintESLint 是一个广泛使用的 JavaScript 代码检查工具,它可以帮助开发人员遵循代码风格规范,并发现代码中潜在的问题。ESLint 有很多可定制的规则,可以根据团队的代码风格和项目的要求进行配置。ESLint 还支持集成到许多编辑器和 IDE 中,如 Visual Studio Code、Sublime Text、Atom、WebStorm 等,以提供实时的语法和格式错误检查。
  3. PrettierPrettier 是一个代码格式化工具,它可以自动化地将代码格式化为一致的风格。与 ESLint 不同的是,Prettier 不关心代码的语义或质量,只关心代码的外观。PrettierESLint 集成使用可以让代码保持一致性和规范性。
  4. StylelintStylelint 是一个 CSS 样式检查工具,它可以帮助开发人员遵循 CSS 代码风格规范,并发现代码中潜在的问题。Stylelint 有很多可定制的规则,可以根据团队的代码风格和项目的要求进行配置。Stylelint 也支持集成到许多编辑器和 IDE 中,如 Visual Studio Code、Sublime Text、Atom、WebStorm 等,以提供实时的语法和格式错误检查。
  5. MarkdownlintMarkdownlint 是一个用于检查 Markdown 文件中语法和格式的工具,它可以帮助你保证 Markdown 文件的一致性和可读性。Markdownlint 支持在命令行、编辑器和 CI/CD 工具中使用。

这些工具都有相似的目标

  • 使代码本身和团队成员之间更加一致
  • 检测可能导致潜在错误的有问题的代码

总的来说:

  • EditorConfig: 跨编辑器和IDE编写代码,保持一致的简单编码风格;
  • Prettier: 专注于代码格式化的工具,美化代码;
  • ESLint:专注于代码质量检测、编码风格约束等;
  • Stylelint:专注于样式代码语法检查和格式错误检查;
  • Markdownlint:专注作为 Markdownlinter

它们整个的工作流程是这样的:

微信图片_20230612194445.png

1.2 代码提交规范工具

  1. CommitizenCommitizen 是一个 Git 提交信息格式化工具,可以通过命令行交互式地创建符合规范的 Git 提交信息。Commitizen 支持自定义提交信息的格式,并且可以与其他规范工具(如 ESLintPrettier)集成使用。
  2. Conventional CommitsConventional Commits 是一个 Git 提交信息规范标准,规定了 Git 提交信息的格式和内容,包括提交类型、作用域、描述、消息体和消息页脚等部分。Conventional Commits 规范可以帮助团队协作中的开发人员更好地理解和管理代码变更历史。
  3. HuskyCommitlintHuskyCommitlint 是两个工具,可以结合使用来规范 Git 提交信息。Husky 可以在 Git 提交前执行一些预定义的钩子(如 pre-commitpre-push),而 Commitlint 可以检查 Git 提交信息是否符合规范。
  4. Git HooksGit Hooks 是 Git 自带的一个钩子系统,可以在 Git 的各个生命周期(如 pre-commitpost-commit)执行自定义的脚本。开发人员可以使用 Git Hooks 来规范化 Git 提交信息,例如在 pre-commit 钩子中执行提交信息的格式检查。

代码 Git 提交规范工具是非常有用的,可以帮助开发人员更好地管理代码变更历史,提高代码可维护性和协作效率。开发人员可以根据自己的需求和团队的规范选择合适的工具和标准来使用。

推荐文章:

2、editorconfig

在项目中引入 editorconfig 是为了在多人协作开发中保持代码的风格和一致性。不同的开发者使用不同的编辑器或IDE,可能会有不同的缩进(比如有的人喜欢4个空格,有的喜欢2个空格)、换行符、编码格式等。甚至相同的编辑器因为开发者自定义配置的不同也会导致不同风格的代码,这会导致代码的可读性降低,增加代码冲突的可能性,降低了代码的可维护性。

EditorConfig 使不同编辑器可以保持同样的配置。因此,我们得以无需在每次编写新代码时,再依靠 Prettier 来按照团队约定格式化一遍(出现保存时格式化突然改变的情况) 。当然这需要在你的 IDE 上安装了必要的 EditorConfig 插件或扩展。

2.1 安装 EditorConfig for VS Code

微信图片_20230612194518.png目前主流的编辑器或者 IDE 基本上都有对应的 EditorConfig 插件,有的是内置支持的(比如,WebStorm 不需要独立安装 EditorConfig 的插件),有的需要独立安装。

需要注意的是,不同的插件对 EditorConfig 属性的支持度不一样,笔者使用的是 VS Code

然后在插件的介绍页上点击设置的齿轮,并且选择Add to Workspace Recommendations,就可以将其加入清单。也可以直接开启 .vscode/extensions.json 进行编辑

{ 
    "recommendations": ["editorconfig.editorconfig"] 
}

微信图片_20230612194558.png为什么要做这个操作? 假如哪天项目新来一个协同开发的同学,当他拉取取项目,用 vscode 打开项目的时候,编辑器就会自动提醒他安装这个插件,并将相关的配置做设定。下面的 eslintprettier 插件也是类似。

2.2 新建 .editorconfig

在根目录新建 .editorconfig 文件:

# https://editorconfig.org
root = true # 设置为true表示根目录,控制配置文件 .editorconfig 是否生效的字段
[*] # 匹配全部文件,匹配除了 `/` 路径分隔符之外的任意字符串
charset = utf-8                  # 设置字符编码,取值为 latin1,utf-8,utf-8-bom,utf-16be 和 utf-16le,当然 utf-8-bom 不推荐使用
end_of_line = lf                 # 设置使用的换行符,取值为 lf,cr 或者 crlf
indent_size = 2                  # 设置缩进的大小,即缩进的列数,当 indexstyle 取值 tab 时,indentsize 会使用 tab_width 的值
indent_style = space             # 缩进风格,可选space|tab
insert_final_newline = true      # 设为true表示使文件以一个空白行结尾
trim_trailing_whitespace = true  # 删除一行中的前后空格
[*.md] # 匹配全部 .md 文件
trim_trailing_whitespace = false

上面的配置可以规范本项目中文件的缩进风格,和缩进空格数等,会覆盖 vscode 的配置,来达到不同编辑器中代码默认行为一致的作用。

VS Code 的 EditorConfig 目前支持下列属性:

  • indent_style
  • indent_size
  • tab_width
  • end_of_line(on save)
  • insert_final_newline(on save)
  • trim_trailing_whitespace(on save)

3、prettier

每个人写代码的风格习惯不一样,比如代码换行,结尾是否带分号,单双引号,缩进等,而且不能只靠口头规范来约束,项目紧急的时候可能会不太注意代码格式,这时候需要有工具来帮我们自动格式化代码,而prettier就是帮我们做这件事的。

3.1 安装 VS Code 插件和 prettier

微信图片_20230612194647.png
微信图片_20230612194656.png安装 prettier

pnpm add prettier -D

3.2 新建 .prettier.js

在根目录下新建 .prettierrc.js 和 .prettierignore 文件:

// .prettierrc.js
module.exports = {
  tabWidth: 2, // 一个tab代表几个空格数,默认就是2
  useTabs: false, // 是否启用tab取代空格符缩进,.editorconfig设置空格缩进,所以设置为false
  printWidth: 100, // 一行的字符数,如果超过会进行换行
  semi: false, // 行尾是否使用分号,默认为true
  singleQuote: true, // 字符串是否使用单引号
  trailingComma: 'none', // 对象或数组末尾是否添加逗号 none| es5| all
  jsxSingleQuote: true, // 在jsx里是否使用单引号,你看着办
  bracketSpacing: true, // 对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
  arrowParens: 'avoid' // 箭头函数如果只有一个参数则省略括号
}
// .prettierignore
node_modules
dist
env
.gitignore
pnpm-lock.yaml
README.md

3.3 配置 .vscode/settings.json

配置前两步后,虽然已经配置 prettier 格式化规则,但还需要让 vscode 来支持保存后触发格式化,在项目根目录新建 .vscode 文件夹,内部新建 settings.json 文件配置文件,代码如下:

{
  "search.exclude": {
    "/node_modules": true,
    "dist": true,
    "pnpm-lock.yaml": true
  },
  "files.autoSave": "onFocusChange",
  "editor.formatOnSave": true,
  "editor.formatOnType": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "vscode.json-language-features"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "javascript.validate.enable": false,
}
  • 若配置 "prettier.requireConfig": true 则要求根目录下有 Prettier 的配置文件,它会覆盖 Prettier扩展 中的默认配置,否则保存时不会自动格式化。可以参考这里
  • 若配置 "prettier.requireConfig": false 则不要求根目录下有配置文件,若有的话也会被感知到并以配置文件的内容为准。

这些代码的作用是:在编辑后保存 [xxx] 文件时,自动应用 Prettier 进行格式化,以确保代码风格的一致性。

先配置了忽略哪些文件不进行格式化,又添加了保存代码后触发格式化代码配置,以及各类型文件格式化使用的格式。这一步配置完成后,修改项目代码,把格式打乱,点击保存时就会看到编辑器自动把代码格式规范化了。

若设置需要配置文件,则必须要求根目录下有配置文件 .prettierrc.js.editorconfig 中的一个或者两个同时存在,否则代码保存不会进行格式化。

可能你会对上面 .editorconfig 文件作为 Prettier 的配置文件感到疑惑,vscodePrettier 插件中有关配置文件有这样的一段描述,如下图:

微信图片_20230612194856.png

  • 可以看出Prettier插件获取配置文件有一个优先级:.prettierrc > .editorconfig > vscode默认配置
  • 上面的前两者并不是说 .prettierrc.editorconfig 同时存在时,后者的配置内容就被忽略,实际的表现:
  • .prettierrc.js.editorconfig 同时存在时,二者内容会进行合并,若配置项有冲突,这 .prettierrc 的优先级更高。

为了保证我们的编辑器是使用 prettier 作为默认格式化的工具,最好是手动配置一下默认的格式化插件:

微信图片_20230612194922.png
微信图片_20230612194929.png
微信图片_20230612195001.png

3.4 脚本命令检查和修复格式

package.json"scripts" 中加入以下脚本命令:

"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,scss,stylus,html,md}\""

这段代码是一个脚本命令,用于运行 Prettier 工具来格式化指定目录下的文件。具体解释如下:

  • "--write": 表示将格式化后的结果直接写回原文件中,而不是输出到控制台。
  • "--loglevel warn": 表示只输出警告级别的日志信息。
  • "src/**/*.{js,ts,json,tsx,css,less,scss,stylus,html,md}": 是要格式化的文件的路径,这里指定了在 src 目录下,所有扩展名为 .js.ts.json.tsx.css.less.scss.stylus.html.md 的文件。

这个脚本命令的作用是:运行 Prettier 工具来格式化指定目录下的文件,并将格式化后的结果直接写回原文件中。同时,只输出警告级别的日志信息。

现在可以测试一下,将 .prettierrc.js 中的 tabWidth 值修改为 4(缩进为 4 个空格),然后运行 pnpm run lint:prettier,随便打开一个 src 下的文件,你就会发现缩进从 2 变成 4 了。

4、Markdownlint

4.1 安装 markdownlint-cli

微信图片_20230612195054.png
微信图片_20230612195103.png
安装依赖:

pnpm add markdownlint-cli -D

4.2 新建 .markdownlint.js

module.exports = {
  default: false, // excludes all rules
  MD001: true, // enables rule MD001
  MD003: { style: 'atx_closed' }, // set parameter style of rule MD003 to atx_closed
  'first-line-heading': true, // enables alias first-line-heading
  atx_closed: true // enables tag atx-closed
}

名称可以是defaultrulealiastags

  • default:特殊属性,设为 true 会启用所有规则,反之设为 false 则关闭所有规则
  • rule:规则名称,对应至各个规则,像是范例中的 MD001MD003
  • alias:规则别称,对应至各个规则的别名,例如范例中的 first-line-heading规则 MD041 的别名
  • tags:作用的标签,对应至各规则的所属标签,可以将其视为规则的群组,例如范例中的 atx_closed 包括了 MD020MD021 两个规则

在根目录新建 .markdownlintignore,然后加入:

node_modules
dist
env
.gitignore
pnpm-lock.yaml
src/assets/*
.vscode
public
.github

设定完成后执行 Markdownlint

npx markdownlint --config .markdownlint.js --fix .

这个指令会依照 .markdownlint.js 所设定的规则规范项目中所有的 Markdown 文件。

最后一步,将其加入到 package.jsonscripts

 "scripts": {
    // ...
    "lint:md": "npx markdownlint --config .markdownlint.js --fix ."
  },

4.3 配置 .vscode/settings.json

{ 
    // ...
    "editor.codeActionsOnSave": { 
        "source.fixAll.markdownlint": true 
    } 
}

这样就可以在保存md文件的时候,自动修复文档了。

5、stylelint

5.1 安装 stylelint 插件和依赖
微信图片_20230612195335.png

pnpm add stylelint stylelint-config-css-modules stylelint-config-prettier stylelint-config-standard stylelint-order -D

5.2 新建 .stylelintrc.js 和 .stylelintignore

// @see: https://stylelint.io
module.exports = {
  extends: [
    'stylelint-config-standard',
    'stylelint-config-prettier'
  ],
  plugins: ['stylelint-order'],
  rules: {
    'selector-class-pattern': [
      // 命名规范 -
      '^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
      {
        message: 'Expected class selector to be kebab-case'
      }
    ],
    'string-quotes': 'double', // 单引号
    'at-rule-empty-line-before': null,
    'at-rule-no-unknown': null,
    'at-rule-name-case': 'lower', // 指定@规则名的大小写
    'length-zero-no-unit': true, // 禁止零长度的单位(可自动修复)
    'shorthand-property-no-redundant-values': true, // 简写属性
    'number-leading-zero': 'always', // 小数不带0
    'declaration-block-no-duplicate-properties': true, // 禁止声明快重复属性
    'no-descending-specificity': true, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器。
    'selector-max-id': null, // 限制一个选择器中 ID 选择器的数量
    'max-nesting-depth': 10,
    'declaration-block-single-line-max-declarations': 1,
    'block-opening-brace-space-before': 'always',
    'selector-max-type': [0, { ignore: ['child', 'descendant', 'compounded'] }],
    indentation: [
      2,
      {
        // 指定缩进  warning 提醒
        severity: 'warning'
      }
    ],
    'order/order': ['custom-properties', 'dollar-variables', 'declarations', 'rules', 'at-rules'],
    'order/properties-order': [
      // 规则顺序
      // ...  这块太长,去我 github repo 找吧
    ]
  }
}

.stylelintignore 文件:

dist
public
env
build
.vscode
.husky
.DS_Store
.github
typings
README.md
node_modules

5.3 配置 .vscode/settings.json

最后记得在 .vscode/settings.json 中加入:

{ 
    // ...
    "editor.codeActionsOnSave": { 
         "source.fixAll.stylelint": true 
     },
     "stylelint.validate": [
        "css",
        "less",
        "sass",
        "stylus",
        "postcss"
      ]
}

6、eslint

ESLint 是什么呢?一个开源的 JavaScriptlinting 工具,是一个在 JavaScript 代码中通过规则模式匹配作代码识别和报告的插件化的检测工具,它的目的是保证代码规范的一致性和及时发现代码问题、提前避免错误发生。它使用 espreeJavaScript 代码解析成抽象语法树 (AST),然后通过AST 来分析我们代码,从而给予我们两种提示:

  1. 代码质量问题:使用方式有可能有问题,eslint 可以发现代码中存在的可能错误,如使用未声明变量声明而未使用的变量修改 const 变量代码中使用debugger等等
  2. 代码风格问题:风格不符合一定规则,eslint 也可以用来统一团队的代码风格,比如加不加分号使用tab还是空格字符串使用单引号 等等

ESLint 的关注点是代码质量,检查代码风格并且会提示不符合风格规范的代码。除此之外 ESLint 也具有一部分代码格式化的功能。

ESLint 最初是由 Nicholas C. Zakas ( JavaScript 高级程序设计 作者)于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具。

JavaScript发展历程中出现的Lint工具:JSLint->JSHint->ESLint/TSLint

  • JSLint是最早出现的 Lint 工具,不支持灵活拓展及配置,必须接受它所有规则;
  • JSHintJSLint 的基础上提供了一定的配置项,给了开发者较大的自由,但无法添加自定义规则;
  • Zakas创建ESLint的初衷就是觉得当时的JSHint存在局限性,无法添加自定义规则。
  • ES6的出现后则让ESLint迅速大火。
    因为ES6新增了很多语法,JSHint 短期内无法提供支持,而 ESLint 只需要有合适的解析器以及拓展校验规则 就能够进行 Lint 检查。此时 babel 就为兼容 ESLint 开发了 babel-eslint 解析器,提供支持的同时也让 ESLint 成为最快支持 ES6 语法的 Lint 工具。

6.1 安装 eslint 插件和包

微信图片_20230612195522.png
微信图片_20230612195541.png安装 eslint

pnpm add eslint eslint-config-airbnb eslint-config-standard eslint-friendly-formatter eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-node eslint-plugin-promise eslint-plugin-react-hooks eslint-plugin-react @typescript-eslint/eslint-plugin @typescript-eslint/parser -D 

6.2 新建 .eslintrc.js

在根目录新建一个 .eslintrc.js 文件:

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: [
    'airbnb-base',
    'eslint:recommended',
    'plugin:import/recommended',
    'plugin:@typescript-eslint/recommended'
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true
    },
    ecmaVersion: 'latest',
    sourceType: 'module'
  },
  plugins: ['react', '@typescript-eslint'],
  rules: {
    // eslint (http://eslint.cn/docs/rules)
    'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx', '.ts', '.tsx'] }],
    'class-methods-use-this': 'off',
    'no-param-reassign': 'off',
    'no-unused-expressions': 'off',
    'no-plusplus': 0,
    'no-restricted-syntax': 0,
    'consistent-return': 0,
    '@typescript-eslint/ban-types': 'off',
    // "import/no-extraneous-dependencies": "off",
    '@typescript-eslint/no-non-null-assertion': 'off',
    'import/no-unresolved': 'off',
    'import/prefer-default-export': 'off', // 关闭默认使用 export default 方式导出
    'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
    '@typescript-eslint/no-use-before-define': 0,
    'no-use-before-define': 0,
    '@typescript-eslint/no-var-requires': 0,
    '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
    'no-shadow': 'off',
    // "@typescript-eslint/no-var-requires": "off"
    'import/extensions': [
      'error',
      'ignorePackages',
      {
        '': 'never',
        js: 'never',
        jsx: 'never',
        ts: 'never',
        tsx: 'never'
      }
    ]
    // "no-var": "error", // 要求使用 let 或 const 而不是 var
    // "no-multiple-empty-lines": ["error", { max: 1 }], // 不允许多个空行
    // "no-use-before-define": "off", // 禁止在 函数/类/变量 定义之前使用它们
    // "prefer-const": "off", // 此规则旨在标记使用 let 关键字声明但在初始分配后从未重新分配的变量,要求使用 const
    // "no-irregular-whitespace": "off", // 禁止不规则的空白
    // // typeScript (https://typescript-eslint.io/rules)
    // "@typescript-eslint/no-unused-vars": "error", // 禁止定义未使用的变量
    // "@typescript-eslint/no-inferrable-types": "off", // 可以轻松推断的显式类型可能会增加不必要的冗长
    // "@typescript-eslint/no-namespace": "off", // 禁止使用自定义 TypeScript 模块和命名空间。
    // "@typescript-eslint/no-explicit-any": "off", // 禁止使用 any 类型
    // "@typescript-eslint/ban-ts-ignore": "off", // 禁止使用 @ts-ignore
    // "@typescript-eslint/ban-types": "off", // 禁止使用特定类型
    // "@typescript-eslint/explicit-function-return-type": "off", // 不允许对初始化为数字、字符串或布尔值的变量或参数进行显式类型声明
    // "@typescript-eslint/no-var-requires": "off", // 不允许在 import 语句中使用 require 语句
    // "@typescript-eslint/no-empty-function": "off", // 禁止空函数
    // "@typescript-eslint/no-use-before-define": "off", // 禁止在变量定义之前使用它们
    // "@typescript-eslint/ban-ts-comment": "off", // 禁止 @ts-<directive> 使用注释或要求在指令后进行描述
    // "@typescript-eslint/no-non-null-assertion": "off", // 不允许使用后缀运算符的非空断言(!)
    // "@typescript-eslint/explicit-module-boundary-types": "off", // 要求导出函数和类的公共类方法的显式返回和参数类型
    // // react (https://github.com/jsx-eslint/eslint-plugin-react)
    // "react-hooks/rules-of-hooks": "error",
    // "react-hooks/exhaustive-deps": "off"
  },
  settings: {
    'import/extensions': ['.js', '.jsx', '.ts', '.tsx'],
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx']
    },
    'import/resolver': {
      node: {
        paths: ['src'],
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
        moduleDirectory: ['node_modules', 'src/']
      }
    }
  }
}

有时候,我们需要在代码中忽略ESLint的某些规则检查,此时我们可以通过加入代码注释的方式解决:可以指定整个文件、某一行、某一区块开启/关闭 某些或全部规则检查;

/* eslint-disable */    --禁用全部规则  放在文件顶部则整个文件范围都不检查
/* eslint-disable no-alert, no-console */  --禁用某些规则
// eslint-disable-line     --当前行上禁用规则
// eslint-disable-next-line --下一行上禁用规则

6.3 新建 .eslintignore

在根目录新建一个 .eslintignore 文件:

node_modules
dist
env
.gitignore
pnpm-lock.yaml
README.md
src/assets/*

.eslintignore 用于指定 ESLint 工具在检查代码时要忽略的文件和目录。具体来说,.eslintignore 文件中列出的文件和目录将被 ESLint 忽略,不会对其进行代码检查和报告。这个文件中的每一行都是一个文件或目录的模式,支持使用通配符(*)和正则表达式来匹配多个文件或目录。

通常情况下,.eslintignore 文件中会列出一些不需要检查的文件或目录,比如第三方库、测试代码、构建输出等,以减少 ESLint 的检查范围,提高代码检查的效率。

6.4 添加eslint语法检测脚本

前面的eslint报错和警告都是我们用眼睛看到的,有时候需要通过脚本执行能检测出来,在package.jsonscripts中新增:

// --fix:此项指示 ESLint 尝试修复尽可能多的问题。这些修复是对实际文件本身进行的,只有剩余的未修复的问题才会被输出。
"lint:eslint": "eslint --fix --ext .js,.ts,.tsx ./src",

现在执行 pnpm run lint:eslint,控制台将会爆出一系列 warning

微信图片_20230612195734.png
除此之外再解决一个问题就是 eslint 报的警告:

React version not specified in eslint-plugin-react settings

需要告诉 eslint 使用的 react版本,在 .eslintrc.jsrules 平级添加 settings 配置,让 eslint 自己检测 react 版本,对应 issuse

settings: {
  "react": {
     "version": "detect"
  }
}

再执行pnpm run lint:eslint就不会报这个未设置react版本的警告了。

6.5 eslint 与 prettier 冲突

安装两个依赖:

pnpm add eslint-config-prettier eslint-plugin-prettier -D

.eslintrc.jsextends 中加入:

module.exports = {
  // ...
  extends: [
    // ...
    'plugin:prettier/recommended', // <==== 增加一行
  ],
  // ...
}

最后再配置一下 .vscode/settings.json

{
  // ...
  "eslint.enable": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
  },
}

7、husky + lint-statged

7.1 使用lint-staged优化eslint检测速度

在上面配置的eslint会检测src文件下所有的 .ts, .tsx文件,虽然功能可以实现,但是当项目文件多的时候,检测的文件会很多,需要的时间也会越来越长,但其实只需要检测提交到暂存区,就是git add添加的文件,不在暂存区的文件不用再次检测,而lint-staged就是来帮我们做这件事情的。

package.json添加lint-staged配置

"lint-staged": {
  "src/**/*.{ts,tsx}": [
    "pnpm run lint:eslint",
    "pnpm run lint:prettier"
  ]
},

因为要检测 git 暂存区代码,所以如果你的项目还没有使用 git 来做版本控制,需要执行git init初始化一下git

git init 

初始化git完成后就可以进行测试了,先提交一下没有语法问题的App.tsx

git add src/App.tsx 

src/App.tsx提交到暂存区后,执行npx lint-staged,会顺利通过检测。

假如我们现在把 package.json 中的 "lint:eslint" 改一下,加一个 --max-warnings=0,表示允许最多 0 个警告,就是只要出现警告就会报错:


"lint:eslint": "eslint --fix --ext .js,.ts,.tsx ./src --max-warnings=0",

然后在 App.tsx 中加入一个未使用的变量:

// ...
const a = 1
// ...

然后执行:

git add src/App.tsx 
npx lint-staged

你就会发现控制台出现了 warning

微信图片_20230612200052.png
这就是 lint-staged 的作用。

7.2 使用tsc检测类型和报错

需要注意的是,执行 tsc 命令可能会生成一个编译后的产物文件,需想要避免这个问题,需要在 tsconfig.json 中加入 "noEmit": true

{
  "compilerOptions": {
    "target": "es2016", // 指定ECMAScript目标版本
    "esModuleInterop": true,
    "module": "commonjs",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "allowJs": false, // 允许编辑js文件
    "noEmit": true, // 不生成输出文件
    "noImplicitAny": false,
    "experimentalDecorators": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "typeRoots": ["./typings/*.d.ts", "node_modules/@types"],
    "jsx": "react-jsx" // react18这里改成react-jsx,就不需要在tsx文件中手动引入React了
  },
  "include": ["./src/*", "./src/**/*.ts", "./src/**/*.tsx", "./typings/*.d.ts"],
  "exclude": ["node_modules", "dist"]
}

更多的配置参考:

{
  "compilerOptions": {
    /* 基本选项 */
    "target": "es5",                       // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
    "module": "commonjs",                  // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
    "lib": [],                             // 指定要包含在编译中的库文件
    "allowJs": true,                       // 允许编译 javascript 文件
    "checkJs": true,                       // 报告 javascript 文件中的错误
    "jsx": "preserve",                     // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
    "declaration": true,                   // 生成相应的 '.d.ts' 文件
    "sourceMap": true,                     // 生成相应的 '.map' 文件
    "outFile": "./",                       // 将输出文件合并为一个文件
    "outDir": "./",                        // 指定输出目录
    "rootDir": "./",                       // 用来控制输出目录结构 --outDir.
    "removeComments": true,                // 删除编译后的所有的注释
    "noEmit": true,                        // 不生成输出文件
    "importHelpers": true,                 // 从 tslib 导入辅助工具函数
    "isolatedModules": true,               // 将每个文件作为单独的模块 (与 'ts.transpileModule' 类似).
    /* 严格的类型检查选项 */
    "strict": true,                        // 启用所有严格类型检查选项
    "noImplicitAny": true,                 // 在表达式和声明上有隐含的 any类型时报错
    "strictNullChecks": true,              // 启用严格的 null 检查
    "noImplicitThis": true,                // 当 this 表达式值为 any 类型的时候,生成一个错误
    "alwaysStrict": true,                  // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
    /* 额外的检查 */
    "noUnusedLocals": true,                // 有未使用的变量时,抛出错误
    "noUnusedParameters": true,            // 有未使用的参数时,抛出错误
    "noImplicitReturns": true,             // 并不是所有函数里的代码都有返回值时,抛出错误
    "noFallthroughCasesInSwitch": true,    // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿)
    /* 模块解析选项 */
    "moduleResolution": "node",            // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
    "baseUrl": "./",                       // 用于解析非相对模块名称的基目录
    "paths": {},                           // 模块名到基于 baseUrl 的路径映射的列表
    "rootDirs": [],                        // 根文件夹列表,其组合内容表示项目运行时的结构内容
    "typeRoots": [],                       // 包含类型声明的文件列表
    "types": [],                           // 需要包含的类型声明文件名列表
    "allowSyntheticDefaultImports": true,  // 允许从没有设置默认导出的模块中默认导入。
    /* Source Map Options */
    "sourceRoot": "./",                    // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
    "mapRoot": "./",                       // 指定调试器应该找到映射文件而不是生成文件的位置
    "inlineSourceMap": true,               // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
    "inlineSources": true,                 // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性
    /* 其他选项 */
    "experimentalDecorators": true,        // 启用装饰器
    "emitDecoratorMetadata": true          // 为装饰器提供元数据的支持
  }
}

在项目中使用了ts,但一些类型问题,现在配置的eslint是检测不出来的,需要使用ts提供的tsc工具进行检测,如下示例

微信图片_20230612200154.png

index.tsx定义了函数hello,参数namestring类型,当调用传number类型参数时,页面有了明显的ts报错,但此时提交index.tsx文件到暂存区后执行npx lint-staged

微信图片_20230612200228.png
发现没有检测到报错,所以需要配置下tsc来检测类型,在package.json添加脚本命令

"pre-check": "tsc && npx lint-staged" 

执行pnpm run pre-check,发现已经可以检测出类型报错了。


微信图片_20230612200317.png

7.3 配置 husk

为了避免把不规范的代码提交到远程仓库,一般会在git提交代码时对代码语法进行检测,只有检测通过时才能被提交,git提供了一系列的githooks,而我们需要其中的pre-commit钩子,它会在git commit把代码提交到本地仓库之前执行,可以在这个阶段检测代码,如果检测不通过就退出命令行进程停止commit

7.3.1 代码提交前husky检测语法

husky就是可以监听githooks的工具,可以借助它来完成这件事情。

7.3.2 安装husky

pnpm add husky -D 

7.3.3 配置husky的pre-commit钩子

生成.husky配置文件夹(如果项目中没有初始化git,需要先执行git init

npx husky install 

会在项目根目录生成 .husky文件夹,生成文件成功后,需要让husky支持监听pre-commit钩子,监听到后执行上面定义的pnpm run pre-check语法检测。

npx husky add .husky/pre-commit 'pnpm run pre-check' 

会在 .husky目录下生成pre-commit文件,里面可以看到我们设置的npm run pre-check命令。
微信图片_20230612200426.png
然后提交代码进行测试

git add . 
git commit -m "feat: add code validate" 

会发现监听pre-commit钩子执行了pnpm run pre-check, 使用eslint检测了git暂存区的两个文件,并且发现了index.tsx的警告,退出了命令行,没有执行git commit把暂存区代码提交到本地仓库。

微信图片_20230612200512.png
到这里代码提交语法验证就配置完成了,可以有效的保障仓库的代码质量。

8、Commit 信息的 Linter - Commitlint

Commitlint 是个 npm 包,它使用 commit conventions 规范来检查 commit 的信息是否符合我们约定好的提交规范。

通过配置 commitlint.config.jsCommitlint 可以知道要使用哪些规则规范 commit 信息,并输出相对的提示供使用者作为修改的依据。

使用 Commitlint 规范项目的 commit,可以让所有人的代码提交保持一致的格式,这样做会有下列好处:

  • 容易检索:利用定义的关键字可以轻松地找到想要找的 commit
  • 自动输出 Changelog :固定的讯息格式可以藉由changelog 工具的帮助输出 Changelog

8.1 安装Commitlint

首先安装 Commitlint


pnpm add @commitlint/cli -D

8.2 使用Commitlint

安装完成后,由于 Commitlint 的配置档是必要的,因此要建立配置档 commitlint.config.js

js

复制代码

module.exports = {
  rules: {
    'header-min-length': [2, 'always', 10],
  },
};

配置属性 rules 可以设定规则,规则列表请参考 Commitlint 的官方页面。范例中设定讯息标头的最小长度要大于10。

接着执行 commitlint

> echo 'foo' | npx commitlint
⧗   input: foo
✖   header must not be shorter than 10 characters, current length is 3 [header-min-length]
✖   found 1 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

message 信息为 foo 时,由于长度只有3,因此 Commitlint 会视为违规而输出错误讯息。

8.3 配置规则包

为了节省配置规则的时间, Commitlint 可以使用预先配置的规则包来设定多项规则。使用前须要先安装:

pnpm add @commitlint/config-conventional -D

这里使用 @commitlint/config-conventionalCommitlint 提供的规则包。安装完成后,要在配置中设定使用规则包:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  // ...
};

这样一来 Commitlint 就会将 @commitlint/config-conventional所配置的规则都纳入并对讯息做相应的检查。

8.4 使用 Husky 为 Commitlint 注册 Git Hooks

到目前为止,我们都必须自己去手动调用 Commitlint 才能作用,使用起来的步骤较原本多,也不直观,容易被忽略。

接下来我们使用 HuskyCommitlint 融入 Git flow 中,让其更加的易用。使用 husky add 将指令加入 Git hooks

npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

修改完后,要重新注册 Git hooks

npx husky install

这会触发相关的初始化工作。完成设定后,当你输入指令 git commit,在完成编辑讯息后会启动 Commitlint 检查讯息。

9、Commitizen

为了避免写出不符规范的 commit message 而提交失败, Commitizen 使用问答的方式,让使用者在完成问答时就可以边写出符合规范的信息,以减少来回的次数。

Commitizen 是个指令式的工具,使用 Commitizencommit 代码时会启动设定的adapter,使用 adapter 提供的问题一一询问开发者,每个问题都会确认一部分的 commit message,到最后将所有的回答组合起来,变成一个完整并符合规范的 commit message

9.1 cz-git

指定提交文字规范,一款工程性更强、高度自定义、标准输出格式的 commitizen 适配器:


pnpm add commitizen cz-git -D

配置 package.json

"config": {
  "commitizen": {
    "path": "node_modules/cz-git"
  }
}

9.2 配置 commitlint.config.js 文件

// @see: https://cz-git.qbenben.com/zh/guide
/** @type {import('cz-git').UserConfig} */
module.exports = {
  ignores: [commit => commit.includes('init')],
  extends: ['@commitlint/config-conventional'],
  rules: {
    // @see: https://commitlint.js.org/#/reference-rules
    'body-leading-blank': [2, 'always'],
    'footer-leading-blank': [1, 'always'],
    'header-max-length': [2, 'always', 108],
    'subject-empty': [2, 'never'],
    'type-empty': [2, 'never'],
    'subject-case': [0],
    'type-enum': [
      2,
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'build',
        'ci',
        'chore',
        'revert',
        'wip',
        'workflow',
        'types',
        'release'
      ]
    ]
  },
  prompt: {
    messages: {
      type: "Select the type of change that you're committing:",
      scope: 'Denote the SCOPE of this change (optional):',
      customScope: 'Denote the SCOPE of this change:',
      subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
      body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
      breaking: 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',
      footerPrefixsSelect: 'Select the ISSUES type of changeList by this change (optional):',
      customFooterPrefixs: 'Input ISSUES prefix:',
      footer: 'List any ISSUES by this change. E.g.: #31, #34:\n',
      confirmCommit: 'Are you sure you want to proceed with the commit above?'
      // 中文版
      // type: "选择你要提交的类型 :",
      // scope: "选择一个提交范围(可选):",
      // customScope: "请输入自定义的提交范围 :",
      // subject: "填写简短精炼的变更描述 :\n",
      // body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
      // breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
      // footerPrefixsSelect: "选择关联issue前缀(可选):",
      // customFooterPrefixs: "输入自定义issue前缀 :",
      // footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",
      // confirmCommit: "是否提交或修改commit ?"
    },
    types: [
      {
        value: 'feat',
        name: 'feat:     🚀  A new feature',
        emoji: '🚀'
      },
      {
        value: 'fix',
        name: 'fix:      🧩  A bug fix',
        emoji: '🧩'
      },
      {
        value: 'docs',
        name: 'docs:     📚  Documentation only changes',
        emoji: '📚'
      },
      {
        value: 'style',
        name: 'style:    🎨  Changes that do not affect the meaning of the code',
        emoji: '🎨'
      },
      {
        value: 'refactor',
        name: 'refactor: ♻️   A code change that neither fixes a bug nor adds a feature',
        emoji: '♻️'
      },
      {
        value: 'perf',
        name: 'perf:     ⚡️  A code change that improves performance',
        emoji: '⚡️'
      },
      {
        value: 'test',
        name: 'test:     ✅  Adding missing tests or correcting existing tests',
        emoji: '✅'
      },
      {
        value: 'build',
        name: 'build:    📦️   Changes that affect the build system or external dependencies',
        emoji: '📦️'
      },
      {
        value: 'ci',
        name: 'ci:       🎡  Changes to our CI configuration files and scripts',
        emoji: '🎡'
      },
      {
        value: 'chore',
        name: "chore:    🔨  Other changes that don't modify src or test files",
        emoji: '🔨'
      },
      {
        value: 'revert',
        name: 'revert:   ⏪️  Reverts a previous commit',
        emoji: '⏪️'
      }
      // 中文版
      // { value: "特性", name: "特性:   🚀  新增功能", emoji: "🚀" },
      // { value: "修复", name: "修复:   🧩  修复缺陷", emoji: "🧩" },
      // { value: "文档", name: "文档:   📚  文档变更", emoji: "📚" },
      // { value: "格式", name: "格式:   🎨  代码格式(不影响功能,例如空格、分号等格式修正)", emoji: "🎨" },
      // { value: "重构", name: "重构:   ♻️  代码重构(不包括 bug 修复、功能新增)", emoji: "♻️" },
      // { value: "性能", name: "性能:   ⚡️  性能优化", emoji: "⚡️" },
      // { value: "测试", name: "测试:   ✅  添加疏漏测试或已有测试改动", emoji: "✅" },
      // { value: "构建", name: "构建:   📦️  构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)", emoji: "📦️" },
      // { value: "集成", name: "集成:   🎡  修改 CI 配置、脚本", emoji: "🎡" },
      // { value: "回退", name: "回退:   ⏪️  回滚 commit", emoji: "⏪️" },
      // { value: "其他", name: "其他:   🔨  对构建过程或辅助工具和库的更改(不影响源文件、测试用例)", emoji: "🔨" }
    ],
    useEmoji: true,
    themeColorCode: '',
    scopes: [],
    allowCustomScopes: true,
    allowEmptyScopes: true,
    customScopesAlign: 'bottom',
    customScopesAlias: 'custom',
    emptyScopesAlias: 'empty',
    upperCaseSubject: false,
    allowBreakingChanges: ['feat', 'fix'],
    breaklineNumber: 100,
    breaklineChar: '|',
    skipQuestions: [],
    issuePrefixs: [{ value: 'closed', name: 'closed:   ISSUES has been processed' }],
    customIssuePrefixsAlign: 'top',
    emptyIssuePrefixsAlias: 'skip',
    customIssuePrefixsAlias: 'custom',
    allowCustomIssuePrefixs: true,
    allowEmptyIssuePrefixs: true,
    confirmColorize: true,
    maxHeaderLength: Infinity,
    maxSubjectLength: Infinity,
    minSubjectLength: 0,
    scopeOverrides: undefined,
    defaultBody: '',
    defaultIssues: '',
    defaultScope: '',
    defaultSubject: ''
  }
}

然后测试

git add .
git cz

微信图片_20230612200901.png

9.3 一键提交

我们还可以通过一个script来集成之前所有的这些步骤:

"scripts": {
    // ...
    "commit": "git pull && git add -A && git-cz && git push",
}

现在,我们只需要执行 pnpm run commit 即可完成代码的质量检测、style format、代码提交规范等一系列流程了。

10、change-log

10.1 简单使用

安装 standard-versiongithub地址

pnpm add standard-version -D

自动化升级版本号、生成 changelogtag

添加到 package.json 脚本命令

"scripts": {
    // ...
    "release": "standard-version"
}

通过 pnpm run release,生成日志。

10.2 高级用法

10.2.1 这个东西可以做什么?

  • 自动升级版本
  • 自动打 tag
  • 自动生成 changelog

10.2.2 自动升级版本

1. 版本构成

版本号 major.minor.patch

2. 默认的版本更新规则

主版本号.次版本号.修订号,版本号递增规则如下:

  • 主版本号(major):当你做了不兼容的 API 修改,
  • 次版本号(minor):当你做了向下兼容的功能性新增,可以理解为 Feature 版本,
  • 修订号(patch):当你做了向下兼容的问题修正,可以理解为 Bug fix 版本。

先行版本号可以加到 “主版本号.次版本号.修订号” 的后面,作为延伸。

3. 先行版本

当即将发布大版本改动前,但是又不能保证这个版本的功能 100% 正常,这个时候可以发布先行版本:

  • alpha: 内部版本
  • beta: 公测版本
  • rc: 候选版本(Release candiate)

比如:1.0.0-alpha.01.0.0-alpha.11.0.0-rc.01.0.0-rc.1等。

standard-verstion 生成的 CHANGELOG 只会包含 featfixBREACK-CHANGE 类型的提交记录:

{
  scripts: {
    "release": "standard-version",
    "release:alpha": "standard-version --prerelease alpha",
    "release:rc": "standard-version --prerelease rc",
    "release:major": "pnpm run release -- --release-as major",
    "release:minor": "pnpm run release -- --release-as minor",
    "release:patch": "pnpm run release -- --release-as patch"
  }
}

10.2.3 手动控制版本更新

1. 直接升级major

"scripts": {
    "release-major": "standard-version --release-as major",
}

2. 直接升级minor

"scripts": {
    "release-minor": "standard-version --release-as minor",
}

3. 直接升级patch

"scripts": {
    "release-patch": "standard-version --release-as patch",
}

4. 按默认规则升级版本号

"scripts": {
    "release": "standard-version",
}

5. 强制打一个静态版本号

"scripts": {
    "release-static": "standard-version --release-as 3.3.3",
}

第一个版本(该方式不会升级版本号)

# npm run script
pnpm run release -- --first-release
# global bin
standard-version --first-release
# npx
npx standard-version --first-release

10.2.4 配置哪些commit消息写入changelog

hidden 属性值控制是否将该类型的 commit 消息写入 changlog, 不填的情况下默认是: false,在根目录下新建 .versionrc.js

module.exports = {
  types: [
    { type: 'feat', section: '✨ Features | 新功能' },
    { type: 'fix', section: '🐛 Bug Fixes | Bug 修复' },
    { type: 'init', section: '🎉 Init | 初始化' },
    { type: 'docs', section: '✏️ Documentation | 文档' },
    { type: 'style', section: '💄 Styles | 风格' },
    { type: 'refactor', section: '♻️ Code Refactoring | 代码重构' },
    { type: 'perf', section: '⚡ Performance Improvements | 性能优化' },
    { type: 'test', section: '✅ Tests | 测试' },
    { type: 'revert', section: '⏪ Revert | 回退', hidden: true },
    { type: 'build', section: '📦‍ Build System | 打包构建' },
    { type: 'chore', section: '🚀 Chore | 构建/工程依赖/工具' },
    { type: 'ci', section: '👷 Continuous Integration | CI 配置' }
  ]
}

10.2.5 配置跳过生成changelog这个步骤

所有可配置跳过的有: bump, changelog, commit, tag:

{
  "standard-version": {
    "skip": {
      "changelog": true
    }
  }
}

至此,我们就完成了脚手架的代码质量和 git 提交规范的配置。就当前的脚手架已具备基本的 React 项目的配置,可以作为大多数项目的基础架子了~

end~

相关文章
|
3月前
|
前端开发 JavaScript
React项目路由懒加载lazy、Suspense,使第一次打开项目页面变快
本文介绍了在React项目中实现路由懒加载的方法,使用React提供的`lazy`和`Suspense`来优化项目首次加载的速度。通过将路由组件改为懒加载的方式,可以显著减少初始包的大小,从而加快首次加载速度。文章还展示了如何使用`Suspense`组件包裹`Switch`来实现懒加载过程中的fallback效果,并提供了使用前后的加载时间对比,说明了懒加载对性能的提升作用。
256 2
React项目路由懒加载lazy、Suspense,使第一次打开项目页面变快
|
3月前
|
前端开发 JavaScript Java
SpringBoot项目部署打包好的React、Vue项目刷新报错404
本文讨论了在SpringBoot项目中部署React或Vue打包好的前端项目时,刷新页面导致404错误的问题,并提供了两种解决方案:一是在SpringBoot启动类中配置错误页面重定向到index.html,二是将前端路由改为hash模式以避免刷新问题。
313 1
|
1月前
|
前端开发 JavaScript
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
|
3月前
|
移动开发 前端开发
react项目配合diff实现文件对比差异功能
在React项目中,可以使用`diff`库实现文件内容对比差异功能。首先安装`diff`库,然后在组件中引入并使用`Diff.diffChars`或`Diff.diffLines`方法比较文本差异。通过循环遍历`diff`结果,可以生成不同样式的HTML元素来高亮显示文本差异。
160 1
react项目配合diff实现文件对比差异功能
|
3月前
|
前端开发 算法 JavaScript
React项目input输入框输入自动失去焦点
本文讨论了在React项目中如何处理input输入框自动失去焦点的问题,特别是在移动端开发中。文章提供了一个使用React Native的TouchableWithoutFeedback组件来监听点击事件,并在事件处理函数中通过调用Keyboard.dismiss()方法使输入框失去焦点的示例代码。这种方法可以确保在用户点击页面其他区域时,键盘能够收起,输入框失去焦点。
126 1
React项目input输入框输入自动失去焦点
|
3月前
|
JavaScript 前端开发 应用服务中间件
本地运行打包好的React、Vue项目
本文讨论了如何本地运行打包好的React和Vue项目,并解决了使用React-Router时Tomcat部署刷新页面导致404的问题,提出了将请求转回index.html的解决方案。
40 1
本地运行打包好的React、Vue项目
|
2月前
|
前端开发 JavaScript 应用服务中间件
linux安装nginx和前端部署vue项目(实际测试react项目也可以)
本文是一篇详细的教程,介绍了如何在Linux系统上安装和配置nginx,以及如何将打包好的前端项目(如Vue或React)上传和部署到服务器上,包括了常见的错误处理方法。
758 0
linux安装nginx和前端部署vue项目(实际测试react项目也可以)
|
3月前
|
资源调度 JavaScript 前端开发
使用vite+react+ts+Ant Design开发后台管理项目(二)
使用vite+react+ts+Ant Design开发后台管理项目(二)
|
2月前
|
Java Shell 开发工具
git集成IDEA,托管项目实现版本管理
git集成IDEA,托管项目实现版本管理
39 0
|
3月前
|
缓存 前端开发 JavaScript
在react项目中实现按钮权限createContext && useContext
文章介绍了在React项目中如何使用`createContext`和`useContext`来实现按钮级别的权限控制。
81 0