Build front end Lint workflow from zero

  • Eslint + prettier + husky + lint staged + typescript + eslint config alloy to ensure the quality of project code
  • Inherit the concept of plug-in and configuration advocated by ESLint, and meet the personalized needs (i.e. let professional tools do what they are good at)

Selective reading

What is code checking

  • Code checking is mainly used to find code errors and unify code style.
  • In JavaScript projects, we usually use ESLint to check the code, which greatly enriches the scope of application through plug-in features. With TypeScript ESLint, it can even be used to check TypeScript code.

Configure ESLint

Small test ox knife

  1. Create a new folder, open the command line, npm init -y create package.json
  2. Installation depends on NPM install -- save dev eslint Babel eslint eslint config alloy
  3. Create one under the project root eslintrc.js Or eslintrc.json Profile for:
// .eslintrc.js
module.exports = {
    extends: [
        'alloy',
    ],
};
  1. Create a index.js , copy the following:
var myName = 'Tom';
console.log(`My name is ${myNane}`);
  1. Enter NPX eslint on the command line index.js
// eslint error message:
✖ 2 problems (2 errors, 0 warnings)
error  Unexpected var, use let or const instead  no-var
error  'myNane' is not defined                   no-undef
  1. Using npx eslint index.js --fix automatically fixes some rules
// Then var becomes let
// There's a bug that can't be fixed automatically 
✖ 1 problem (1 error, 0 warnings)
error  'myNane' is not defined  no-undef

With TypeScript

  1. Because ESLint uses Espree for syntax parsing by default, it can't recognize some syntax of typescript, so we need to install @ typescript ESLint / parser instead of the default parser. Don't forget to install typescript at the same time:
npm install --save-dev typescript @typescript-eslint/parser
  1. Next, you need to install the corresponding plug-in @ typescript eslint / eslint plugin, which complements the default rules of eslint and provides some additional rules applicable to ts syntax.
npm install --save-dev @typescript-eslint/eslint-plugin
  1. Modify profile
module.exports = {
    extends: [
        'alloy',
    ],
    parser: '@typescript-eslint/parser',
    plugins: ['@typescript-eslint'],
    rules: {
        // Disable var
        'no-var': "error",
        // interface is preferred over type
        '@typescript-eslint/consistent-type-definitions': [
            "error",
            "interface"
        ]
    }
}
  • In the above configuration, we have customized two rules, among which no VaR is a native rule of ESLint (we just used this rule, which is included in alloy, and will be covered here), @ typescript ESLint / consistent type definitions is a new rule of @ typescript ESLint / ESLint plugin
  • The value of the rule is generally an array (in the above example, @ typescript eslint / consistent type definitions). The first item is one of off, warn or error, indicating shutdown, warning and error. The following items are all other configurations of the rule.
  • If there is no other configuration, you can abbreviate the value of the rule to the first item in the array (no VaR in the above example).

The meanings of closing, warning and error reporting are as follows:

  • Close: disable this rule
  • Warning: error message is output during code check, but exit code will not be affected
  • Error reporting: when an error is found, not only the error information will be output, but also the exit code will be set to 1 (generally, if the exit code is not 0, it means that there is an error in execution)
  1. newly build index.ts File:
var myName = 'Tom';
console.log(`My name is ${myNane}`);
console.log(`My name is ${myName.toStrng()}`);
type Foo = {};
  1. Enter NPX eslint on the command line index.ts , you can see the error message and repairable items as follows
  1:1   error  Unexpected var, use let or const instead  no-var
  2:27  error  'myNane' is not defined                   no-undef
  4:6   error  Use an `interface` instead of a `type`    @typescript-eslint/consistent-type-definitions

