Recently, the project team is not very busy. In order to practice what I have learned and absorb and optimize, I decided to standardize and optimize the existing projects of the project team, which is also responsible for the project code. Here I will make a record.

Set up the React project manually

An introduction to

This article records the standard optimization and upgrading based on the code of the online project, which is also my own remedy for the code of the project I handled. For the project to be optimized, it involves the following points of knowledge:

  • Developing in Typescript (ts is cool, I’ve read some documentation about it, but I haven’t done it in a specific project, so I don’t really know what it’s like)
  • 8, Coding ESLint+Prettier (actually my responsibility, I turned off the ESLint specification at the beginning of the project because I was annoyed by too many ESLint errors, which I now think is not only irresponsible for the project, but also for myself, for the team, for the future monkeys, so, Establish this specification even if it is painful to use now.)
  • Coding specification and specification documentation, documentation of related configuration files
  • Unit Testing (core business modules)
  • Specification of writing advanced components, use of advanced components (normalizing and rationalizing, such as writing with decorators, rational use of advanced components according to business)
  • Exception error in project (including abnormal component error, error bounds of optimization, optimization category), abnormal for rendering (component rendering exception handling) related content of “error bounds” application in the project (if the rendering is unusual, in the absence of any downgrade protection measures, page will display directly hang. You can use getDerivedStateFromError and componentDidCatch internally, as well as error boundary prevention and padding for integrity purposes.)
  • The introduction of mockjs
  • According to the above optimization, custom writing front-end scaffolding
  • Build front-end public component library (for a long time, our project could reuse components with cutting business boundary is not clear, can reuse components without clear classification according to the function of the component, in engineering practice in the process of building the project directory, there is no clear arrangement is built, these problems and so on, was already abandon and criticized by in my mind, However, I have no time to replan and reorganize. During this leisure time and my promotion period, I replan and standardize the module that I always dislike.)
  • Sentry Error collection platform access (open source Sentry platform)
  • Sonar Builds (Whether it’s for project responsibility, team growth, project code delivery, or your own code quality specification, you really need a code quality analysis tool, so choose Sonarqube)
  • Performance optimization practices in projects

The above related knowledge points are the optimization points of our project. This article will continue to be written, because the project will continue to be optimized. The following figure shows the general implementation steps of the normalization and optimization of the whole project, as follows:Without further ado, let’s get to the show:

Include Typescript in your project

Introduce Typescript for reference:

  • React + TS project template
  • Get started with TypeScript in 5 minutes
  • The React project added TS
  • Use TypeScript in React
  • Configure TypeScript support in Babel 7
  • For more TS translation solutions, see Webpack translation Typescript’s existing solution

1. Install ts globally

The installation command is as follows:

npm i -g typescript
Copy the code

2. Create tsconfig. Json

The command is as follows:

tsc --init
Copy the code

The diagram below:

Tsconfig. json configuration parameters are as follows:

3. Install development environment dependencies

1. Older development environments

1. The following dependencies:

npm install --save-dev typescript @types/react @types/react-dom @types/react-router-dom ts-loader
Copy the code

2. The following is an example of the Webpack configuration file:

module.exports = { context: ... , entry: ... , output: ... Resolve resolve: {Extensions: ['.ts', '.tsx', '.js']}, module: {loaders: [// add new loaders {test: /\.tsx?$/, loaders: ['babel-loader', 'ts-loader'] }, ... ]  }, plugins: ... };Copy the code

The following error is reported when running the project:

The following dependencies are installed:

It is speculated that this error is caused by the excessively high version of TS-Loader. Since TS-Loader scheme is not used, no further investigation is made.

2. New development environment

1. The following dependencies:

npm install --save-dev typescript @types/react @types/react-dom @babel/preset-typescript @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/core @babel/preset-env
Copy the code

2. Package. json items are set as follows:

{" name ":" inforserver ", "version" : "1.0.0", "description" : "information service platform", "main" : "index. Js", "scripts" : {" test ": "echo \"Error: no test specified\" && exit 1", "dev": "Webpack - the dev server -- config. / config/webpack dev. Config. Js - host 0.0.0.0", "build" : "webpack -p --config ./config/webpack.prod.config.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies" : {" antd ":" ^ 3.22.2 ", "axios" : "^ 0.19.0", "crypto - js" : "^ 4.0.0", "echarts" : "4.9.0", "happypack" : "^ 5.0.1," "hard - source - webpack - plugin" : "^ 0.13.1", the "immutable" : "^ 4.0.0 - rc. 12", "js - cookies" : "^ 2.2.1", "" : "^ 2.24.0 prop -", "types" : "latest", "qs" : "^ 6.8.0", "react" : "^ 16.9.0", "the react - cookies" : "^ while", "the react - dom" : "^ 16.9.0", "the react - loadable" : "^ 5.5.0", "the react - redux" : "^ 7.1.1", "the react - the router" : "^ 5.0.1", "the react - the router - dom" : "^ 5.0.1", "story" : "^ 4.0.4", "story - persist" : "^ 6.0.0", "the story - persist - transform - immutable" : "^ 5.0.0", "the story - thunk" : "^2.3.0"}, "devDependencies": {"@babel/core": "^7.14.6", "@babel/ proposal-class-properties": "^ 7.14.5 @", "Babel/plugin - proposal - object - the rest - spread" : "^ 7.14.7", "@ Babel/plugin - syntax - dynamic - import" : "^ 7.8.3 @", "Babel/plugin - transform - runtime" : "^ 7.14.5", "@ Babel/preset - env" : "^ 7.5.5", "@ Babel/preset - react" : "^ 7.0.0 @", "Babel/preset - the typescript" : "^ 7.14.5", "@ SVGR/webpack" : "^ 5.3.1", "@ types/react" : "16.9.23", "@ types/react - dom" : "16.9.7", "@ types/react - the router - dom" : "5.1.3", "Babel - loader" : "^ 8.0.6 Babel - plugin -", "import" : "^ 1.13.3", "Babel - polyfill" : "^ 6.26.0", "the clean - webpack - plugin" : "^ 3.0.0 copy - webpack -", "plugins" : "^ 6.0.2", "CSS - loader" : "^ 3.2.0", "file - loader" : "^ 4.2.0", "HTML - webpack - plugin" : "^ 3.2.0", "less" : "^ 3.10.3", "less - loader" : "^ 5.0.0", "mini - CSS - extract - the plugin" : "^ 0.8.0", "node - sass" : "^ 4.12.0", "the react - countup" : "^ 4.3.3", "sass - loader" : "^ 8.0.0", "style - loader" : "^ 1.0.0", "terser - webpack - plugin" : "^ 4.2.0 typescript", ""," ^ 4.3.5 ", "uglifycss - loader" : "^ 1.0.2", "url - loader" : "^ 3.0.0", "webpack" : "^ 4.39.3 webpack -", "cli" : "^ 3.3.7", "webpack - dev - server" : "^ 3.8.0", "webpack - merge" : "^ 4.2.2 webpack - theme -", "color - replacer" : "^ 1.3.7"}}Copy the code

Among them:

Configure TypeScript support in Babel 7, use @babel/preset- TypeScript and @babel/preset-env to configure TypeScript compilation environment.

There are five packages to download and install. They are:

  • @babel/core
  • @babel/preset-env
  • @babel/preset-typescript
  • @babel/plugin-proposal-class-properties
  • @babel/plugin-proposal-object-rest-spread

It contains two plug-ins, plugin-proposal-class-properties and plugin-proposal-object-rest-spread, which are used to convert syntax features “class attributes” and “object expansion” respectively.

  1. Configure the Babel

Note: our project did not create the file.babelrc

The configuration is as follows:

Our project uses the HappyPack plug-in to improve the webpack build time, so the specific content of the WebPack configuration file is as follows:

The HappyPack configuration is as follows:

Pay attention toRun the Typescript project after completion if the following error occurs:

The following error is reported:

Typescript error “Cannot write file xxx because it would overwrite input file
Copy the code

This problem is basically caused by allowJs being enabled.

  • AllowJs allows the Typescript compiler to compile JS. The compiled output file, xxx.js, is the same as the source file.
  • So an error like “will overwrite the input file” is reported.

The solution is as follows:

I set the outDir parameter to point to the relevant location.

ESLint+Prettier Unified code style

1. The background

In a collaboration project, different developers write code style is different, such as whether to need to add a semicolon at the end of the line, line feeds, Spaces, tighten, scattered in the project of the console processing method, maximum length code line, etc., if there is no unified standard in the project will result in code style is multifarious, does not favor the code to read and maintain.

In order to have a uniform coding specification in the project, we used ESLint + Prettier for the constraint.

  • Add a uniform code specification using ESLint + Prettier
  • Format nonconforming files under existing projects
  • Configure the editor to automatically detect the specification validity of new or modified code

Introduction of ESLint+Prettier

  • Eslint +prettier
  • Build a React-hooks project from scratch
  • Husky uses summary
  • Husky 6.x and Lint-staged were introduced in the React project
  • Eslintrc file configuration
  • The React project added ESLint + Perttier as a code specification

2. Configure dependent environments and configuration files

1. Install eslint

ESLint has the following features:

  • The default rules contain all existing JSLint and JSHint rules and are easy to migrate;
  • High configurability: You can set two error levels: Warning and Error, or disable the rule directly.
  • Rules that include code style checks (JSCS can be dropped);
  • Support plug-in extension and custom rules.

ESLint configuration mode. You can configure ESLint in one of the following ways:

  • Use.eslintrc files (JSON and YAML syntax supported);
  • Add an eslintConfig config block to package.json;
  • Defined directly in the code file.

We choose to use.eslintrc file mode!!

Rule severity

  • “off”
  • Or 0 – turn the rule off
  • Or 1-turn the rule on as a warning(doesn’t affect exit code)
  • Or 2-turn the rule on as an error(exit code is 1 when triggered) error(if triggered) rules (Additional options) “quotes”: [2, “double”]

1. Installation dependencies:

npm i -D eslint babel-eslint eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/parser @typescript-eslint/eslint-plugin
Copy the code

Relevant plug-ins are as follows:

  • Eslint-plugin-jsx-a11y: Checks JSX syntax
  • Eslint-plugin-react: Specifies the react component specification
  • Eslint-plugin-import: The rules specification for using imports
  • @typescript-eslint/parser: EsLint is used by defaultEspreeSome syntax of TS is not recognized, so you need to install a TS parser@typescript-eslint/parser, instead of the default parser
  • @typescript-eslint/eslint-plugin: to provide a rule supplement for TS

2. Add the. Eslintrc configuration file

The configuration file is as follows:

{
  //  ESLint默认使用Espree作为其解析器
  //  此项是用来指定eslint解析器的,解析器必须符合规则
  //  官网没有对其他解析器进行说明,但是有提示,使用其他解析器的时候,注意确认它是不是和 ESLint 兼容。
  //  至于咋确认。。你指定一下这个解析器,看看 eslint 会不会对你想检查的代码正常报错,就行了。
  // 以下解析器与 ESLint 兼容:
  //  1、Esprima
  //  2、Babel-ESLint:一个对Babel解析器的包装,使其能够与 ESLint 兼容(如果你想使用一些 先进的语法,比如es6789...)。
  //  3、@typescript-eslint/parser:将 TypeScript 转换成与 estree 兼容的形式,以便在ESLint中使用(如果你想使用typescript)。
  "parser": "@typescript-eslint/parser",
  //  解析器选项,与parser同时使用
  //  在使用自定义解析器时,
  //  为了让 ESLint 在处理非 ECMAScript 5 特性时正常工作,
  //  配置属性 parserOptions 仍然是必须的
  //  解析器会被传入parserOptions,
  //  但是不一定会使用它们来决定功能特性的开关。
  "parserOptions": {
    // 默认是 script。模块化的代码要写:module(当前最常见做法,如果你的代码是 ECMAScript 模块)
    "sourceType": "module",
    //emcaVersion用来指定你想要使用的 ECMAScript 版本
    //注意,使用对于 ES6 语法,使用"ecmaVersion": 6时,不自动启用es6全局变量
    //自动启用es6语法和全局变量,需要搭配env使用"env": { "es6": true }
    "ecmaVersion": 6,
    //想使用额外的语言特性,一个配置对象,可配置项如下(value 均为 true/false)
    "ecmaFeatures": {
      "jsx": true,//启用jsx
      "globalReturn":true, //在全局作用域下使用return语句
      "impliedStrict":true, //启用全局strict mode (如果 ecmaVersion 是 5 或更高)
      "experimentalObjectRestSpread": false //启用实验性的object rest/spread properties支持(不建议开启)
    },
    "useJSXTextNode": true
  },
  //  要在配置文件中指定环境,请使用env键并通过将每个设置为来指定要启用的环境true。
  "env": {
    "browser": true, //开启浏览器全局变量
    "es6": true, //启用除模块以外的所有ECMAScript 6功能(这会自动将ecmaVersion解析器选项设置为6)
    "node": true //Node.js全局变量和Node.js作用域
  },
  // 此项是用来配置标准的js风格,就是说写代码的时候要规范的写
  // 指定配置的字符串(配置文件的路径,可共享配置的名称eslint:recommended或eslint:all)。
  // 字符串数组:每个其他配置都扩展了前面的配置
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  // 此项是用来提供插件的,插件名称省略了eslint-plugin-
  "plugins": [
    "react",
    "@typescript-eslint"
  ],
  /*
  * "off" 或 0 - 关闭规则
  * "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  * "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
  */
  "rules": {
    "semi": 2, // 行末分号,根据编码习惯选择添加,这里配置的加分号
    "no-console": 0, // 禁用 console
    "comma-dangle": [2,"never"], //对象字面量项尾不能有逗号(always-multiline是有逗号)
    "max-len": 0, // 强制一行的最大长度,可以是[1, 200]限制长度
    "max-lines": 0, // 强制最大行数
    "max-params": 0, // 强制 function 定义中最多允许的参数数量,可以用[1, 7]限制数量
    "max-statements": 0, // 强制 function 块最多允许的的语句数量,可以用[1, 200]限制数量
    "max-statements-per-line": 0, // 强制每一行中所允许的最大语句数量
    "space-before-function-paren": [0,"always"], // 强制在 function的左括号之前使用一致的空格
    // 禁止出现未使用过的表达式
    "no-unused-expressions": [
      0,
      {
        "allowShortCircuit": true,
        "allowTernary": true
      }
    ],
    "arrow-body-style": [0, "never"], // 要求箭头函数体使用大括号
    "func-names": 0, // 强制使用命名的 function 表达式
    "prefer-const": 0, // 要求使用 const 声明那些声明后不再被修改的变量
    "no-extend-native": 2, // 禁止扩展原生类型
    "no-param-reassign": 0, // 不允许对 function 的参数进行重新赋值
    "no-restricted-syntax": 0, // 禁止使用特定的语法
    "no-eval": 0, // 禁用 eval(),eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
    "no-continue": 0, // 禁用 continue 语句
    "global-require": 1, // 要求 require() 出现在顶层模块作用域中
    "camelcase": 2, //强制驼峰法命名
    "import/no-extraneous-dependencies": 0,
    "import/prefer-default-export": 0,
    "import/no-unresolved": 0,
    "import/extensions": 0,
    // react
    "react/jsx-first-prop-new-line": 0,
    "react/jsx-filename-extension": 0,
    "react/require-default-props": 0,
    "react/no-string-refs": 0,
    "react/no-find-dom-node": 0,
    "react/display-name": 0, //防止在React组件定义中丢失displayName
    "react/forbid-prop-types": [2, {"forbid": ["any"]}], //禁止某些propTypes
    "react/jsx-boolean-value": 2, //在JSX中强制布尔属性符号
    "react/jsx-closing-bracket-location": 1, //在JSX中验证右括号位置
    "react/jsx-curly-spacing": [2, {"when": "never", "children": true}], //在JSX属性和表达式中加强或禁止大括号内的空格。
    "react/jsx-indent-props": [2, 4], //验证JSX中的props缩进
    "react/jsx-key": 2, //在数组或迭代器中验证JSX具有key属性
    "react/jsx-max-props-per-line": [1, {"maximum": 1}], // 限制JSX中单行上的props的最大数量
    "react/jsx-no-bind": 0, //JSX中不允许使用箭头函数和bind
    "react/jsx-no-duplicate-props": 2, //防止在JSX中重复的props
    "react/jsx-no-literals": 0, //防止使用未包装的JSX字符串
    "react/jsx-no-undef": 1, //在JSX中禁止未声明的变量
    "react/jsx-pascal-case": 0, //为用户定义的JSX组件强制使用PascalCase
    "react/jsx-sort-props": 2, //强化props按字母排序
    "react/jsx-uses-react": 1, //防止反应被错误地标记为未使用
    "react/jsx-uses-vars": 2, //防止在JSX中使用的变量被错误地标记为未使用
    "react/no-danger": 0, //防止使用危险的JSX属性
    "react/no-did-mount-set-state": 0, //防止在componentDidMount中使用setState
    "react/no-did-update-set-state": 1, //防止在componentDidUpdate中使用setState
    "react/no-direct-mutation-state": 2, //防止this.state的直接变异
    "react/no-multi-comp": 2, //防止每个文件有多个组件定义
    "react/no-set-state": 0, //防止使用setState
    "react/no-unknown-property": 2, //防止使用未知的DOM属性
    "react/prefer-es6-class": 2, //为React组件强制执行ES5或ES6类
    "react/prop-types": 0, //防止在React组件定义中丢失props验证
    "react/react-in-jsx-scope": 2, //使用JSX时防止丢失React
    "react/self-closing-comp": 0, //防止没有children的组件的额外结束标签
    "react/sort-comp": 2, //强制组件方法顺序
    "react/no-array-index-key": 0, //防止在数组中遍历中使用数组key做索引
    "react/no-deprecated": 1, //不使用弃用的方法
    "react/jsx-equals-spacing": 2, //在JSX属性中强制或禁止等号周围的空格
    "no-extra-boolean-cast": 0, //禁止不必要的bool转换
    "no-unreachable": 1, //不能有无法执行的代码
    "no-mixed-spaces-and-tabs": 0, //禁止混用tab和空格
    "prefer-arrow-callback": 0, //比较喜欢箭头回调
    "arrow-parens": 0, //箭头函数用小括号括起来
    "arrow-spacing": 0, //=>的前/后括号
    "jsx-a11y/href-no-hash": 0,
    "jsx-a11y/no-static-element-interactions": 0,
    "quotes": [2, "single"], //单引号
    "no-debugger": 2, //禁用debugger
    "no-var": 2, //对var警告
    "no-irregular-whitespace": 0, //不规则的空白不允许
    "no-trailing-spaces": 1, //一行结束后面有空格就发出警告
    "eol-last": 0, //文件以单一的换行符结束
    "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], //不能有声明后未被使用的变量或参数
    "no-underscore-dangle": 0, //标识符不能以_开头或结尾
    "no-alert": 2, //禁止使用alert confirm prompt
    "no-lone-blocks": 0, //禁止不必要的嵌套块
    "no-class-assign": 2, //禁止给类赋值
    "no-cond-assign": 2, //禁止在条件表达式中使用赋值语句
    "no-const-assign": 2, //禁止修改const声明的变量
    "no-delete-var": 2, //不能对var声明的变量使用delete操作符
    "no-dupe-keys": 2, //在创建对象字面量时不允许键重复
    "no-duplicate-case": 2, //switch中的case标签不能重复
    "no-dupe-args": 2, //函数参数不能重复
    "no-empty": 2, //块语句中的内容不能为空
    "no-func-assign": 2, //禁止重复的函数声明
    "no-invalid-this": 0, //禁止无效的this,只能用在构造器,类,对象字面量
    "no-redeclare": 2, //禁止重复声明变量
    "no-spaced-func": 2, //函数调用时 函数名与()之间不能有空格
    "no-this-before-super": 0, //在调用super()之前不能使用this或super
    "no-undef": 2, //不能有未定义的变量
    "no-use-before-define": 0, //未定义前不能使用
    "jsx-quotes": [2, "prefer-double"], //强制在JSX属性(jsx-quotes)中一致使用双引号
    "@typescript-eslint/no-unused-vars": 0,
    "@typescript-eslint/no-explicit-any": 0,
    "@typescript-eslint/no-empty-interface": 0,
    "@typescript-eslint/explicit-function-return-type": 0,
    "@typescript-eslint/camelcase": ["off", {"properties":"always"}], //强制驼峰法命名(ts)
    "@typescript-eslint/no-use-before-define": 0
  },
  /*
  *ESLint支持将共享设置添加到配置文件中。
  *您可以将settings对象添加到ESLint配置文件,并将其提供给将要执行的每个规则。
  *如果您要添加自定义规则,并希望它们能够访问相同的信息并且易于配置,这可能会很有用。
  */
  "settings": {
    "import/resolver": "node",
    "react": {
      "version": "detect"
    }
  }
}

//环境定义了预定义的全局变量。可用环境为:
//browser -浏览器全局变量。
//node -Node.js全局变量和Node.js作用域。
//commonjs -CommonJS全局变量和CommonJS作用域(将其用于使用Browserify / WebPack的仅浏览器代码)。
//shared-node-browser -Node.js和浏览器通用的全局变量。
//es6-启用除模块以外的所有ECMAScript 6功能(这会自动将ecmaVersion解析器选项设置为6)。
//es2017-添加所有ECMAScript 2017全局变量并自动将ecmaVersion解析器选项设置为8。
//es2020-添加所有ECMAScript 2020全局变量并将ecmaVersion解析器选项自动设置为11。
//worker -网络工作者的全局变量。
//amd- 根据amd规范定义require()和define()作为全局变量。
//mocha -添加所有Mocha测试全局变量。
//jasmine -添加了版本1.3和2.0的所有Jasmine测试全局变量。
//jest -开玩笑的全局变量。
//phantomjs -PhantomJS全局变量。
//protractor -量角器全局变量。
//qunit -QUnit全局变量。
//jquery -jQuery全局变量。
//prototypejs -Prototype.js全局变量。
//shelljs -ShellJS全局变量。
//meteor -流星全局变量。
//mongo -MongoDB全局变量。
//applescript -AppleScript全局变量。
//nashorn -Java 8 Nashorn全局变量。
//serviceworker -服务人员全局变量。
//atomtest -Atom测试助手全局变量。
//embertest -灰烬测试助手全局变量。
//webextensions -WebExtensions全局变量。
//greasemonkey -GreaseMonkey全球。
//这些环境不是互斥的,因此您一次可以定义多个环境。
Copy the code

3. Add the script to package.json

The script content is as follows:

{
  scripts: {
    "lint-fix": "eslint --fix .js src"
  }
}
Copy the code
  • Run this command to check all js files in the SRC directory.
  • If you find folders in the SRC directory that do not need to be detected, such as vendors folder that contains third-party open-source code and does not need to do format verification, configure. Eslintignore and ignore the directory.
  • After executing lint-fix, ESLint will flag nonconformities based on the configuration file and automatically add changes, such as removing the end of lines and adding semicolons.
  • But there are other code formatting options, such as whether to indent with a space or a TAB, whether to add a space to braces, that Prettier does very well.

Note: there is a problem with the scripts above. If you write the scripts as above, the following error will occur after execution:So the script content is changed to the following:

{
  scripts: {
    "lint-fix": "eslint --fix --ext .js --ext .tsx src"
  }
}
Copy the code

Insert –ext before the file format to be tested

Error: eslintrc configuration file configuration error: Eslintrc configuration file configuration error: eslintrc configuration file configuration error: eslintrc configuration file configuration error:

Change it to the following:

So it’s a configuration error, and it shouldn’t be written in the wrong way.

If yarn run lint-fix is executed, the following error occurs:

Eslint-plugin-react Warning: React version not specified in eslint-plugin-react Settings

To specify the React version in eslintrc.js, add Settings in eslintrc.js

"settings": {
  "react": {
    "version": "detect"
  }
}
Copy the code

4. Configuration hooks

The project uses hooks syntax, so we need to add the hooks parsing rule to help us fix the hooks

1. Install dependencies

The installation command is as follows:

// yarn add eslint-plugin-react-hooks
npm install eslint-plugin-react-hooks --save-dev
Copy the code
2. Add related configurations to.eslintrc.json as follows
// .eslintrc.json
{
  "plugins": ["@typescript-eslint", "react-hooks"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}
Copy the code

Introducing hooks checks should prompt syntax errors like using hooks syntax in non-React components.

5. Installationhuskyandlint-staged

Prior to code submission, code rule checking ensures that all code entering git repositories complies with code rules. However, lint can be slow to run on an entire project, and Lint-staged versions can be fast because they only detect files in staging.

1. husky

Husky is a tool that adds hooks to Git clients. Once installed, it automatically adds hooks to the.git/ directory in your repository. For example, a pre-commit hook will trigger when you perform a Git commit.

You can implement things like Lint checking, unit testing, and code beautification in pre-commit. Of course, make sure that the commands executed in the pre-commit phase are not too slow, and waiting too long for each commit is not a good experience.

The installation command is as follows:

npm i husky -D
Copy the code
  • Git Hooks are scripts that trigger when Git executes certain events (commit, push, receive, etc.). Similar to “hook functions”, Hooks that are not set to execute are ignored.

  • Husky generates a series of Git hook scripts in the.git/hooks folder during installation.

  • Json file to configure the husky hooks to perform the following commands or operations:

{
  "husky": {
    "hooks": {
      "pre-commit": "echo \"git commit trigger husky pre-commit hook\" "
    }
  }
}
Copy the code

Execute multiple commands in the hook as follows:

  • According to the rules of NPM Script, use &&
{
  "husky": {
    "hooks": {
      "pre-commit": "echo \"git commit trigger husky pre-commit hook\" && npm run test"
    }
  }
}
Copy the code

Starting with 1.0.0, husky can be configured using.huskyrc,.huskyrc.json,.huskyrc.js, or husky.config.js files

  • If you prefer to use arrays, the suggested approach is in.huskyrc.jsDefine them in
const tasks = arr => arr.join(' && ')

module.exports = {
  'hooks': {
    'pre-commit': tasks([
      'npm run lint',
      'npm run test'
    ])
  }
}
Copy the code
2. lint-staged

Lint-staged, a tool that simply filters out Git code staging files (files added by Git); This is useful because if we do a review of the entire project code, it can take a long time, but if we do an older project, we have to do a code specification review and modify the previous code, which can be troublesome and lead to big changes in the project.

So this Lint-staged project is a great tool for team projects and open source projects, which act as a specification and discipline for the code that individuals must commit. Lint-staged always passes a list of all staged files to a task.

The installation command is as follows:

npm i lint-staged -D
Copy the code

The configuration method is as follows: Package. json file

{
  "lint-staged": {
    "*.js": "eslint --fix"
  }
}
Copy the code

or

{
  "src/**/*.{js,jsx,ts/tsx}": [
    "prettier --write",
    "eslint --cache --fix",
    "git add"
  ]
}
Copy the code

Lint-staged configuration: three commands will be executed for all.js.jsx ‘.ts’.tsx in the SRC directory in a git file to commit. The first two will be covered in a moment, and the last one will add the processed code back to Git.

Combined with husky, which we introduced earlier, and with Husky’s pre-commit hook, one will formAutomated tool chain.

The combination method is as follows:

"husky": {
  "hooks": {
    "pre-commit": "lint-staged"
  }
},
"lint-staged": {
  "src/**/*.{js,jsx,ts,tsx}": ["prettier --write", "eslint --cache --fix", "git add"]
}
Copy the code

Before committing, do a code review and beautification of the contents of the staging area before adding them to the staging area; Then commit, ok!!

Starting with V3.1, you can now configure Lint-staged in different ways:

  • Lint-staged in your object package.json
  • Lintstagedrc File in JSON or YML format
  • Lint-lanterns.config. js A file in JS format
  • Pass the configuration file using the –config or -c flag

It’s just that roads are often tortuous, and this is the fun part of having programmed things like #### Husky and Lint-staged installation and configuration problems. Husky (6.0.0) has made a disruptive change to the current husky (6.0.0) configuration.

3. Why did Husky abandon the previous configuration

Officially, the way Husky worked was that in order for the user to set any type of Hooks to work, Husky had to create all of them. This invokes the script husky set up at each stage of git’s work, in which husky checks to see if the user has configured the hook, runs the user-configured command if so, and continues if not.

The advantage of this is that no matter what type of Git hook husky the user sets up, it will work. Husky adds all types of Git hooks to Git even if the user doesn’t set up any.

Is it possible to get Husky to add only the Git hooks we need? The author tried to solve this problem, but failed. The root cause of this failure is that Husky needs to be configured in two places to complete a Git hook function. One is the actual command to execute to configure git hooks in package.json, and the other is to configure the corresponding Git hooks in.git/hooks/. In other words, adding or removing Git hooks should be done synchronously. The author was unable to find a reliable way to synchronize the configuration of the two places and failed.

The authors argue that the problem was caused by flaws in husky’s working model, and that a new working model would have to be adopted if the problem was to be solved. So the new Husky has made a disruptive change.

This change started with husky6.0.0 and I installed version 7.0.1, which obviously required a disruptive new configuration.

4. How the new Husky works

The new version of Husky uses a new feature, core.hookspath, introduced with Git 2.9. Core. hooksPath allows you to specify the directory where git hooks are located instead of using the default.git/hooks/.

Husky can use husky install to specify the.husky/ directory for which the hooks are located, and then use the husky add command to add hooks to.husky/. This way we can add only the git hooks we need, and all the scripts are saved in one place (.husky/) so there are no synchronization problems.

5. New Husky Practices

The following installation commands must have been executed:

npm install husky lint-staged -D
Copy the code

Husky supports numerous hooks, such as pre-commit and commit-msg. So that we can do something at a certain point in time.

1. The judge.git Whether the file is in the project root directory

2. Modify the “scripts” field in package.json in the root directory of the project
  1. If the.git file is in the root directory of your current project, make the following changes to the “scripts” field in package.json
Json "scripts": {"prepare": "husky install"},Copy the code
  1. If the.git file is not in your project’s root directory, you need to customize the directory

In the.git home directory, hooks can be executed according to project-specific rules. Especially in a repository that manages multiple projects, automatic commit management can be implemented for the independent configuration of sub-projects without affecting the independent configuration of Lint for each project. The situation is as follows:

As shown in the figure, the.git file is not in the root directory of the current project, so make the following changes to the “scripts” field in package.json in the root directory of the current project

Json "scripts": {"prepare": "CD.. Husky install Name of current project /. Husky "},Copy the code
3. Performnpm run preparegenerate.huskyfolder

In the package.json file, you can run the prepare command after NPM install or YARN install, or run the NPM run prepare command. After execution, a.husky folder will appear in the root directory of the current project

4. Run the following command to create a vmpre-commithook

To create a pre-commit file in the.husky folder, run the following command: NPX husky add. husky/pre-commit

npx husky add .husky/pre-commit
Copy the code

Note: Why not use the commands provided on the official website? Because using the commands provided in the official website will always fail in some cases, check Issues for details

5. Modify the pre-commit file created in Step 5
  1. .gitThe file is in the root directory of your current project

The content of the file is as follows:

// Change the pre-commit file to #! /bin/sh . "$(dirname "$0")/_/husky.sh" npx lint-stagedCopy the code
  1. .gitThe file is not in the root of your current project

The content of the file is as follows:

// Change the pre-commit file to #! /bin/sh . "$(dirname "$0")/_/husky.sh" cd projectName npx lint-stagedCopy the code
6. Install Lint-staged installation packages

To be clear, Lint-staged are simply file filters that won’t format anything for you, so there are no code rules configuration files and you’ll need to configure them yourself, as shown in package.json:

"lint-staged": {
  "src/**/*.{js,jsx,ts,tsx}": [
    "eslint --fix",
    "git add"
  ]
}
Copy the code

The diagram below:

7. Test Husky + Lint-staged configurations to see if they work

Git does not allow you to commit the a variable defined by var.

2. What is Prettier?

  • Prettier is a tool for completely unifying team code styles, including JSX and CSS.

  • Prettier means “pretty, clever” and the name of a popular code formatting tool that parses code and reprints it using rules you choose to Prettier. Prettier differs from ESLint in that Prettier is a tool that focuses on formatting code without quality checks. When Prettier is used, code review does not need to talk about code styles, saving time and effort.

  • For example, whether to indent with a space or a TAB, whether to add a space to braces, the plug-in prettier is good at doing.

  • Prettier Prettier prettier prettier formatting code, indentation, line wrapping, adding whitespace, makes code more readable and beautiful. Prettier can be used as a plug-in for ESLint.

Prettier can be installed as follows (if ESLint is already in the project) :

1. Install dependency related to Prettier

The installation command is as follows:

npm i -D prettier stylelint-config-prettier eslint-config-prettier eslint-plugin-prettier
Copy the code

Note: Some dependency installation commands are as follows:

NPM install --save-dev --save-exact prettier //--save-exactCopy the code

Or it can be displayed in package.json after installation as follows:

// Install the local dependency packageCopy the code

2. Run Prettier using ESLint

  1. Modify the extends field of the.eslintrc.js file in the project root directory to the following:
"extends": [
  "eslint:recommended",
  "plugin:react/recommended",
  "plugin:@typescript-eslint/recommended",
  "prettier"
]
Copy the code

Add ‘prettier’

  1. Add an entry to the.eslintrc.js file rules in the project root"prettier/prettier":"2"

  1. Prettierrc adds a. Prettierrc configuration file to set rules for formatting code:

Create the.prettierrc.js configuration file in the project root directory, where you can customize the configuration according to team preferences

The configuration is as follows:

Module. exports = {"printWidth": 100, // specifies code length beyond the newline "tabWidth": 2, // tabWidth" useTabs": false, // does not use TAB "semi": False, // end with semicolon "singleQuote": true, // Use single quotation marks "quoteProps": "as-needed", // Ask if object literal attributes are wrapped in quotation marks,(' as-needed ': 'consistent': use 'trailingQuote ': false, // use' trailingquote ': // use 'trailingquote ': "Es5 ", // Make sure the last attribute of the object is followed by a comma "bracketSpacing": true, // Braces have Spaces {name: 'rose'} "jsxBracketSameLine": False, // Append > "arrowParens": "always" to the last line of a multi-line JSX element, // arrow function, parentheses "requirePragma" for a single argument: // whether to insertPragma at the top of a formatted file to show that the file is "proseWrap" where prettier is formatting it "Preserve", / / according to file the same folding line "htmlWhitespaceSensitivity" : "ignore", / / HTML file space sensitivity, control whether space layout "endOfLine" : "Auto" // ends with \n\r \n\r auto}Copy the code

With that configuration file, esLint would format our file from the prettier configuration file.

At this point, the rule configuration for ESLint + Prettier in our project is almost complete.

3. The final content of the configuration file is as follows:

Json,. Eslintrc,. Prettierrc, and tsconfig.json

1. package.jsonConfiguration file Contents

//package.json {"name": "inforserver", "version": "1.0.0", "description": "information service platform ", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "dev": "Webpack - the dev server -- config. / config/webpack dev. Config. Js - host 0.0.0.0", "build" : "webpack -p --config ./config/webpack.prod.config.js", "lint-fix": "eslint --fix --ext .js --ext .tsx src", "prepare": "husky install" }, "lint-staged": { "src/**/*.{js,jsx,ts,tsx}": [ "prettier --write", "eslint --cache --fix", "git add" ] }, "keywords": [], "author": "", "license": "ISC", "dependencies" : {" antd ":" ^ 3.22.2 ", "axios" : "^ 0.19.0", "crypto - js" : "^ 4.0.0", "echarts" : "4.9.0", "happypack" : "^ 5.0.1," "hard - source - webpack - plugin" : "^ 0.13.1", the "immutable" : "^ 4.0.0 - rc. 12", "js - cookies" : "^ 2.2.1", "" : "^ 2.24.0 prop -", "types" : "latest", "qs" : "^ 6.8.0", "react" : "^ 16.9.0", "the react - cookies" : "^ while", "the react - dom" : "^ 16.9.0", "the react - loadable" : "^ 5.5.0", "the react - redux" : "^ 7.1.1", "the react - the router" : "^ 5.0.1", "the react - the router - dom" : "^ 5.0.1", "story" : "^ 4.0.4", "story - persist" : "^ 6.0.0", "the story - persist - transform - immutable" : "^ 5.0.0", "the story - thunk" : "^2.3.0"}, "devDependencies": {"@babel/core": "^7.14.6", "@babel/ proposal-class-properties": "^ 7.14.5 @", "Babel/plugin - proposal - object - the rest - spread" : "^ 7.14.7", "@ Babel/plugin - syntax - dynamic - import" : "^ 7.8.3 @", "Babel/plugin - transform - runtime" : "^ 7.14.5", "@ Babel/preset - env" : "^ 7.5.5", "@ Babel/preset - react" : "^ 7.0.0 @", "Babel/preset - the typescript" : "^ 7.14.5", "@ SVGR/webpack" : "^ 5.3.1", "@ types/react" : "16.9.23", "@ types/react - dom" : "16.9.7", "@ types/react - the router - dom" : "5.1.3", "@ typescript - eslint/eslint - plugin" : "^ 4.28.4", "@ typescript eslint/parser" : "^ 4.28.4", "Babel - eslint" : "^ 10.1.0", "Babel - loader" : "^ 8.0.6 Babel - plugin -", "import" : "^ 1.13.3", "Babel - polyfill" : "^ 6.26.0", "the clean - webpack - plugin" : "^ 3.0.0 copy - webpack -", "plugins" : "^ 6.0.2", "CSS - loader" : "^ 3.2.0", "eslint" : "^ 7.31.0", "eslint - config - prettier" : "^ 8.3.0 eslint - plugin -", "import" : "^ 2.23.4", "eslint - plugin - JSX - a11y" : "^ 6.4.1", "eslint - plugin - prettier" : "^ 3.4.0 eslint - plugin -", "react" : "^ 7.24.0", "eslint - plugin - react - hooks" : "^ 4.2.0", "file - loader" : "^ 4.2.0 HTML - webpack -", "plugins" : "^ 3.2.0", "husky" : "^ 7.0.1", "less" : "^ 3.10.3", "less - loader" : "^ 5.0.0 lint -", "staged" : "^ 11.1.1", "mini - CSS - extract - the plugin" : "^ 0.8.0", "node - sass" : "^ 4.12.0", "prettier" : "^ 2.3.2," "the react - countup" : "^ 4.3.3", "sass - loader" : "^ 8.0.0", "style - loader" : "^ 1.0.0", "stylelint - config - prettier" : "^ 8.0.2 terser - webpack -", "plugins" : "^ 4.2.0", "typescript" : "^ 4.3.5", "uglifycss - loader" : "^ 1.0.2", "url - loader" : "^ 3.0.0 webpack", ""," ^ 4.39.3 ", "webpack - cli" : "^ 3.3.7", "webpack - dev - server" : "^ 3.8.0", "webpack - merge" : "^ 4.2.2 webpack - theme -", "color - replacer" : "^ 1.3.7"}}Copy the code

2. .eslintrcThe configuration file is as follows:

//.eslintrc
{
  //  ESLint默认使用Espree作为其解析器
  //  此项是用来指定eslint解析器的,解析器必须符合规则
  //  官网没有对其他解析器进行说明,但是有提示,使用其他解析器的时候,注意确认它是不是和 ESLint 兼容。
  //  至于咋确认。。你指定一下这个解析器,看看 eslint 会不会对你想检查的代码正常报错,就行了。
  // 以下解析器与 ESLint 兼容:
  //  1、Esprima
  //  2、Babel-ESLint:一个对Babel解析器的包装,使其能够与 ESLint 兼容(如果你想使用一些 先进的语法,比如es6789...)。
  //  3、@typescript-eslint/parser:将 TypeScript 转换成与 estree 兼容的形式,以便在ESLint中使用(如果你想使用typescript)。
  "parser": "@typescript-eslint/parser",
  //  解析器选项,与parser同时使用
  //  在使用自定义解析器时,
  //  为了让 ESLint 在处理非 ECMAScript 5 特性时正常工作,
  //  配置属性 parserOptions 仍然是必须的
  //  解析器会被传入parserOptions,
  //  但是不一定会使用它们来决定功能特性的开关。
  "parserOptions": {
    // 默认是 script。模块化的代码要写:module(当前最常见做法,如果你的代码是 ECMAScript 模块)
    "sourceType": "module",
    //emcaVersion用来指定你想要使用的 ECMAScript 版本
    //注意,使用对于 ES6 语法,使用"ecmaVersion": 6时,不自动启用es6全局变量
    //自动启用es6语法和全局变量,需要搭配env使用"env": { "es6": true }
    "ecmaVersion": 6,
    //想使用额外的语言特性,一个配置对象,可配置项如下(value 均为 true/false)
    "ecmaFeatures": {
      "jsx": true,//启用jsx
      "globalReturn":true, //在全局作用域下使用return语句
      "impliedStrict":true, //启用全局strict mode (如果 ecmaVersion 是 5 或更高)
      "experimentalObjectRestSpread": false //启用实验性的object rest/spread properties支持(不建议开启)
    },
    "useJSXTextNode": true
  },
  //  要在配置文件中指定环境,请使用env键并通过将每个设置为来指定要启用的环境true。
  "env": {
    "browser": true, //开启浏览器全局变量
    "es6": true, //启用除模块以外的所有ECMAScript 6功能(这会自动将ecmaVersion解析器选项设置为6)
    "node": true //Node.js全局变量和Node.js作用域
  },
  // 此项是用来配置标准的js风格,就是说写代码的时候要规范的写
  // 指定配置的字符串(配置文件的路径,可共享配置的名称eslint:recommended或eslint:all)。
  // 字符串数组:每个其他配置都扩展了前面的配置
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended"
  ],
  // 此项是用来提供插件的,插件名称省略了eslint-plugin-
  "plugins": [
    "react",
    "@typescript-eslint",
    "react-hooks"
  ],
  /*
  * "off" 或 0 - 关闭规则
  * "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
  * "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
  */
  "rules": {
    "semi": 2, // 行末分号,根据编码习惯选择添加,这里配置的加分号
    "no-console": 0, // 禁用 console
    "comma-dangle": [2,"never"], //对象字面量项尾不能有逗号(always-multiline是有逗号)
    "max-len": 0, // 强制一行的最大长度,可以是[1, 200]限制长度
    "max-lines": 0, // 强制最大行数
    "max-params": 0, // 强制 function 定义中最多允许的参数数量,可以用[1, 7]限制数量
    "max-statements": 0, // 强制 function 块最多允许的的语句数量,可以用[1, 200]限制数量
    "max-statements-per-line": 0, // 强制每一行中所允许的最大语句数量
    "space-before-function-paren": [0,"always"], // 强制在 function的左括号之前使用一致的空格
    "prettier/prettier":2, // 这项配置 对于不符合prettier规范的写法,eslint会提示报错
    // 禁止出现未使用过的表达式
    "no-unused-expressions": [
      0,
      {
        "allowShortCircuit": true,
        "allowTernary": true
      }
    ],
    "arrow-body-style": [0, "never"], // 要求箭头函数体使用大括号
    "func-names": 0, // 强制使用命名的 function 表达式
    "prefer-const": 0, // 要求使用 const 声明那些声明后不再被修改的变量
    "no-extend-native": 2, // 禁止扩展原生类型
    "no-param-reassign": 0, // 不允许对 function 的参数进行重新赋值
    "no-restricted-syntax": 0, // 禁止使用特定的语法
    "no-eval": 0, // 禁用 eval(),eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
    "no-continue": 0, // 禁用 continue 语句
    "global-require": 1, // 要求 require() 出现在顶层模块作用域中
    "camelcase": 2, //强制驼峰法命名
    "import/no-extraneous-dependencies": 0,
    "import/prefer-default-export": 0,
    "import/no-unresolved": 0,
    "import/extensions": 0,
    // react
    "react/jsx-first-prop-new-line": 0,
    "react/jsx-filename-extension": 0,
    "react/require-default-props": 0,
    "react/no-string-refs": 0,
    "react/no-find-dom-node": 0,
    "react/display-name": 0, //防止在React组件定义中丢失displayName
    "react/forbid-prop-types": [2, {"forbid": ["any"]}], //禁止某些propTypes
    "react/jsx-boolean-value": 2, //在JSX中强制布尔属性符号
    "react/jsx-closing-bracket-location": 1, //在JSX中验证右括号位置
    "react/jsx-curly-spacing": [2, {"when": "never", "children": true}], //在JSX属性和表达式中加强或禁止大括号内的空格。
    "react/jsx-indent-props": [2, 4], //验证JSX中的props缩进
    "react/jsx-key": 2, //在数组或迭代器中验证JSX具有key属性
    "react/jsx-max-props-per-line": [1, {"maximum": 1}], // 限制JSX中单行上的props的最大数量
    "react/jsx-no-bind": 0, //JSX中不允许使用箭头函数和bind
    "react/jsx-no-duplicate-props": 2, //防止在JSX中重复的props
    "react/jsx-no-literals": 0, //防止使用未包装的JSX字符串
    "react/jsx-no-undef": 1, //在JSX中禁止未声明的变量
    "react/jsx-pascal-case": 0, //为用户定义的JSX组件强制使用PascalCase
    "react/jsx-sort-props": 2, //强化props按字母排序
    "react/jsx-uses-react": 1, //防止反应被错误地标记为未使用
    "react/jsx-uses-vars": 2, //防止在JSX中使用的变量被错误地标记为未使用
    "react/no-danger": 0, //防止使用危险的JSX属性
    "react/no-did-mount-set-state": 0, //防止在componentDidMount中使用setState
    "react/no-did-update-set-state": 1, //防止在componentDidUpdate中使用setState
    "react/no-direct-mutation-state": 2, //防止this.state的直接变异
    "react/no-multi-comp": 2, //防止每个文件有多个组件定义
    "react/no-set-state": 0, //防止使用setState
    "react/no-unknown-property": 2, //防止使用未知的DOM属性
    "react/prefer-es6-class": 2, //为React组件强制执行ES5或ES6类
    "react/prop-types": 0, //防止在React组件定义中丢失props验证
    "react/react-in-jsx-scope": 2, //使用JSX时防止丢失React
    "react/self-closing-comp": 0, //防止没有children的组件的额外结束标签
    "react/sort-comp": 2, //强制组件方法顺序
    "react/no-array-index-key": 0, //防止在数组中遍历中使用数组key做索引
    "react/no-deprecated": 1, //不使用弃用的方法
    "react/jsx-equals-spacing": 2, //在JSX属性中强制或禁止等号周围的空格
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "no-extra-boolean-cast": 0, //禁止不必要的bool转换
    "no-unreachable": 1, //不能有无法执行的代码
    "no-mixed-spaces-and-tabs": 0, //禁止混用tab和空格
    "prefer-arrow-callback": 0, //比较喜欢箭头回调
    "arrow-parens": 0, //箭头函数用小括号括起来
    "arrow-spacing": 0, //=>的前/后括号
    "jsx-a11y/href-no-hash": 0,
    "jsx-a11y/no-static-element-interactions": 0,
    "quotes": [2, "single"], //单引号
    "no-debugger": 2, //禁用debugger
    "no-var": 2, //对var警告
    "no-irregular-whitespace": 0, //不规则的空白不允许
    "no-trailing-spaces": 1, //一行结束后面有空格就发出警告
    "eol-last": 0, //文件以单一的换行符结束
    "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], //不能有声明后未被使用的变量或参数
    "no-underscore-dangle": 0, //标识符不能以_开头或结尾
    "no-alert": 2, //禁止使用alert confirm prompt
    "no-lone-blocks": 0, //禁止不必要的嵌套块
    "no-class-assign": 2, //禁止给类赋值
    "no-cond-assign": 2, //禁止在条件表达式中使用赋值语句
    "no-const-assign": 2, //禁止修改const声明的变量
    "no-delete-var": 2, //不能对var声明的变量使用delete操作符
    "no-dupe-keys": 2, //在创建对象字面量时不允许键重复
    "no-duplicate-case": 2, //switch中的case标签不能重复
    "no-dupe-args": 2, //函数参数不能重复
    "no-empty": 2, //块语句中的内容不能为空
    "no-func-assign": 2, //禁止重复的函数声明
    "no-invalid-this": 0, //禁止无效的this,只能用在构造器,类,对象字面量
    "no-redeclare": 2, //禁止重复声明变量
    "no-spaced-func": 2, //函数调用时 函数名与()之间不能有空格
    "no-this-before-super": 0, //在调用super()之前不能使用this或super
    "no-undef": 2, //不能有未定义的变量
    "no-use-before-define": 0, //未定义前不能使用
    "jsx-quotes": [2, "prefer-double"], //强制在JSX属性(jsx-quotes)中一致使用双引号
    "@typescript-eslint/no-unused-vars": 0,
    "@typescript-eslint/no-explicit-any": 0,
    "@typescript-eslint/no-empty-interface": 0,
    "@typescript-eslint/explicit-function-return-type": 0,
    "@typescript-eslint/camelcase": ["off", {"properties":"always"}], //强制驼峰法命名(ts)
    "@typescript-eslint/no-use-before-define": 0
  },
  /*
  *ESLint支持将共享设置添加到配置文件中。
  *您可以将settings对象添加到ESLint配置文件,并将其提供给将要执行的每个规则。
  *如果您要添加自定义规则,并希望它们能够访问相同的信息并且易于配置,这可能会很有用。
  */
  "settings": {
    "import/resolver": "node",
    "react": {
      "version": "detect"
    }
  }
}

//环境定义了预定义的全局变量。可用环境为:
//browser -浏览器全局变量。
//node -Node.js全局变量和Node.js作用域。
//commonjs -CommonJS全局变量和CommonJS作用域(将其用于使用Browserify / WebPack的仅浏览器代码)。
//shared-node-browser -Node.js和浏览器通用的全局变量。
//es6-启用除模块以外的所有ECMAScript 6功能(这会自动将ecmaVersion解析器选项设置为6)。
//es2017-添加所有ECMAScript 2017全局变量并自动将ecmaVersion解析器选项设置为8。
//es2020-添加所有ECMAScript 2020全局变量并将ecmaVersion解析器选项自动设置为11。
//worker -网络工作者的全局变量。
//amd- 根据amd规范定义require()和define()作为全局变量。
//mocha -添加所有Mocha测试全局变量。
//jasmine -添加了版本1.3和2.0的所有Jasmine测试全局变量。
//jest -开玩笑的全局变量。
//phantomjs -PhantomJS全局变量。
//protractor -量角器全局变量。
//qunit -QUnit全局变量。
//jquery -jQuery全局变量。
//prototypejs -Prototype.js全局变量。
//shelljs -ShellJS全局变量。
//meteor -流星全局变量。
//mongo -MongoDB全局变量。
//applescript -AppleScript全局变量。
//nashorn -Java 8 Nashorn全局变量。
//serviceworker -服务人员全局变量。
//atomtest -Atom测试助手全局变量。
//embertest -灰烬测试助手全局变量。
//webextensions -WebExtensions全局变量。
//greasemonkey -GreaseMonkey全球。
//这些环境不是互斥的,因此您一次可以定义多个环境。
Copy the code

3. .prettierrcThe content of the configuration file is as follows:

Prettierrc module.exports = {"printWidth": exports = {"tabWidth": 2, "useTabs": //. Prettierrc module.exports = {"printWidth": 0, // False, // Without TAB "semi": true, // end with semicolon "singleQuote": true, // Use single quotation marks "quoteProps": "As-needed ", // Requires that object literal attributes be wrapped in quotes (' as-needed ': no special requirements, prohibited, 'consistent': consistent, unrestricted) "jsxSingleQuote": False, // JSX syntax uses single quotes "trailingComma": "es5", // Make sure the last attribute of the object is followed by a comma "bracketSpacing": true, // Braces with Spaces {name: 'Rose'} "jsxBracketSameLine": false, // Append > "arrowParens": "always", // arrow function, single argument parentheses "requirePragma": // whether to insertPragma at the top of a formatted file to show that the file is "proseWrap" where prettier is formatting it "Preserve", / / according to file the same folding line "htmlWhitespaceSensitivity" : "ignore", / / HTML file space sensitivity, control whether space layout "endOfLine" : "Auto" // ends with \n\r \n\r auto}Copy the code

4. tsconfig.jsonThe content of the configuration file is as follows:

{ "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ "paths": { "@/*": ["./src/*"] }, /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ "target": "Es2015 ", /* Output code ES version, can be: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ "module": "Commonjs / * assigned module generates way: 'none', 'commonjs',' amd ', 'system', 'umd', 'es2015', 'es2020', or 'ESNext. * /" allowJs ": True, /* Allow js files */ "JSX ": "react", /* JSX: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ "sourceMap": true, /* Generate corresponding map file */ "outDir": "./dist/", /* define the folder for output files */ "removeComments": true, /* removeComments */ "strict": true, /* specifies whether all type checking is enabled. If (d:any) =>{} if (d:any) =>{} if (d:any) =>{} if (d:any) =>{} Function looks more like js (d) =>{} */ "esModuleInterop": true, /* Create namespace by importing content to achieve interoperability between CommonJS and ES modules */ "skipLibCheck": True, / * skip type checking for library definition file (2.0 or above) * / "forceConsistentCasingInFileNames" : true, / * don't allow different variables to represent the same file * / "strictNullChecks" : True, / * null check (2.0 or above) * / "noFallthroughCasesInSwitch" : "AllowUnreachableCode ": true, "allowUnusedLabels": "allowUnreachableCode": true, "allowUnusedLabels": "allowUnreachableCode": "allowUnreachableCode": "allowUnusedLabels": False, /* Do not report unused tag errors */ "noImplicitThis": true, /* Do not allow this to be implicit any */ "noUnusedLocals": NoUnusedParameters can be set to noUnusedParameters, which can be set to noUnusedParameters, and can be set to noUnusedParameters, which can be set to noUnusedParameters. [], / * definition file folder location (2.0 or above) * / "types" : [], / * set to introduce the definition file (2.0 or above) * / "allowSyntheticDefaultImports" : React */ / "lib": true /* Allows the import of modules that do not have a default export, that is, the TSX uses js module import to import modules, such as react */ / "lib": [], /* Specify library files to be included in the compilation. */ // "checkJs": true, /* Report errors in .js files. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ // "rootDir": ". / ", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (node.js) or 'classic' (TypeScript pre-1.6). */ / "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": []. /* List of root folders whose combined content represents the structure of the project at runtime. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ }, "include": ["src/**/*"] , "exclude": [ "node_modules" ] }Copy the code