规范化是咱们践行前端工程化中重要的一部分。

为什么要有规范化规范

俗话说,无规矩不成方圆,尤其是在开发行业中,更是要有谨严的工作态度,咱们都晓得大多数软件开发都不是一个人的工作,都是须要多人协同的,而不同的开发者有不同的编码习惯和爱好,这些集体的爱好并没有什么不好的中央,只是说同一个我的项目中,每一个人的爱好都不雷同,那么就会导致我的项目的保护老本大大增加,所以说咱们须要为每个我的项目或者团队须要明确对立的规范,让我的项目或团队中的成员依照对立的规范去实现工作,从而防止各种不对立而带来的麻烦。那么晓得了为什么规范化规范之后,那么看一下在开发过程中,哪些地方用到规范化规范的。

  • 代码、文档、甚至是提交的日志
  • 开发过程中人为编写的内容
  • 其中代码的标准化标准最为重要,因为代码的标准很大水平上决定着代码的品质以及可维护性,为了便于前期保护以及其余成员的浏览,个别状况下咱们都对代码的格调进行对立的要求。

实现规范化的办法

咱们在落实规范化的规范的时候也很简略,只须要提前约定好一个执行的规范,而后依照规范各自执行各自的开发工作。最初在Code Review环节依照之前约定的规范去查看各自相应的代码,然而依照人为约定的形式执行规范化会有很多的问题,一来人为束缚不牢靠,二来开发者也很难记住规定。所以咱们就须要绝对应的工具做保障,相比人为的查看,工具的查看更为牢靠,同时配合自动化的工具进行自动化查看,这样就能失去品质化的保障。将工具查看代码标准的过程称为lint,例如前端常见的eslint、stylelint等。

常见的规范化实现形式

  • ESLint工具应用
  • 定制ESLint校验规定
  • ESLint对TypeScript的反对
  • ESLint联合自动化工具或者Webpack进行我的项目自动化校验
  • 基于ESLint的衍生工具
  • Stylelint工具的应用

ESLint介绍

EsLint是目前最为支流的JavaScript Lint工具,专门用于检测JS代码品质,通过ESLint很容易对立开发者的编码格调,例如:缩进、换行、分号以及空格之类的应用。不仅如此,EsLint还能帮忙咱们找到代码中不合理的中央,例如咱们定义了一个从未应用的变量,或者在变量应用之后才去做申明等等,而这些不合理的操作就是代码中潜在的问题,通过EsLint能无效防止这些问题,从而进步代码的品质。

对于 JavaScript 这种动静、宽松类型的语言来说,开发者更容易犯错。因为 JavaScript 不具备先天编译流程,往往会在运行时裸露谬误,而 Linter,尤其最具代表性的 ESLint 的呈现,容许开发者在执行前发现代码谬误或不合理的写法。

ESLint 最重要的几点哲学思想:

  • 所有规定都插件化
  • 所有规定都可插拔(随时开关)
  • 所有设计都透明化
  • 应用 Espree 进行 JavaScript 解析
  • 应用 AST 剖析语法
  • 想要顺利执行 ESLint,还须要装置利用规定插件。

那么如何申明并利用规定呢?在根目录中关上 .eslintrc 配置文件,咱们在该文件中退出:

{    "rules": {        "semi": ["error", "always"],        "quote": ["error", "double"]    }}

semi、quote 就是 ESLint 规定的名称,其值对应的数组第一项能够为:off/0、warn/1、error/2,别离示意敞开规定、以 warning 模式关上规定、以 error 模式关上规定。

  • off/0:敞开规定
  • warn/1:以 warning 模式关上规定
  • error/2:以 error 模式关上规定

同样咱们还会在 .eslintrc 文件中发现:

{  "extends": "eslint:recommended"}

这行示意 ESLint 默认的规定都将会被关上。当然,咱们也能够选取其余规定汇合,比拟闻名的有:

  • Google JavaScript Style Guide
  • Airbnb JavaScript Style Guide

