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 developmentide
And submit the codegit hooks
I’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 wholeeslint
The 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
build
Compile-related changes, such as release versions, changes to project builds, or dependencieschore
Other changes, such as changing the build process, or adding dependent libraries, tools, etcci
Continuous integration modificationdocs
Document revisionfeat
New features, new functionsfix
Modify the bugperf
Optimizations related, such as improved performance, experiencerefactor
Code refactoringrevert
Roll back to the previous versionstyle
Code format modification, note not CSS modificationtest
Test 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:
- a
commit
Do one thing, not half done. - Be tested before you submit.
- In strict accordance with the
commit
The 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