In front end development, it is also important to understand and establish a set of fully usable standards, which is strictly the starting point of Devops.

The local part uses NPX to execute binary, NPM >7.x, which can be upgraded by NPM I NPM -g.

The purpose of this article is to quickly build a set of project development standards suitable for your own, suitable for extension and encapsulation, and try to complete the entire explanation of front-end native code development with this article.

1: husky

What it does: You can easily add Git hooks, which are great for project continuous integration and code detection.

npm install -D husky
Copy the code

Add the prepare script to packgae.json, which is executed after each NPM install. The command creates the.husky/ directory and specifies it as the directory where git hooks reside.

 {
  "scripts": {
    "prepare": "husky install"}}Copy the code

Add a pre-hooks, which will be triggered when you commit git. It would be more consistent with continuous integration if we did some lint checks, unit tests, code beautification, etc.

 npx husky add .husky/pre-commit "npm run test"
Copy the code

You can view the pre-commit command locally in.husky.

Add another commit-hoos:

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

Commitlint is responsible for verifying the commit specification, which is covered below.

In addition, in the project’s.git/hooks directory, there are some sample hook scripts ending in.sample. If you want to enable the corresponding hook, you can manually remove the suffix. (Delete the suffix.sample of a hook to enable the hook script, which is disabled by default.)

Husky is already encapsulated on top, so it’s more compatible and easier to use. Specific use will generally cooperate with the following tools to carry out.

2: lint-staged

lint

Lint is a tool that statically analyzes code and tries to figure out what’s wrong with it. The meaning is to reduce the cost of low-level code errors and troubleshooting, saving time resources, after all, in development, time and scheduling is very important.

Github lists commonly used tools for front end lint. The following esLint and Pretter are common tools for Lint.

Timing should have a point in time: during local developmentideAnd submit the codegit hooksI’m going to do it in two phases.

lint-staged

Lint-passage (Git Add) a tool that merely intercepts and verifies Git code staging area files (i.e., the area where files are newly added to Git add), specifically for static check every time a new code is submitted to a tollbooth before a highway.

The installation

npm install -D lint-staged
yarn add --dev lint-staged
Copy the code