✖ 3 problems (3 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.

Script command check entire project

  1. Create a new src folder in the root directory, and index.js and index.ts Put it in
  2. stay package.json New scripts in:
{
    "scripts": {
        // Because eslint is not installed globally, npx is used
        "eslint": "npx eslint src --ext .js,.ts,tsx"
        // eslint does not check the files with the. TS suffix by default, so you need to add the parameter -- ext.ts
    }
}
  1. Then npm run lint can see the error information of all specified suffix files under src

Recommended configuration for AlloyTeam

  • The upper handle completes the configuration process of ESLint
  • It is recommended to use AlloyTeam directly to implement customizable and extensible ESLint rules
  • AlloyTeam/eslint-config-alloy Has helped us integrate various technology stacks
  1. Installation technology stack dependency
// Eslint
npm install --save-dev eslint babel-eslint eslint-config-alloy
// React
npm install --save-dev eslint babel-eslint eslint-plugin-react eslint-config-alloy
// Vue
npm install --save-dev eslint babel-eslint vue-eslint-parser eslint-plugin-vue eslint-config-alloy
// TypeScript
npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-alloy
// TypeScript React
npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-config-alloy
  1. to configure. eslintrc.js file
/* .eslintrc.js */
module.exports = {
    extends: [
        'alloy', // All need
        'alloy/vue', //vue project needs
        'alloy/react', //react project needs
        'alloy/typescript', //ts project needs
    ],
    env: {
        // Your environment variable (contains multiple predefined global variables)
        //
        // browser: true,
        // node: true,
        // mocha: true,
        // jest: true,
        // jquery: true
    },
    globals: {
        // Your global variable (set to false to indicate that it is not allowed to be reassigned)
        //
        // myGlobal: false
    },
    rules: {
        // Customize your rules
    }
};
  1. Next, you can check the file directly with the eslint command
  2. In this way, you can introduce the lint rules of alloy team, and then you can use rules to cover the rules you don't like. You can directly use open source rules to avoid repeated wheel building. You can also choose another team or define a set of rules yourself

VSCode integration ESLint check

By integrating ESLint check in the editor, errors can be found in the development process, and even can be automatically fixed when saving, which greatly increases the development efficiency

  1. First install the ESLint plug-in, open VSCode, click the "extension" button, search for ESLint, and then install it
  2. In "file = > Preferences = > Settings = > workspace" (you can also create a configuration file. Vscode in the project root directory/ settings.json ), add the following configuration:
{
    // By default, the ESLint plug-in in VSCode does not check the suffix of '. vue', 'ts' or'. tsx '
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "vue",
        "typescript",
        "typescriptreact"
    ],
    // Auto repair on save
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
    // Specifies the ts version of VSCode for IntelliSense, replacing the built-in version with the workspace version
    "typescript.tsdk": "node_modules/typescript/lib"
}

Use with Prettier

Prettier is a code formatting tool, which provides fewer options but is more professional than the code formatting rules in ESLint.
AlloyTeam recommends using Prettier to manage formatting related rules, and using ESLint to check for logical errors it is better at.

Configure Prettier

  1. Install Prettier
npm install --save-dev prettier
  1. to configure. prettierrc.js For reference only:
// .prettierrc.js
module.exports = {
    // Up to 100 characters in a line
    printWidth: 100,
    // Indent with 4 spaces
    tabWidth: 4,
    // Use spaces instead of indents
    useTabs: false,
    // Semicolon required at end of line
    semi: true,
    // single quotes 
    singleQuote: true,
    // Object's key is quoted only if necessary
    quoteProps: 'as-needed',
    // jsx uses double quotes instead of single quotes
    jsxSingleQuote: false,
    // Comma not required at end
    trailingComma: 'none',
    // Spaces are required at the beginning and end of braces
    bracketSpacing: true,
    // Reverse angle bracket of jsx label needs to wrap
    jsxBracketSameLine: false,
    // Arrow functions, when there is only one parameter, also need brackets
    arrowParens: 'always',
    // The format range of each file is the whole content of the file
    rangeStart: 0,
    rangeEnd: Infinity,
    // You don't need to write @ prettier at the beginning of the file
    requirePragma: false,
    // You don't need to automatically insert @ prettier at the beginning of the file
    insertPragma: false,
    // Use the default folding standard
    proseWrap: 'preserve',
    // Decide whether to wrap html according to the display style
    htmlWhitespaceSensitivity: 'css',
    // Use lf for line break
    endOfLine: 'lf'
};

VSCode integration Prettier

  1. At. vscode/settings.json Add configuration to:
{
    // Automatically format all supporting files on save JavaScript / JavaScript react / typescript / typescriptreact / JSON / graphql
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
}
  1. When we save the file, it can be automatically formatted
  2. You can also specify the format file type:
{
    // Set the default
    "editor.formatOnSave": false,
    // Enable per-language
    "[javascript]": {
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "editor.formatOnSave": true
    }
}

Git code pre check

  • We have configured ESLint and Prettier to integrate the VSCode plug-in to realize error prompt and save automatic repair
  • However, it is only a small part of the automatic repair. If team members do not follow the specification, they can still push the non-standard code to the remote code base
  • We prevent irregular code from being submitted to some extent through Git code pre inspection

Implementation process

  1. Code to be submitted
  2. git add to staging area
  3. Execute git commit (code pre check at this time)
  4. husky registers the hook of GIT pre commit to start lint staged
  5. Lint staged gets all the submitted files and performs the written tasks in turn
  6. If there is an error (failing the ESlint check), stop the task, wait for the next commit, and print the error message at the same time
  7. After successful submission, git push is pushed to the remote library