留神,上文中 .eslintrc 文件咱们采纳了 .eslintrc.js 的 JavaScript 文件格式,此外还能够采纳 .yaml、.json、yml 等格局。如果我的项目中含有多种配置文件格式,优先级程序为:

  • .eslintrc.js
  • .eslintrc.yaml
  • .eslintrc.yml
  • .eslintrc.json
  • .eslintrc
  • package.json

最终,咱们在 package.json 中能够增加 script:

"scripts": {    "lint": "eslint --debug src/",    "lint:write": "eslint --debug src/ --fix" },

咱们对上述 npm script 进行剖析,如下:

  • lint 这个命令将遍历所有文件,并在每个找到谬误的文件中提供具体日志,但须要开发者手动关上这些文件并更正谬误。
  • lint:write 与 lint 命令相似,但这个命令能够主动纠正错误。

ESLint装置

首先咱们须要创立一个我的项目,并在我的项目中装置ESLint模块为开发依赖,而后初始化配置文件。

mkdir test-eslint && cd test-eslintnpm initnpm install eslint -D //装置npm init @eslint/config //初始化配置文件

而后提醒,给出了三个选项

  • To check syntax only:只查看语法的谬误
  • To check syntax and find problems:查看语法错误并发现问题代码
  • To check syntax, find problems, and enforce code style:第三个在前两个根底上校验代码格调

其中语法错误比拟好了解,问题代码指的是代码不合理的中央,例如未被应用的变量或者不存在的函数。代码格调指的是在代码格调上存在的问题,例如缩进不对立。在理论开发中倡议抉择第三种。

而后再抉择我的项目的模块化,依据我的项目的理论状况抉择即可。

等等一些根底配置,包含我的项目用的什么框架,React、Vue还是啥也没用,是否用TypeScript,你的我的项目运行在什么环境是浏览器还是Node,你想要在你的我的项目中怎么定义代码格调,应用市面上支流的格调、通过询问问题造成格调、依据JS代码文件推断出格调?


那么咱们抉择市面上支流的格调后,又提醒让你抉择具体市面上哪个格调。


最初提醒配置文件以何种形式寄存,这里抉择JS的形式即可,不便后续做条件判断。


之后会提醒装置我的项目须要的插件,确定装置即可,在我的项目根目录下会看到.eslintrc.js文件。

而后再执行npx eslint xxx.js能够看出校验了很多的问题。

总结来讲eslint有两个作用:一是能够找出代码的问题,包含语法错误、代码不合理、格调不对立。二是能够修复代码格调上的大多数的问题。例如npx eslint xxx.js --fix命令来修复,例如增加如下命令:

"scripts": {    "lint": "eslint ./src/**/*.{js,jsx,vue,ts,tsx} --fix"},

ESLint配置文件解析

我的项目生成的.eslintrc.js文件内容如下:

module.exports = {  env: {    browser: true,    es2021: true  },  extends: 'standard',  overrides: [  ],  parserOptions: {    ecmaVersion: 'latest'  },  rules: {  }}