Common parameter analysis:

 npx lint-staged --help
 Options: -v, --version Output version number --allow-empty Allows empty commits when the task undoes all phased changes (default:false) -c, --config [path] Specifies the path to the configuration file -d, --debug Displays other debugging information (default:false) -p, --concurrent <parallel Tasks > Number of tasks to be run simultaneously, orfalseTo run the task continuously (default:true-q, --quiet your own console output (default:false) -r, --relative passes relative file paths to the task (default:false) -x, -- Shell skips task resolution to better support the shell (default:false) -h, --help Displays usage informationCopy the code

Then add the configuration in package.json:

 "husky": {
    "hooks": {
      Var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var
      "pre-commit": "npx lint-staged".// Verify the commit writing specification, which will be explained below
      "commit-msg": "commitlint -e $1"}},"lint-staged": {
    "./src/*.{js,jsx}": [
      "eslint src --fix"."npx prettier --write".// Directly beautify the original file
      "git add "]},Copy the code

3: eslint

Espree is an open source JavaScript linting tool that uses Espree to parse JavaScript code into an abstract syntax tree (AST) and then analyzes our code through the AST, giving us two tips:

  • Code quality issues: Problematic patterns
  • Code style problem: The style doesn’t adhere to certain style guidelines.

Quick experience case:

   // 1: project creation
   mkdir eslintApp && cd eslintApp && touch index.js & npm i eslint -D & touch .eslintrc.js
   
   / / 2; .eslintrc.js
   {
    "rules": {
      "indent": 2."no-unused-vars": 2."no-alert": 2
    }, 
    "env": {
       "browser": true}}// 3: index.js
   
   // -fix This option instructs ESLint to try to fix as many problems as possible, and output failed fixes
   // 4: npx eslint index.js --fix
Copy the code

You can see the specific error message and the submission failure message. The wholeeslintThe core is the configuration file, below I posted all the local configuration file and description information.

module.exports = {
  root: true.// ESLint will stop looking in the parent directory once it finds "root": true in the configuration file.

  // If javascript is running in different environments, there will be different global variables. For example, if javascript is running in the Node environment, there will be global variables. If javascript is running in the Browser environment, there will be window variables.
  // ESlint will identify global variables in code based on the current runtime environment, and will report an error if the execution environment does not match global variables
  // Set esLint's environment to avoid checking global variables. You can choose more than one environment. For example, if you drop node, some variables will be undefined
  env: {
    browser: true.node: true.es6: true.// Es6 syntax environment
  }, 

  // By default ESlint uses Espree as the parser, but once we use Babel,
  // We need to use babel-eslint to make esLint and Babel work better.
  parser: "@babel/eslint-parser".// ESlint parserOptions can be set in configuration files using the parserOptions property. The available options are:
  parserOptions: {

    // Es35 is supported by default, and new syntax above ES6 needs to be configured if it is supported
    // Support for ES6 syntax does not mean support for new ES6 global variables or types (such as new types such as Set),
    // Also need {"env": {"es6": true}} (es6 syntax support is automatically enabled when this configuration is enabled)
    ecmaVersion: 6.sourceType: "module".requireConfigFile: false.// Indicate the additional language features you want to use:
    ecmaFeatures: {
      // Support for JSX syntax is not used for React support. React uses JSX syntax that specific ESLint doesn't recognize.
      // If you are using React and want React semantic support, use eslint-plugin-react.
      jsx: true.// globalReturn: false to allow return statements in the global scope
      // impliedStrict :false, enabling global strict mode
      / / experimentalObjectRestSpread: enable experimental object rest/spread properties support}},// Parser configuration

  /** * ESlint provides many configurable Rules, which can be cumbersome to configure one by one. ESlint supports inheriting startup rules from existing configurations. Eslint-config-standard (); eslint-config-airbnb (); ESlint provides an ESlint :recommended configuration, which provides a set of core rules that can be inherited using the extends property. * 2: "plugin:node/recommended: requires a separate plugin to provide: eslint-plugin-node * 3; NPM install -d eslint-plugin-standard {"extends": ["eslint:recommended", "standard"]} When using an external NPM package in ESLint, Omit exlint-plugin- If you want to override the extends configuration, you can do so in the rules field: */

  // Plugins must be called in plugins first, refer to prettier
  // react: "extends": ["eslint:recommended", "plugin:react/recommended"]
  extends: ["eslint:recommended"."plugin:node/recommended"."prettier"].// ESlint has a lot of rules attached to it. You can add a project's rules rule using the configuration mentioned above.

  /** * the first parameter error level: * 0 or off(to turn off the rule), * 1 or WARN (to turn on the rule and use a warning level error that will not cause the program to exit), * 2 or ERROR (to turn on the rule and use an error level error that will cause the program to exit) * * Second argument: In the example, indent is configured to default 4 Spaces, 2 Spaces and TAB indent. * * /
  rules: {

    // Use two Spaces. The error level is 2
    // "indent": [2, 2]

    // Use TAB indent. The error level is 2
   "indent": [2."tab"]."node/no-unsupported-features/es-syntax": 0."node/no-extraneous-import": 0."node/no-unsupported-features/node-builtins": 0."node/no-extraneous-require": 0."node/no-deprecated-api": 0."node/no-missing-import": 0."node/no-unpublished-import": 0."node/no-missing-require": 0."node/no-unpublished-require": 0."react/prop-types": 0."react/display-name": 0."react/no-children-prop": 0."react/jsx-no-target-blank": 0."react/no-string-refs": 0."react/no-direct-mutation-state": 0."react/no-find-dom-node": 0."react/jsx-no-duplicate-props": 0.// quotes: [1, "single"],
    complexity: 0.eqeqeq: 0."max-len": 0."no-case-declarations": 0.camelcase: 0."no-empty-function": 0."array-bracket-spacing": [2."never"]."comma-spacing": [
      2,
      {
        before: false.after: true],},"computed-property-spacing": [2."never"]."keyword-spacing": 2."space-before-blocks": [2."always"]."space-in-parens": [2."never"]."space-infix-ops": 2."space-unary-ops": [
      2,
      {
        words: true.nonwords: false],},"spaced-comment": [
      2."always",
      {
        markers: [
          "global"."globals"."eslint"."eslint-disable"."*package"."!",]}],"no-useless-escape": 0.// Then you need to open it
    "no-undef": 2.// Then you need to open it
    "no-unused-vars": 0.// Then you need to open it
    "guard-for-in": 0.// Then you need to open it
    "no-empty": 0.// Then you need to open it
    "default-case": 0.// Then you need to open it
    "no-process-exit": 0.// Then you need to open it
    "no-prototype-builtins": 0.// Then you need to open it
    "no-control-regex": 0."no-fallthrough": 0."no-mixed-spaces-and-tabs": 0."no-redeclare": 0."no-inner-declarations": 0."no-irregular-whitespace": 0."prettier/prettier": [
      "error",
      {
        endOfLine: "auto",}]},/ / here only lists several examples, the first parameter is the error of the level, the second is to set the value of the three values off, warn, error (0), the specific parameter configuration, see https://eslint.org/docs/rules/ for details


  // No-undef will issue a warning when accessing variable names that are not defined in the source file. This can be set as a separate global variable in the ESlint configuration file using globals.
  // EsLint checks for skipped global variables, eg: lodash,jquery
  globals: {
    document: true.localStorage: true.window: true.__dirname: true.importScripts: true.testVar: true  // No need to define, you can use directly
  },

  /** * a plug-in is an NPM package that typically outputs one or more named rule configurations. * We can use the plugins property to introduce an NPM package, and then use the extends property to inherit a set of rules from that NPM package. * * eg: npm install eslint-plugin-react --save-dev */
  plugins: [
    // "react",
    // "html"
    "prettier",]};Copy the code

The above configuration involves the following dependencies:

prettier

eslint-plugin-prettier
eslint-config-prettier  // This installation must be used by extends

eslint-plugin-node 
eslint-plugin-react 

@babel/eslint-parser

/ / comment
eslint-plugin-html

eslint-plugin-standard
eslint-config-standard

Copy the code

The.eslintignore file tells ESLint to ignore specific files and directories. Using glob patterns to match path paths should ignore detection. Or package.json file to specify that the eslintIgnore field is ignored

{
    "eslintIgnore": ["main.js"]}Copy the code

4: pretter

Function: Using defined code writing standards to beautify code writing at specific times and achieve the synchronization of writing specifications in collaborative development is an essential step in the development process specification. It is usually used in conjunction with ESLint.

npm i -D prettier
Copy the code

Quick to use:

 // index.js
var a = 100;var b = 200;function t(){return 100};

// npx prettier -w index.js
// npx prettier --write package.json
Copy the code

The above command line format for the index.js and package.json files uses the default format.

Configuration file:.prettierrc, there are three types of.js,.json,.yaml, the following is my project configuration.

    module.exports = {
      extends: ['airbnb'.'prettier'.'prettier/react'].printWidth: 200.// Over the maximum line feed
      htmlWhitespaceSensitivity: 'ignore'.semi: true.// No semicolon at the end
      disableLanguages: ['vue'].// Do not format the vue file. Format the vue file separately
      trailingComma: 'none'.Tail / / whether or not to use commas, there are three optional value "< none | es5 | all >", namely a JSON object behind the last attribute, don't need a comma
      tabWidth: 4,}Copy the code

“Lint-staged” and “esLint” configurations above both use prettier, and are usually used directly with each other in projects.

5: commitlint and git – cz

Background: Consistent commit separation in a multi-person collaborative team is a great way to manage and review code, and a clear commit can be completely meaningful. In the husky section above, we added a hooks:commitlint, which is used in more detail here.

Step 1

  npm install -g @commitlint/cli @commitlint/config-conventional
Copy the code

The local commitlint.config.js commitlint.config.js is dependent on.

Step 2

Git-cz repository address is an integrated tool, more simple and convenient to use.

npm install -g commitizen git-cz 
npx commitizen init git-cz --save-dev --save-exact
Copy the code

Step 3

The local commitlint.config.js file must be added, which is responsible for defining whether the input conforms to the criteria. It is triggered during the hooks phase.

module.exports = {
  extends: ["@commitlint/config-conventional"].rules: {
    "type-enum": [
      2."always"["feat"."fix"."docs"."style"."refactor"."perf"."test"."build"."ci"."chore"."revert",]],"subject-full-stop": [0."never"]."subject-case": [0."never"],}};Copy the code

Step 4

When the code is committed, you can perform git Cz to commit.

Supplement knowledge

Conventional Commits:

Git submission instructions are divided into three parts: Header[type+ scope + subject], Body and Footer.

Common type

  • buildCompile-related changes, such as release versions, changes to project builds, or dependencies
  • choreOther changes, such as changing the build process, or adding dependent libraries, tools, etc
  • ciContinuous integration modification
  • docsDocument revision
  • featNew features, new functions
  • fixModify the bug
  • perfOptimizations related, such as improved performance, experience
  • refactorCode refactoring
  • revertRoll back to the previous version
  • styleCode format modification, note not CSS modification
  • testTest case modifications

Scope indicates the scope of the impact of the commit and can be omitted. Subject is a short description of commit and can be omitted.

A detailed description of the Body commit, indicating a detailed description of the code commit.

Footer The Footer is required if the code is submitted for incompatible changes or close defects, otherwise it can be omitted.

Best practices:

  • acommitDo one thing, not half done.
  • Be tested before you submit.
  • In strict accordance with thecommitThe submission specification defined above.

6: extension

1: Captures ESLint

In general, inheritance development, CD/CI process, of course, we don’t want everything to be done outside the plug-in, we want to be able to capture inside the program.

const shell = require("shelljs");
const path = require("path");
const indexDir = path.resolve(__dirname, "index.js");
const eslintBin = path.resolve(__dirname, "node_modules/.bin/eslint");

const prettierBin = path.resolve(__dirname, "node_modules/.bin/prettier");

// eslint
const res = shell.exec(`${eslintBin} ${indexDir} --fix`);

if(! res.code) {// No error automatic prettier
  const preRes = shell.exec(`${prettierBin} -wc index.js`);
} else {
  console.log("opps,errors!");
}

console.log("= = =", res);
Copy the code