What is git hook

  • git hook s are hook functions under hooks in the. git folder. They will be called at a specific time
  • To view all git hook functions:
cd .git/hooks
ls -l
// Print as follows:
total 96
-rwxr-xr-x  1 zzc  staff   478 10 21  2019 applypatch-msg.sample
-rwxr-xr-x  1 zzc  staff   896 10 21  2019 commit-msg.sample
-rwxr-xr-x  1 zzc  staff  3327 10 21  2019 fsmonitor-watchman.sample
-rwxr-xr-x  1 zzc  staff   189 10 21  2019 post-update.sample
-rwxr-xr-x  1 zzc  staff   424 10 21  2019 pre-applypatch.sample
-rwxr-xr-x  1 zzc  staff  1638 10 21  2019 pre-commit.sample
-rwxr-xr-x  1 zzc  staff  1348 10 21  2019 pre-push.sample
-rwxr-xr-x  1 zzc  staff  4898 10 21  2019 pre-rebase.sample
-rwxr-xr-x  1 zzc  staff   544 10 21  2019 pre-receive.sample
-rwxr-xr-x  1 zzc  staff  1492 10 21  2019 prepare-commit-msg.sample
-rwxr-xr-x  1 zzc  staff  3610 10 21  2019 update.sample
  • . sample is the case script of each hook. You can remove the sample and directly write a shell script to execute it.
  • The front end can use the plug-ins husky and pre commit to make the hook effective.

husky register for git hook

Requires Node >= 10 and Git >= 2.13.0.

  • The configuration and use of the old and new versions of husky have changed a lot. Please upgrade the old version by yourself. For details, see husky
  1. Install husky
npm install husky --save-dev
  1. Edit package.json File:
{
    "husky": {
        "hooks": {
            "pre-commit": "eslint src/**/*.js"
        }
    },
}
  1. If you try to commit with git commit, you will execute eslint src/**/*.js first, and the code will not be submitted until there is no problem
  2. In this way, every time the code is submitted, eslint will check all the files. If there are too many missing messages, it will crash

Lint staged only lint changes code

lint-staged requires Node.js version 10.13.0 or later.

  • Any new changes to the original staging file after v10.0.0 are automatically added to the commit. If your task previously contained a git add step, please delete this step. Running multiple git operations at the same time will usually result in errors. See lint-staged
  1. Install lint staged
npm install lint-staged --save-dev
  1. newly added package.json to configure:
{
    "lint-staged": {
        "src/**/*.js": "eslint"
    }
}
  1. In this way, husky is only responsible for registering git hook, and the subsequent operations are handed over to lint staged. It only performs tasks on the changed files, and it is very convenient

To configure multiple commands:

{
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "src/**/*.js": ["eslint --fix", "prettier --write"]
    }
}
  1. As mentioned above, before we submit the code, the program will automatically repair the eslint configuration and format the prettier configuration

Some suggestions

  • It is recommended that code submission should only be checked and tested to intercept the problem code. It is better to automatically repair the eslint and prettier configurations when saving, and most of them need to be manually repaired
  • In case of emergency, you can also skip the check through git commit-m-n "skip code pre check". Use with caution
  • It is recommended to use -- save dev to install the package related to construction inside the project
  • The old husky lint staged configurations are all placed in the package.json At present, eslint prettier husky lint staged supports multiple suffix configuration files. It is recommended to use the. js unified format, which is also convenient for expansion:

Unified profile format

// .eslintrc.js
module.exports = {
    extends: [
        'alloy',
    ],
};
// .prettierrc.js
module.exports = {
    // Up to 100 characters in a line
    printWidth: 100,
    // Indent with 4 spaces
    tabWidth: 4,
    // ...
};
// .huskyrc.js
module.exports = {
  'hooks': {
    'pre-commit': "lint-staged"
  }
}
// .lintstagedrc.js
module.exports = {
  "src/**/*.{js,ts}": "eslint"
}

Expansion example

  • .huskyrc.js
// Configure multiple commands in array mode
const tasks = arr => arr.join(' && ')
module.exports = {
  'hooks': {
    'pre-commit': tasks([
      'npm run lint',
      'npm test'
    ])
  }
}
  • .lintstagedrc.js
module.exports = {
    // If there are more than 10 staging files, run eslint on the entire repository
    '**/*.js?(x)': (filenames) =>
    filenames.length > 10 ? 'eslint .' : `eslint ${filenames.join(' ')}`,
    "*.css": "stylelint",
    "*.scss": "stylelint --syntax=scss",
    // Run tsc on the ts file without passing any parameters
    '**/*.ts?(x)': () => 'tsc -p tsconfig.json --noEmit'
}