该配置项默认有四个配置选项

  1. env:JS在不同的环境中有不同的api能够调用,例如在浏览器中能够间接应用widow、document全局成员,这个env就是表明以后代码的运行环境,它会依据环境信息判断全局成员是否可用,为了防止代码中应用不存在的成员。比方browser为true示意代码运行在浏览器中,这里定义的每一个环境对应了一组全局变量,一旦开启了某个环境,这个环境的全局变量则都能被应用。env运行环境配置如下:
  • browser:浏览器环境中的全局变量
  • node:Node.js全局变量和Node.js作用域
  • commonjs:CommonJS全局变量和CommonJS作用域(用于Browserify/Webpack打包的只在浏览器中运行的代码)
  • shared-node-browser:Node.js和Browser通用全局变量
  • es6:启用除了modules以外的所有ECMAScript6个性(该选项会主动设置ecmaVerison解析器选项为6)
  • worker:Web Workers全局变量
  • amd:将require()和define()定义为像amd一样的全局变量
  • mocha:增加所有的Mocha测试全局变量
  • jasmine:增加所有的Jasmine版本1.3和2.0的测试全局变量
  • jest:Jest全局变量
  • phantomjs:PhantomJS全局变量
  • protractor:Protractor全局变量
  • qunit:QUnit全局变量
  • jquery:jQuery全局变量
  • prototypejs:Prototype.js全局变量
  • shelljs:ShellJS全局变量
  • meteor:Meteor全局变量
  • mongo:MongoDB全局变量
  • applescript:AppleScript全局变量
  • nashorn:Java 8 Nashorn全局变量
  • atomtest:Atom测试全局变量
  • embertest:Ember测试全局变量
  • webextensions:WebExtensions全局变量
  • greasemonkey:GreaseMonkey全局变量
  1. extends:用于继承一些共享的配置,例如咱们应用的standard标准。
  2. parserOptions:该选项用于设置语法解析器的配置,它只检测语法,而不是检测哪个全局成员是否可用。
  3. rules:用于配置校验规定的开启和敞开。
  4. plugins:设置规定插件。
  5. parser:默认状况下 ESLint 应用 Espree 进行解析。

如果想校验vue标准,能够装置vue-eslint-plugin,增加如下配置即可

