# mofish-react-template **Repository Path**: mcfish/mofish-react-template ## Basic Information - **Project Name**: mofish-react-template - **Description**: 基于cra生成typescript模板,使用craco管理配置,统一代码风格、样式风格、代码提交等前端规范 - **Primary Language**: TypeScript - **License**: Not specified - **Default Branch**: dev-1.0 - **Homepage**: https://gitee.com/mcfish/mofish-react-template - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-05-23 - **Last Updated**: 2022-08-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 创建react项目 ```js npx create-react-app my-app --template typescript ``` ### [Craco](https://www.npmjs.com/package/@craco/craco) #### 使用craco来重写cra配置 1. 安装 ```js npm i @craco/craco - D ``` 2. 修改package.json文件 ```js "scripts": { "start": "craco start", "build": "craco build", "test": "craco test", "eject": "craco eject" }, ``` 3. 新增craco.config.ts 文件 (**项目根目录下新建**) ```js const config = () => ({ // 编写修改webpack配置,可以参考craco,和webpack的语法 }) export default config ``` 或者新增craco.config.js文件 ```js module.exports = () => ({ // 编写修改webpack配置,可以参考craco,和webpack的语法 }) ``` #### 支持less和装饰器语法 1. 安装 ```js npm i craco-less -D npm i @babel/plugin-proposal-decorators -D ``` 2. 修改craco.config.js 文件 ```js // 使用less插件 const CracoLessPlugin = require('craco-less'); const config = () => ({ // 编写修改webpack配置,可以参考craco,和webpack的语法 plugins: [ { plugin: CracoLessPlugin, options: { lessLoaderOptions: { lessOptions: { // 修改主题色 modifyVars: { '@primary-color': '#4578FA' }, javascriptEnabled: true, }, }, }, }, ], babel: { // 支持装饰器模式语法 plugins: [ ["@babel/plugin-proposal-decorators", { legacy: true }] ] } }) export default config ``` #### [设置别名](https://juejin.cn/post/6990896895077908487) **问题背景**:使用cra创建的项目每一次重启都会重置tsconfig.json, 导致在tsconfig.json设置的别名失效。 1. 安装 ```js npm i craco-alias -D ``` 2. 新建tsconfig.path.json (**项目根目录下新建**) ```js { "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"], "Components": ["src/components"] } } } ``` 3. craco.config.ts **CracoAlias** 配置为 ```js const aliasPlugin = require('craco-alias') const config = () => ({ ... plugins:[ { plugin: aliasPlugin, options: { source: 'tsconfig', baseUrl: '.', tsConfigPath: './tsconfig.path.json', }, }, ] ... }) export default config ``` 4. tsconfig.json 文件插入 ```js "extends": "./tsconfig.path.json", ``` #### 规范代码风格 [ESLint 与 Prettier 配合使用](https://juejin.cn/post/6924568874700505102) 两者配合使用,eslint进行代码质量检验,prettier进行自动格式化代码 1. 安装 ```js npm i -D eslint prettier eslint-config-prettier eslint-plugin-prettier ``` 2. 项目根目录添加 .eslintrc.js 和 .prettierrc ```JS // .eslintrc.js { "extends": ['plugin:prettier/recommended'] // 覆盖eslint格式配置,写在最后 } ``` ```JS // .prettierrc { "printWidth": 100, // 指定代码长度,超出换行 "tabWidth": 2, // tab 键的宽度 "useTabs": false, // 不使用tab "semi": false, // 结尾加上分号 "singleQuote": true, // 使用单引号 "quoteProps": "as-needed", // 要求对象字面量属性是否使用引号包裹,(‘as-needed’: 没有特殊要求,禁止使用,'consistent': 保持一致 , preserve: 不限制,想用就用) "jsxSingleQuote": false, // jsx 语法中使用单引号 "trailingComma": "es5", // 确保对象的最后一个属性后有逗号 "bracketSpacing": true, // 大括号有空格 { name: 'rose' } "jsxBracketSameLine": false, // 在多行JSX元素的最后一行追加 > "arrowParens": "always", // 箭头函数,单个参数添加括号 "requirePragma": false, // 是否严格按照文件顶部的特殊注释格式化代码 "insertPragma": false, // 是否在格式化的文件顶部插入Pragma标记,以表明该文件被prettier格式化过了 "proseWrap": "preserve", // 按照文件原样折行 "htmlWhitespaceSensitivity": "ignore", // html文件的空格敏感度,控制空格是否影响布局 "endOfLine": "auto" // 结尾是 \n \r \n\r auto } ``` 3. 添加eslint自定义规则(和prettier不冲突) 1. 安装自定义解析器 ```js npm i -D babel-eslint @typescript-eslint/parser ``` 2. 配置 ```js module.exports = { settings: { // 在eslintrc.js中指定react版本 react: { version: 'detect' } }, plugins: ['react'], // 配置插件 parser: '@typescript-eslint/parser', // 指定自定义解析器为ts-eslint extends: ['plugin:prettier/recommended'], // 继承 扩展配置文件 parserOptions: { parser: 'babel-eslint', // 指定解析器选项 ecmaVersion: 6, sourceType: 'module', // 默认script,可选module ecmaFeatures: { // 其他语言特性 experimentalObjectRestSpread: true, // ...rest参数和扩展扩算符 jsx: true, modules: true, }, }, env: { // 指定环境 es6: true, node: true, browser: true, }, // 布尔值false和字符串值"readable"等价于"readonly" // 布尔值true和字符串值"writeable"等价于"writable" globals: { // 指定全局变量 React: true, document: false, navigator: false, window: false, DEV: true, TEST: true, PRE: true, PRO: true, }, rules: { /** * @description 规则 ID 可以设置的值 * “off” 或 0 - 关闭规则 * “warn” 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出) * “error” 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出) */ /** * Possible Errors * 这些规则与 JavaScript 代码中可能的错误或逻辑错误有关 * https://cn.eslint.org/docs/rules/#possible-errors */ 'no-cond-assign': 2, // 条件不能有赋值 'no-control-regex': 2, // reg中不能有控制符号 'no-console': process.env.NODE_ENV === 'production' ? 1 : 0, // node环境prod禁用 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, // node环境prod禁用 'no-dupe-args': 2, // 参数不能重复 'no-dupe-keys': 2, // 对象key不能重复 'no-duplicate-case': 2, // switch不能有重复case 'no-empty-character-class': 2, // reg中不能有空字符串 'no-ex-assign': 2, // 不能复制catch中的error 'no-extra-boolean-cast': 2, // 禁止多余的Boolean转换 'no-extra-parens': [2, 'functions'], // 函数中禁止多余的括号 'no-func-assign': 2, // 禁止赋值函数 'no-inner-declarations': [2, 'functions'], // 禁止在条件中声明function 'no-invalid-regexp': 2, // 禁止无用的reg 'no-irregular-whitespace': 2, // 禁止不规则空格 'no-unsafe-negation': 2, // !(key in object)->yes, !key in object->no 'no-obj-calls': 2, // 禁止calling全局对象属性,如Math/JSON 'no-regex-spaces': 2, // 禁止reg出现多个空格 'no-sparse-arrays': 2, // array不能用空元素 'no-unexpected-multiline': 2, // 禁止有疑义的多行表达式 'no-unreachable': 2, // return/throw等之后不应有表达式 'no-unsafe-finally': 2, // 禁止不安全的finally 'use-isnan': 2, // 使用isNaN 'valid-typeof': 2, // typeof的字符串必须正确 /** * Best Practices * 这些规则是关于最佳实践的,帮助你避免一些问题 * https://cn.eslint.org/docs/rules/#best-practices */ 'accessor-pairs': 2, // getter/setter成对出现 'dot-location': [2, 'property'], // .的位置可以在换行 eqeqeq: [2, 'allow-null'], // 必须===, null除外 'no-caller': 2, // 禁止caller/callee 'no-empty-pattern': 2, // 解构不能有空解构模式 'no-eval': 2, // 不能用eval 'no-extend-native': 2, // 不能扩展Object原型 'no-extra-bind': 2, // bind的函数体中要有明确的this 'no-fallthrough': 2, // switch需要break 'no-floating-decimal': 2, // float中0不能省略 'no-implied-eval': 2, // 禁止隐性eval 'no-iterator': 2, // 禁止使用__iterator__属性 'no-labels': [2, { allowLoop: false, allowSwitch: false }], // 禁止label表达式 'no-lone-blocks': 2, // 禁止无用的{} 'no-multi-spaces': 1, // 禁止多空格 'no-multi-str': 2, // 禁止多行的string 'no-global-assign': 2, // 禁止赋值原生对象(window/Object...) 'no-new-wrappers': 2, // String/Number等不能用new 'no-octal': 2, // 禁止八进制文字 'no-octal-escape': 2, // 禁止八进制转义 'no-proto': 2, // 禁止使用__proto__ 'no-redeclare': 2, // 禁止重新复制var 'no-return-assign': [2, 'except-parens'], // 禁止return中赋值 'no-self-assign': 2, // 禁止自身赋值 'no-self-compare': 2, // 禁止自身比较, 如果NaN->Number.isNaN 'no-sequences': 2, // 禁止,操作符 'no-throw-literal': 2, // 禁止直接throw内容,必须是Error() 'no-unmodified-loop-condition': 2, // 循环中的变量要在循环中修改 'no-useless-call': 2, // 禁止无用的call 'no-with': 2, // 禁用with 'wrap-iife': [2, 'any'], // 立即调用的function必须有括号 yoda: [2, 'never'], // 条件中变量在前 'no-useless-escape': 0, // 不检查escape 'no-new-func': 0, // 禁止对 Function 对象使用 new 操作符 'no-param-reassign': 0, // 禁止对 function 的参数进行重新赋值 'consistent-return': 0, // 要求 return 语句要么总是指定返回的值,要么不指定 'class-methods-use-this': 0, // 强制类方法使用 this 'array-callback-return': 0, // 数值循环显示return 'no-unused-expressions': 0, // func && func() 'no-loop-func': 0, // 禁止在loop内写循环函数 /** * Variables * 这些规则与变量声明有关 * https://cn.eslint.org/docs/rules/#variables */ 'no-delete-var': 2, // 不能delete变量,可以用在对象 'no-label-var': 2, // 禁止label var 'no-shadow-restricted-names': 2, // 禁止跟踪严格模式下部分关键词 'no-restricted-globals': 0, // 禁用特定的全局变量 // 'no-undef': 2, // 禁止使用未赋值变量 'no-undef-init': 2, // 变量不能初始化为undefined 'no-unused-vars': [0, { vars: 'all', args: 'none' }], // 禁止不使用的变量,参数可以 'no-use-before-define': [2, { functions: false, classes: true, variables: true }], // 未定义不能使用 'no-shadow': 0, // 禁止变量声明与外层作用域的变量同名 /** * ECMAScript 6 * 这些规则只与 ES6 有关, 即通常所说的 ES2015 * https://cn.eslint.org/docs/rules/#ecmascript-6 */ 'arrow-spacing': [1, { before: true, after: true }], // 箭头函数前后有空格 'constructor-super': 1, // super()在必须构造函数内 curly: [2, 'multi-line'], // if/while等函数可以多行不带{} 'generator-star-spacing': [2, { before: true, after: true }], // generator函数前后有空格 'no-class-assign': 2, // 禁止赋值class 'no-const-assign': 2, // 禁止赋值常量(const) 'no-dupe-class-members': 2, // class中方法不能有重复 'no-new-symbol': 2, // new Symbol(xxx)->no 'no-this-before-super': 2, // super()前不能用this 'no-useless-computed-key': 2, // 禁止无用的计算属性 'no-useless-constructor': 2, // 禁止无用的constructor 'template-curly-spacing': [2, 'never'], // 模版字符串中变量无空格 'yield-star-spacing': [2, 'both'], // yield的*前后有空格 'prefer-const': 0, // 能用const场景用const 'arrow-parens': [2, 'as-needed'], // 要求箭头函数的参数使用圆括号 'arrow-body-style': 0, // 要求箭头函数体使用大括号 'no-confusing-arrow': [2, { allowParens: true }], // 禁止在可能与比较操作符相混淆的地方使用箭头函数 'object-shorthand': [2, 'properties', { avoidQuotes: true }], // 要求或禁止对象字面量中方法和属性使用简写语法 'prefer-destructuring': 1, // 解构 /** * Node.js and CommonJS * 这些规则是关于Node.js 或 在浏览器中使用CommonJS 的 * https://cn.eslint.org/docs/rules/#nodejs-and-commonjs */ 'handle-callback-err': [2, '^(err|error)$'], // 有err/error必须处理异常 'no-new-require': 2, // new require(xxx)->no 'no-path-concat': 2, // __dirname和__filename禁止string拼接 'global-require': 0, // 要求 require() 出现在顶层模块作用域中 /** * eslint-plugin-react * https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules */ 'react/jsx-uses-react': 2, 'react/prefer-es6-class': 1, // 禁止使用ES5语法创建React组件 'react/prefer-stateless-function': 1, // 组件没有状态或是没有引用refs,推荐使用无状态组件(函数声明)而不是类 'react/jsx-pascal-case': 2, // 组件名称使用帕斯卡命名法 'react/jsx-closing-bracket-location': 1, // 自关闭的jsx标签代码对齐格式 'react/jsx-tag-spacing': 1, // 自关闭的标签前加一个空格 'react/jsx-curly-brace-presence': 1, // 不需要多余的 去掉props和children多余的花括号,如title={"标题"}和
{"标题"}
'react/self-closing-comp': [1, { component: true, html: false }], // 没有子元素的标签总是自关闭标签 'react/jsx-curly-spacing': 1, // 不要在props的{}里两边加空格 'react/jsx-equals-spacing': 1, // props属性不允许等号两边加空格 'react/jsx-indent-props': [1, 2], // props缩进格式 'react/jsx-uses-vars': 2, // 防止在JSX中使用的变量被错误地标记为未使用 'react/jsx-boolean-value': 1, // boolean类型props属性不需要加 ={true} 'react/no-string-refs': 1, // ref里使用回调函数 'react/no-children-prop': 1, // 不允许在props添加children属性 'react/no-danger-with-children': 1, // 阻止chidren和dangerouslySetInnerHTML={{ __html: "HTML" }}同时使用 'react/no-deprecated': 1, // 阻止使用旧版本即将废弃的api 'react/no-did-mount-set-state': 1, // 阻止在componentDidMount中使用this.setState() 'react/no-did-update-set-state': 1, // 阻止在componentDidUpdate中使用this.setState() 'react/no-direct-mutation-state': 1, // 禁止直接修改state 'react/no-find-dom-node': 0, // 禁用 findDOMNode 'react/no-is-mounted': 1, // 禁用 isMounted 'react/no-multi-comp': 0, // 阻止一个文件定义多个组件 'react/no-typos': 1, // 检测错误的组件生命周期名称,以及组件静态属性,主要是大小写 'react/no-this-in-sfc': 0, // 阻止在无状态组件中使用this // 'react/no-redundant-should-component-update': 1, // 阻止在纯组件中使用shouldComponentUpdate 'react/no-unescaped-entities': 1, // jsx防止无效字符,比如 } " ' 'react/no-unknown-property': 1, // 防止使用未知的DOM属性 'react/no-unused-state': 1, // 防止定义了state却未使用 'react/no-will-update-set-state': 1, // 防止在componentWillUpdate中使用this.setState 'react/jsx-no-duplicate-props': [1], // 重复props属性 'react/jsx-key': [1], // 渲染array需要key 'react/jsx-indent': [1, 2], // jsx缩进2个空格 'react/react-in-jsx-scope': 1, // 防止未引入react就使用jsx 'react/style-prop-object': 1, // props的style属性必须是个object 'react/void-dom-elements-no-children': 1, // 自关闭的element不允许添加children ,如
'react/jsx-no-bind': 0, 'react/jsx-first-prop-new-line': 0, 'react/jsx-filename-extension': 0, 'react/destructuring-assignment': 0, 'react/prop-types': 0, 'react/forbid-prop-types': 0, 'react/jsx-props-no-spreading': 0, 'react/static-property-placement': 0, /** * eslint-plugin-import * https://github.com/benmosher/eslint-plugin-import/tree/master/docs/rules */ 'import/no-unresolved': 0, 'import/no-extraneous-dependencies': 0, 'import/prefer-default-export': 0, 'import/no-mutable-exports': 0, 'import/no-named-as-default': 0, // 'import/extensions': 0, /** * eslint-plugin-jsx-a11y * https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules */ 'jsx-a11y/anchor-is-valid': 0, 'jsx-a11y/click-events-have-key-events': 0, 'jsx-a11y/no-static-element-interactions': 0, 'jsx-a11y/mouse-events-have-key-events': 0, 'jsx-a11y/no-noninteractive-element-interactions': 0, } } ``` 4. 如果有使用到一些 ESLint 插件(如eslint-plugin-flowtype),需要禁掉这些插件中与 Prettier 冲突,所以需要添加 "prettier/flowtype"。 ```JS // .eslintrc.js { "extends": [ "plugin:prettier/recommended", "prettier/flowtype", ] } ``` 到这里,我们的项目中的eslint + prettier 的规则配置基本就完成了。 我们基本已经可以实现对老的代码和新的添加的代码实现了格式化的效果,然后就能愉快的写代码了 #### [规范样式风格](https://juejin.cn/post/6940127032932040735) [Stylelint](https://stylelint.bootcss.com/) 是一个强大、先进的 CSS 代码检查器(linter),可以帮助你规避 CSS 代码中的错误并保持一致的编码风格 1. 安装 ```js npm i -D stylelint stylelint-config-standard stylelint-order ``` 2. 项目根目录下新建`.stylelintrc.js`文件 ```js module.exports = { "extends": [ "stylelint-config-standard" ], "plugins": [ "stylelint-order" ], "rules": { // 颜色指定大写 "color-hex-case": "upper", // 禁止空块 'block-no-empty': true, // 颜色6位长度 "color-hex-length": "long", // 兼容自定义标签名 "selector-type-no-unknown": [true, { "ignoreTypes": [] }], // 忽略伪类选择器 ::v-deep "selector-pseudo-element-no-unknown": [true, { "ignorePseudoElements": ["v-deep"] }], // 禁止低优先级的选择器出现在高优先级的选择器之后。 "no-descending-specificity": null, // 不验证@未知的名字,为了兼容scss的函数 "at-rule-no-unknown": null, // 禁止空注释 "comment-no-empty": true, // 禁止简写属性的冗余值 "shorthand-property-no-redundant-values": true, // 禁止值的浏览器引擎前缀 "value-no-vendor-prefix": true, // property-no-vendor-prefix "property-no-vendor-prefix": true, // 禁止小于 1 的小数有一个前导零 "number-leading-zero": "never", // 禁止空第一行 "no-empty-first-line": true, // 属性的排序 "order/properties-order": [ "position", "top", "right", "bottom", "left", "z-index", "display", "justify-content", "align-items", "float", "clear", "overflow", "overflow-x", "overflow-y", "margin", "margin-top", "margin-right", "margin-bottom", "margin-left", "border", "border-style", "border-width", "border-color", "border-top", "border-top-style", "border-top-width", "border-top-color", "border-right", "border-right-style", "border-right-width", "border-right-color", "border-bottom", "border-bottom-style", "border-bottom-width", "border-bottom-color", "border-left", "border-left-style", "border-left-width", "border-left-color", "border-radius", "padding", "padding-top", "padding-right", "padding-bottom", "padding-left", "width", "min-width", "max-width", "height", "min-height", "max-height", "font-size", "font-family", "font-weight", "text-align", "text-justify", "text-indent", "text-overflow", "text-decoration", "white-space", "color", "background", "background-position", "background-repeat", "background-size", "background-color", "background-clip", "opacity", "filter", "list-style", "outline", "visibility", "box-shadow", "text-shadow", "resize", "transition" ], } } ``` 3. 忽略stylelint对css的检验 ```css # 忽略整个文件,在首行加入 `/* stylelint-disable */` /* stylelint-disable */ html {} # 忽略多行 /* stylelint-disable */ html {} .div { color: red; } /* stylelint-enable */ # 忽略一行, 在样式前加入 `/* stylelint-disable-next-line */` 以忽略该行 #id { /* stylelint-disable-next-line */ color: pink !important; } # 在 `.stylelintrc.js` 內设定需要忽略的文件 { ignoreFiles: ["dist/**/*", "src/assets/scss/abc.scss"] } ``` 4. vscode配置 1. 安裝 StyleLint 2. 在 `settings.json` 文件设置, `ctrl` + `shift` + `p` --> open setting (json)进行**配置** ```json { "editor.codeActionsOnSave": { "source.fixAll.stylelint": true } } ``` 设置完之后,在vscode就可以有提示了,也保存自动修复了 #### 规范代码提交 使用 husky、lint-staged 和 commitlint 来规范前端代码提交 ##### [husky](https://www.npmjs.com/package/husky) Husky 是一款 [Git Hooks](https://git-scm.com/docs/githooks) 工具,可以在执行特定的 git 命令时(如: git commit, git push)触发对应的脚本。 由于钩子可以在`git commit`中触发,所以我们可以在提交到暂缓区时,做一些lint 检查、单元测试、代码美化等操作。 1. 安装 ```js npm i husky -D ``` 2. 启用 git hooks ```js npx husky install ``` 3. 加入 husky prepare 命令 方式 1:直接执行如下命令 ```js npm set-script prepare "husky install" ``` 方式 2:直接在 `package.json` 的 `scripts` 里加上如下命令: ```json { "scripts": { "prepare": "husky install" } } ``` 4. 使用 husky 使用 husky 的时候,我们通常只关注 *提交工作流* 的几个 hooks,用得最多的一个是 `pre-commit`。 使用 hosky 的时候,通常是用它来创建一系列的 git hooks,并在对应的文件中撰写 `shell` 脚本代码 例如:创建了 `pre-commit` hook 文件 ```js # 创建一个 pre-commit 的 hooks 文件 npx husky add .husky/pre-commit "npx lint-staged" # 创建好这个文件之后,你就可以根据你的需要去编写这个 shell 脚本了 ``` ##### [lint-staged](https://www.npmjs.com/package/lint-staged) `lint-staged` 是一个专门用于在通过 `git` 提交代码之前,对暂存区的代码执行一系列的格式化。 当 `lint-staged` 配合 git hooks 使用时,可以在 git 提交前的 hook 中加入 `lint-staged` 命令,这样就能在提交代码之前,对即将提交的代码进行格式化,成功之后就会提交代码。 1. 安装 ```js npm i lint-staged -D ``` 2. 项目根目录下新建`.lintstagedrc`文件 ```json { "./src/**/*.{ts,tsx}": "eslint --fix" } ``` 3. 配合husky使用 在husky的`pre-commit` shell文件中编写内容 ```shell #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" # 下面的内容就是执行lint-staged的命令 npx lint-staged ``` 如果husky的`pre-commit` shell文件不存在,执行下面npx命令创建 ```js # 创建一个 pre-commit 的 hooks 文件 npx husky add .husky/pre-commit "npx lint-staged" # 创建好这个文件之后,你就可以根据你的需要去编写这个 shell 脚本了 ``` ##### [commitlint](https://commitlint.js.org/#/) 用来检查git提交记录是否满足固定格式的工具 **为什么需要规范commit日志** 1. commit message 是程序员开发的日常操作, 但是实际工作中却常常被大家忽略 2. 目前commit message 处于五花八门的书写风格,十分不利于阅读和维护 3. 优秀的互联网科技公司都有一套代码提交规范,尤其是在一些大型[开源项目](https://so.csdn.net/so/search?q=开源项目&spm=1001.2101.3001.7020)中,commit message 都是十分一致 **规范commit日志的好处** 1. 团队形成一致的代码提交风格,更好的提高工作效率 2. 规范的 commit message 有助于团队其它人员 review, 还可以有效的输出 `changelog`, 对项目十分重要 3. 成为一名有追求的工程师 **使用步骤** 1. 安装 ```js npm i -D @commitlint/config-conventional @commitlint/cli ``` 2. 项目根目录下新建`commitlint.config.js`文件 ```JSON module.exports = { extends: ['@commitlint/config-conventional'], rules: { 'type-enum': [ 2, 'always', ['upd', 'feat', 'fix', 'refactor', 'docs', 'chore', 'style', 'revert'], ], 'type-case': [0], 'type-empty': [0], 'scope-empty': [0], 'scope-case': [0], 'subject-full-stop': [0, 'never'], 'subject-case': [0, 'never'], 'header-max-length': [2, 'always', 72], }, } ``` 3. 配合husky使用 创建了 `commit-msg` hook 文件 ```shell # 创建一个 commit-msg 的 hooks 文件 npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1" ``` 到这里,我们基本已经可以实现对git commit提交的代码进行限制了,然后就能愉快的提交代码了 #### 配置生成环境 ##### react打包不生成sourceMap 在根目录新建一个`.env.production`文件,里面写上`GENERATE_SOURCEMAP=false`,这是最不具破坏性的。 环境变量是个好东西 ```shell # .env.production文件内容 GENERATE_SOURCEMAP=false ```