{  extends: [    // add more generic rulesets here, such as:    // 'eslint:recommended',    'plugin:vue/vue3-recommended',    // 'plugin:vue/recommended' // Use this if you are using Vue.js 2.x.  ],}

ESLint配置正文

ESLint配置正文指的是将配置以正文的形式写在脚本文件中,而后再去执行代码的校验。在理论开发的过程中,难免会遇到一两个违反配置规定的状况,不能因为这一两个点去颠覆校验规定的配置,这个时候能够应用ESLint配置正文来解决这样的问题。

const str1 = '${name} is a coder'; //eslint-disable-line no-template-curly-in-stringconsole.log(str1);

例如应用eslint-disable-line选择性疏忽这行代码,然而如果一行代码中有多个问题,通过这个正文都不会被检测到了,因而前面加上具体禁用的规定名称,这样就不影响其余的规定。
::: tip 相干文档
http://eslint.cn/docs/user-guide/configuring#configuring-rules
:::

编辑器集成

编辑器集成次要是如何看到不符合规范的谬误提醒,如何依照我的项目中的ESLint规定要求进行格式化。

首先先去卸载或者禁用Vetur插件,而后装置vscode的eslint插件,以及volar插件。

eslint插件是装置并启用了这个插件,它就会主动查找我的项目中的eslint配置标准,并且给出验证提醒。那如何格式化呢?ESLint提供了格式化工具,然而须要手动配置才能够。

onType是在写代码过程中实时去验证,onSave是保留的时候去验证。

ESLint联合gulp

如果咱们的我的项目中采纳自动化构建工作流,那么咱们就把ESLint集成到工作流中。在gulp应用babel编译之前,通过glup-eslint插件来查看代码。应用的时候先调用eslint插件检测,而后调用eslint.format()办法在控制台打印错误信息,而后再应用eslint.failAfterError()办法,在查看到谬误之后终止工作管道。

ESLint联合Webpack

在webpack中应用ESLint须要装置eslint-loader在babel-loader之前调用。

rules:[    {        test: /\.js$/,        exclude: /node_modules/,        use: 'babel-loader'    },    {        test: /\.js$/,        exclude: /node_modules/,        use: 'eslint-loader',        enfore: 'pre'    }]

这里应用一个 enforce 属性配置pre优先解决。它的值如下:

  1. pre 优先解决
  2. normal 失常解决(默认)
  3. inline 其次解决
  4. post 最初解决

针对React非凡语法须要装置eslint-plugin-react插件,而后在.eslintrc.js文件中配置插件,编写rules规定即可。

module.exports = {  env: {    browser: true,    es2021: true  },  extends: 'standard',  overrides: [  ],  parserOptions: {    ecmaVersion: 'latest'  },  rules: {    'react/jsx-uses-react': 2,    'react/jsx-uses-vars': 2  },  plugins:[    'react'  ]}

咱们也能够间接继承eslint-plugin-react中编写的规定,就能够共享配置中的内容。

module.exports = {  env: {    browser: true,    es2021: true  },  extends: [    'standard',    'plugin:react/recommended'  ],  overrides: [  ],  parserOptions: {    ecmaVersion: 'latest'  },  rules: {  }}

ESLint查看TypeScript

之前咱们查看TypeScript是采纳tslint工具,起初tslint官网放弃保护,举荐应用eslint配合typescript插件来做代码校验。留神这里在.eslintrc.js中配置ts的语法解析器。

module.exports = {  env: {    browser: true,    es2021: true  },  extends: [    'standard',  ],  parser: '@typescript-eslint/parser',  overrides: [  ],  parserOptions: {    ecmaVersion: 'latest'  },  rules: {  }  plugins:[    '@typescript-eslint'  ]}

StyleLint介绍

在前端我的项目中除了JavaScript代码须要lint之外,css代码也须要lint,css代码的lint个别应用StyleLint来帮忙实现。StyleLint默认提供了代码查看规定供开发者应用,咱们也能够在配置文件中选择性的开启和敞开规定。StyleLint也同样提供了CLI工具,供开发者在命令行中调用,从而查看css代码。StyleLint也反对通过插件来实现对Sass、Less、PostCSS等衍生语法的查看。最初StyleLint也反对Gulp和Webpack工具的集成。

装置stylelint

npm install stylelint -D

装置stylelint共享配置模块

npm install stylelint-config-standard

创立.stylelintrc.js配置文件

module.exports = {  extends: [    'stylelint-config-standard',  ]}

再通过命令校验css文件

npx stylelint ./index.css

如果你须要应用stylelint校验sass代码,那么就须要装置绝对应的模块。

npm install stylelint-config-sass-guidelines

而后再增加配置文件

module.exports = {  extends: [    'stylelint-config-standard',    'stylelint-config-sass-guidelines'  ]}

Prettier的应用

Prettier是一款通用的前端代码格式化工具,它很弱小,简直能实现所有前端代码的格式化工作。它个别不会查看咱们代码具体的写法,而是在“可读性”上做文章。目前反对包含 JavaScript、JSX、Angular、Vue、Flow、TypeScript、CSS(Less、SCSS)、JSON 等多种语言、数据交换格局、语法标准扩大。在日常工作中,咱们能够应用它来实现日常代码的主动格式化,通过应用它能够落实前端我的项目的规范化规范。

总的来说,它可能将原始代码格调移除,并替换为团队对立配置的代码格调。尽管简直所有团队都在应用这款工具,这里咱们还是简略剖析一下应用它的起因:

  • 构建并对立代码格调
  • 帮忙团队新成员疾速融入团队
  • 开发者能够齐全聚焦业务开发,不用在代码整顿上破费过多心理
  • 不便,低成本灵便接入,并疾速发挥作用
  • 清理并标准已有代码
  • 缩小潜在 Bug
  • 丰盛弱小的社区反对

当然,Prettier 也能够与编辑器联合,在开发者保留后立刻进行丑化,也能够集成到 CI 环境中,或者 Git pre-commit 的 hook 阶段。比方应用 pretty-quick:

yarn add prettier pretty-quick husky -D

格式化文件

npx prettier style.css --write

应用通配符的形式格式化所有的文件

npx prettier . --write

并在 package.json 中配置:

{    "husky": {        "hooks": {            "pre-commit": "pretty-quick --staged"        }    }}

在 husky 中,定义 pre-commit 阶段,对变动的文件运行 Prettier,--staged 参数示意 pre-commit 模式:只对 staged 的文件进行格式化。

这里咱们应用了官网举荐的 pretty-quick 来实现 pre-commit 阶段的丑化。这只是实现形式之一,还能够通过 lint-staged 来实现。

Git Hooks介绍

Git Hook也称之为Git钩子,每个钩子都连着一个具体的Git操作,比方commit、push等等,咱们能够通过shell脚本来编写钩子工作触发时要具体执行的操作。例如咱们能够通过Git Hooks的形式在提交代码之前强制做lint查看,以便后续CI的时候lint失败。

https://github.com/okonet/lint-staged

咱们关上git我的项目,在根目录下找到.git暗藏文件夹


关上hooks目录,能够看到sample钩子文件。咱们能够去自定义这些文件。

因为很多前端开发者并不善于shell,所以有开发者开发了一个npm模块Husky帮忙实现Git Hooks的应用需要。应用Husky就能够在不编写shell脚本的状况下实现Git钩子的需要。

装置,应用以下命令会在我的项目中装置husky和lint-staged

npx mrm@2 lint-staged

装置Husky

npm install husky -D

而后再package.json中配置husky,husky下有hooks对象,外面能够配置钩子和对应的命令。

{    "husky":{        "hooks":{            "pre-commit": "npm run test"        }    }}

如果咱们想在代码格式化后提交到暂存区,那么仅应用husky是满足不了需要的,这时候就须要应用lint-staged模块帮忙合作。咱们先装置lint-staged模块。

npm install lint-staged -D

而后配置package.json

{    "scripts":{        "precommit": "lint-staged"    }    "husky":{        "hooks":{            "pre-commit": "npm run precommit"        }    },    "lint-staged":{        "*.js":[            "eslint",            "git add"        ]    }}

这样就能在提交代码前先应用eslint校验,而后执行git add命令。

git commit标准

举荐参考

  • Commit message和Change log编写指南

对立团队Git commit日志规范,便于后续代码review,版本公布以及日志自动化等。

那么就思考应用commitlint

装置

npm install --save-dev @commitlint/config-conventional @commitlint/cli

创立commitlint.config.js

module.exports = {  extends: ['@commitlint/config-conventional']}

如果想主动生成changelog能够应用conventional-changelog

技术原理和设计

ESLint 是基于动态语法分析(AST)进行工作的,AST 曾经不是一个陈腐话题。ESLint 应用 Espree 来解析 JavaScript 语句,生成 AST。

有了残缺的解析树,咱们就能够基于解析树,对代码进行检测和批改。ESLint 的灵魂是每一条 rule,每条规定都是独立且插件化的,咱们挑一个比较简单的“禁止块级正文规定”源码来剖析:

module.exports = {  meta: {    docs: {      description: '禁止块级正文',      category: 'Stylistic Issues',      recommended: true        }  },  create (context) {    const sourceCode = context.getSourceCode()    return {      Program () {        const comments = sourceCode.getAllComments()        const blockComments = comments.filter(({ type }) => type === 'Block')        blockComments.length && context.report({          message: 'No block comments'        })      }    }  }}

从中咱们看出,一条规定就是一个 node 模块,它由 meta 和 create 组成。meta 蕴含了该条规定的文档形容,绝对简略。而 create 承受一个 context 参数,返回一个对象,如下代码:

{    meta: {        docs: {            description: '禁止块级正文',            category: 'Stylistic Issues',            recommended: true         }    },    create (context) {        // ...        return {        }    }}

从 context 对象上咱们能够获得以后执行扫描到的代码,并通过选择器获取以后须要的内容。如上代码,咱们获取代码的所有 comments(sourceCode.getAllComments()),如果 blockComments 长度大于 0,则 report No block comments 信息。理解了这些,置信你也能写出 no-alert、no-debugger 的规定内容。

尽管 ESLint 背地的技术内容比较复杂,然而基于 AST 技术,它曾经给开发者提供了较为成熟的 APIs。写一条本人的规定并不是很难,只须要开发者找到相干的 AST 选择器。更多的选择器能够参考:Selectors - ESLint - Pluggable JavaScript linter,熟练掌握选择器,将是咱们开发插件扩大的要害。

大厂代码标准

  • Airbnb
  • standard
  • 腾讯
  • 百度
  • 阿里