标准化规范

420 阅读31分钟

1. 规范化介绍

规范化是我们践行前端工程化中重要的一部分 这里从以下几个方面进行介绍规范化:

  • 为什么要有规范化标准

    • 软件开发需要多人协同

    俗话说无规矩不成方圆 做人做事也是一样 尤其是在开发行业中更是需要有严谨的工作态度 -> 大多是情况下软件开发都不是一个人的工作 都是需要多人协同的

    • 不同开发者具有不同的编码习惯和喜好

    • 不同的喜好增加项目维护成本

    • 每个项目或者团队需要明确统一的标准

    让这个项目或者说团队中的成员按照统一的标准工作 -> 从而避免各种不同意造成带来的一些麻烦

  • 在开发过程中哪里需要规范话标准

    • 代码、文档、甚至是提交日志

    • 开发过程中人为编写的成功物

    • 代码标准化规范最为重要

      代码的规范很大程度上决定了项目的质量 也决定了项目的可维护性 -> 为了便于后期的维护以及团队成员的阅读 一般情况下都会对代码的风格做统一的要求 -> 这里的一般都会包括:

      • 统一关键词和操作符左右的空格
      • 统一代码的缩进方式
      • 统一是否使用分号结尾
      • 统一变量或者函数的命名规范等
  • 实施规范化的方法

    • 编码前人为标准约定

      最初落实规范化的操作时也非常简单 只需要提前约定好一个可以执行的标准 -> 然后按照该标准开展各自的开发工作 -> 最终在 code-review 环节就会按照约定的标准检查相对应的标准

      => 但是单靠人为约定的方式落实规范化 会有很多的问题:

      • 人为约束不可靠
      • 开发者也很难记住每个规则
    • 通过工具实现 Lint

      通过专门的工具保障规范化的落实 相对于人为检查 -> 工具的检查更为严谨 更为可靠 -> 同时还可以配合自动化的工具实现自动化检查 -> 这样的规范化就更加容易得到质量上的保证

      => 一般我们将通过工具去找到项目中不符合规范的地方 这样的过程称之为 Lint -> 之所以叫 Lint 是: 在刚有 C语言的时候 有一些常见的代码问题是不能被编译器捕获到的 -> 有人就开发了一个叫 Lint 的工具 用于在编译之前检查出这些问题 避免编译之后造成一些不必要的问题 -> 后续这种类似功能的工具都被称为 Lint 或者说 Linter -> Ex: 前端最常见的 ESLint、StyleLint 等

  • 常见的规范化实现方式

    • ESLint 工具使用
    • 定制 ESLint 校验规范
    • ESLint 对 TypeScript 的支持
    • ESLint 结合自动化工具或者 Webpack
    • 基于 ESLint 的衍生工具
    • StyleLint 工具的使用
    • 演示 git Hock 配合 ESLint 工具如何在代码提交之前进行一些自动化校验

2. ESLint 介绍

当下使用工具完成项目的校验工作是更加高效 合理的 -> 这里就介绍 ESLint:

  • 最主流的 JS Lint 工具 专门检测 JS 代码质量

  • ESLint 很容易统一开发者的编码风格

    Ex: 缩进、换行、分号以及空格之类的使用 -> ESLint 还可以帮助找到代码中不合理的地方 Ex: 定义了未被使用的变量、在变量使用之后再去进行申明、进行比较的时候往往总是选择双等(==)符号等问题

  • ESLint 可以帮助开发者提升编码能力

    如果你编写的代码每次在执行 Lint 的时候都能找出一堆的问题 -> 而这些问题大多数都编码时候的坏习惯 慢慢的你就会记住这些问题 当下次编码时就会避免这些问题 -> 久而久之 编码能力自然而然的也就得到了提升

3. ESLint 安装

这里介绍 ESLint 使用之前的一些工作 -> ESLint 的安装和校验

ESLint 安装步骤:

  • 初始化项目

  • 安装 ESLint 模块为开发依赖

    ESLint 其实就是基于 node 开发的 npm 模块 -> 通过 npm 或者 yarn 安装 ESLint 模块

  • 通过 CLI 命令验证安装结果

    完成安装后 就可以通过简单的命令校验是否安装成功

通过命令行 初始化 package.json

yarn init --yes

通过命令行安装 ESLint 模块

cnpm i eslint -D

就现阶段来说 很少全局安装某个模块 -> 因为大多数情况下都是具体项目依赖某个模块 -> 把模块安装在项目本地 让它跟着项目一起 管理会更加的合理 -> 而且别人拿到你的项目之后不需要单独的关心项目的依赖了哪些全局模块 直接通过 npm install 就可以安装必要的工具模块 -> 这也从侧面的提高了项目的可维护性 => 由于 ESLint 模块提供了一个 CLI 程序 所以安装完成后 在项目 node_modules/.bin 就会多出一个 ESLint 的可执行文件 -> 后续就可以通过该 CLI 程序检测代码中的问题

通过命令行查看 ESLint 的版本

yarn eslint -version 或者 npx eslint --version

打印出 ESLint 的版本说明安装成功 -> 这里不需要纠结到底该使用 npm 还是使用 yarn -> 他们两者之间没有绝对的好坏之分 各有各的优势 按照所在团队/项目 的具体要求使用任何一款即可

4. ESLint 快速上手

先完成项目的初始化和 ESLint 模块的安装; ESLint 检查步骤:

  • 编写"问题"代码

  • 使用 ESLint 执行代码检测

  • 完成 ESLint 使用配置

    在第一次使用 ESlint 必须要完成相对应的配置 然后才能正常的使用

完成项目的初始化和 ESLint 的安装

在项目的根目录下新建 prepare.js 并编辑 prepare.js

const foo = 123


function fn () {
  console.log('hello')
  
  	console.log('eslint')
  
  
}


fn(
  
  syy()

通过命令行运行 ESLint 找到上述代码中的问题

执行 ESLint 命令需要带上具体的文件路径 -> 这里的路径也可以是路径的通配符 因为这样就可以实现批量检查 -> 这里选择的是具体的文件路径

yarn eslint ./prepare.js

执行命令: 终端打出错误信息:

通过错误提示 运行 eslint --init

yarn eslint --init

控制台打印出交付性问题:

  • 语法错误: 很好理解 Ex: 上述代码中 fn() 方法的调用
  • 问题代码: 指的就是代码中不合理的地方 Ex: 上述代码中定义了未被使用的变量 foo 或者说调用了一个不存在的函数 syy
  • 代码风格: 最好理解 在最初的时候 对 ESLint 的期望值就是: 希望 ESLint 能够找出在编码风格上的一些问题 Ex: 代码中的缩进和换行是不统一的

这里选择 To check syntax, find problem, and enforce code style

=> Q2: 你的项目中模块化采用的是那种类型?

这里的选择决定你的代码当中是否允许出现指定的语法或者调用 -> 如果选择的是 CommonJs 就允许 全局的 require 函数和 exports 对象 -> 如果选择的是 ESM 就可以使用 import() 和 export 语法 -> 上述代码没有用到模块化 选择 None of these

=> Q3: 利用的是哪一款框架?

这里选择 None of these

=> Q4: 你代码中有没有使用 TypeScript?

这个没有使用 输入 N

=> Q5: 你的代码将运行在什么环境中?

这里选择 Browser

=> Q6: 你想怎样定义项目代码风格?

一般情况下选择: 市面上主流的代码风格 -> 这样项目中如果有新的成员加入 就可以更好 更快的适应我们的风格

=> Q7: 选择哪一种市面上主流的风格?

选择完毕后 -> 又给出了三个主流风格

其中 Airbnb 和 Google 分别是这两家公司的具体编码规范 -> 而 standard 是社区中的一套规范 -> 个人平时喜欢 Standard 规范: 最大的特点: 不用在语句的末尾添加分号 -> 这里选择 Standard 至于你选择什么 全凭自己的喜好

=> Q8: 你的配置文件想要以何种格式的文件进行存放?

个人建议使用: JavaScript 格式 -> 在配置文件中添加一些条件判断 从而决定是否开启某些功能

选择完以后 终端提示额外安装几个插件 -> 这里选择 Y -> npm 就会安装这些插件

一切完成后 项目的根目录下就会生成 ESLint 的配置文件 .eslintRC.js -> 通过命令行运行 ESLint 检验 prepare.js

yarn eslint ./prepare.js

执行完毕后: 终端检测出错误

=> 这里首先找到的是语法错误 -> 修改 prepare.js 中 fn() 函数的调用

再次通过命令行执行 ESLint 检查

这次终端会检查出更多的错误: 为什么刚刚没有检测出这些错误 -> 原因是: 当代码中存在语法错误的时候 ESLint 是没法检查问题代码和代码风格的 -> 这时可以根据终端的提示 找到错误代码 依次的解决 => 也可以用过 --fix 参数自动修正绝大多数代码风格上的问题 -> 这里通过 --fix 完成一次修正

通过命令行参数 --fix 完成代码风格修正

yarn eslint ./prepare.js --fix

执行完毕后: 代码风格上的问题都被自动修正了 -> 不过你还没有养成良好的编码习惯 建议开始时 还是手动修改错误提示 这样可以加深你的印象 => 这里控制台还打印出两个问题:

=> 修改 prepare.js: 删除 foo 的定义 和 syy() 函数的调用

再次运行 ESLint 检查 -> 就不在报错

**ESLint 的基本作用: 1. 可以找出代码中的问题 -> 问题包括: 语法错误、代码不合理及风格不统一 2. ESLint 可以修复代码风格上的绝大多数问题 **

5. ESLint 配置文件解析

这里来深入了解 ESLint 的配置文件: 之前 通过命令 eslint --init 在项目的根目录下创建了 .slintRC.js 的配置文件 在这个文件中写入的配置就会影响到当前目录以及所有子目录的文件 -> 正常情况下 是不会手动修改该配置文件的 但是如果需要开启或者关闭某些校验规则时 就需要修改该配置文件中的配置项 => 接下来: 就一起来看看 该配置文件中的配置内容

提前做好项目的初始化以及 ESLint 的初始化

在根目录下新建 configuration.js

后续会在它里面去编写示例代码 演示配置文件修改之后的结果

打开配置文件

因为该配置文件最终也是运行在 node 环境中 所以可以看到是以 CommonJs 的方式导出了一个配置对象 在该配置对象中 有四个配置选项: 1. env 2. extends 3. parseroptions 4. rules

5.1. ESLint 配置项-env: 标记当前代码的运行环境

我们都知道 JS 在不同运行环境中是有不同的 API 可以被调用 这些 API 很多时候都是以全局成员的方式提供处理的 Ex: 在浏览器环境可以直接使用 window 和 document 对象 而在 node 环境中却不存在这些对象 => env: 标记当前代码的运行环境 ESLInt 会根据当前的配置的环境信息判断某一个成员是否是可用的 -> 从而避免代码中使用不可使用的成员 -> Ex: 当前配置中的 browser: true 表示当前代码会运行在浏览器环境中 -> 那么在环境中就可以直接使用 document 或者 window 等全局对象 -> 这里的每一种环境对应着一组预定义的全局变量 一旦开启了某个环境 该环境所对应的全局变量都可以被允许被使用

编辑配置文件 修改 browser 的值为 false

//.eslintrc.js
env: {
  browser: false,
  es2020: true
},
......

编辑 configuration.js

document.getElementById("#abc")

通过命令行运行 ESLint 检查 configuration.js

yarn eslint ./configuration.js

可以看到: 这里并没有报出 document 未定义的错误 -> 这时因为在生成 ESLint 配置时选择的 standard 风格 最终这里的配置也就继承了 standard 的配置 -> 而在 standard 的配置中做了一些具体的配置 这时的 document 和 window 在任何的环境中是都可以使用的 => 可以找到 standard 的配置来进行求证 -> 因为配置文件中的 extends 加载的规则就是找 eslint-config-standard 的文件名称 -> 在 node_modules 下找到 eslint-config-standard : 该模块导出的是 json 文件的配置 找到并打开 eslintrc.json

该文件中将 document、navigator 以及 window 通过 globals 设置为了全局只读的成员 -> 而当前的项目配置又继承了该 配置文件 -> 所以刚刚的 env 设置无法影响到 document 的使用 -> 知道了这个原因 可以换一个 window 下的全局成员进行使用

在 configuration.js 中使用 alert

//document.getElementById("#abc")
alert(11)

命令行运行 ESLint 检查

yarn eslint ./configuration.js

运行代码 终端就会报出 alert 未被定义错误

=> 这样证明了 env 选项就是根据配置的环境信息来判断全局成员是否可用 => env 可以配置哪些运行环境勒?

=> 需要注意的是: 这些配置环境选项并不是互斥的 你可以同时开启多个不同的环境 Ex: 可以将 browser 和 node 都设置为 true -> 这样两个环境中的所用全局成员就都可以去同时使用

5.2. ESLint 配置项 - extends: 用来继承一些共享的配置

extends: 用来继承一些共享的配置 Ex: 这里的 standard 很多时候如果你需要在多个项目之间共享一个 ESLint 配置 -> 就可以定义一个公共的配置文件或者说配置模块 然后在 extends 中继承该配置或者文件 => 该属性值可以是一个数组 -> 他可以同时继承多个共享配置 具体的操作在后面会用到

5.3. ESLint 配置项 - ParserOptions: 设置语法解析器的相关配置

近几年 ECMAScript 发布了很多语法 Ex: let const 这些关键字 -> 该属性的主要作用就是: 控制是否允许使用某一个 ES 版本的语法

编辑 .eslintrc.js

......,
parserOptions: {
  ecmaVersion: 5
},
......

修改完成后 代码中就没有办法使用 ES6 的新特性了

编辑 configuration.js

const csa = 222

通过命令行运行 ESLint 检查代码

yarn eslint ./configuration.js

控制台打印出错误信息:

在 ecmaVersion 低于 2015 情况下 sourceType 不能是 module -> 因为 ESModules 是 ES2015 中的新特性 然而在 standard 的配置中 sourceType 设置为了 module

修改 standard 的配置文件 eslintrc.json: 将 sourceType 的值设置为 script

......,
"sourceType": "script",
......

修改完成后 再次运行 eslint 检查代码: 报出错误信息 ->

这里也需要注意一点: parserOptions 中版本的配置影响的只是语法检查 不代表某些成员是否可用 -> 如果是 ES2015 提供的全局成员 Ex: Promise 还是需要 env 中的 ES2016 选项 进行控制

修改 .eslintrc.js

module.exports = {
  env: {
    browser: false,
    es6: false
  },
  ......,
  parserOptions: {
  	ecmaVersion: 2015
	},
  ......
}

编辑 configuration.js

const foo = 1
let csa = 2
let a = new Promise()

命令行运行 eslint 检查 configuration.js(yarn eslint ./configuration.js) -> 控制台报错: Promise is not defined => 具体的成员是否可用还是需要通过 环境来定义

5.4. ESLint 配置项 - rules: 配置 ESLint 中每个检验规则的开启或者关闭

ESLInt 配置项: rules -> 配置每个检查规则的开启或者关闭 -> 具体的开启关闭方法就是在 rules 中开启某个属性 属性名为内置的规则名称 属性值可以是三种:

  • off: 关闭该条规则
  • warn: 发出警告
  • error: 报出错误

编辑 .eslintrc.js

......,
relues: {
  'no-alert': 'error'
}

编辑 configuration.js

alert('cs')

通过命令行运行 ESLint 检验 configuration.js(yarn eslint ./configuration.js) -> 终端报错: ‘alert’ is not defined

=> 具体来说会有哪些规则可以使用? -> 在 ESLint 的官网上给出了所有内置的可用的校验列表 -> 目前使用的 standard 中开启了很对校验规则 基本上满足了校验需求 如果有需要的情况下 可以根据自己的需要进行配置 方法就是修改 rules 里面的配置项

5.5. ESLint 配置项 - globals

该选项的作用是: 额外的申明代码中可以使用的全局成员 Ex: 在使用了 JQuery 的项目中一般都会使用全局的 JQuery 对象 -> 就可以直接添加一个 JQuery 将 值设置为 readonly -> 这样代码中就可以直接使用 JQuery -> 而且也不会报错

编辑 .eslintrc.js

......,
globals: {
  "jQuery": "readonly"
}

编辑 configuration.js

.....
jQuery('#cas')

运行 ESLint 检验 configuration.js -> 不会提示 JQuery 使用错误 -> 这就是 globals 的作用

6、ESLint 配置注释

配置注释可以理解为将配置直接通过注释的方式写在脚本文件中 -> 再去执行代码校验 -> 为什么要这么做勒: 在实际的开发过程中 如果使用 ESLint 难免会遇到一两个违反规则的情况 项目中不能因为这一两个点就推翻校验规则的配置 -> 所以 在这种情况下就可以使用 ESLint 的配置注释解决该问题 => 提前做好准备工作: 初始化 package.json、安装 ESLint 模块、根目录下新建 eslint-configuration-comments.js、根目录下新建 ESLint 配置文件: .eslintrc.js

编辑 eslint-configuration-comments.js

// 定义一个普通字符串 在该字符串中 因为业务的需求 要使用 ${} 字面量占位符 但是 standard 风格是不允许这样使用的
const str1 = "${name} is a coder"

console.log(str1)

运行 ESLint 检查 eslint-configuration-comments.js

yarn eslint ./eslint-configuration-comments.js

运行命令 控制台报错:

=> 这时就可以通过注释的方式临时禁用当前规则 这种注释的语法有很多种 具体可以参考 ESLint 官方文档

编辑 eslint-configuration-comments.js

这里通过 eslint-disable-line -> 这样 ESLint 在工作时就会选择性的忽略这行的检查

const str1 = "${name} is a coder" // eslint-disable-line

console.log(str1)

重新运行 ESLint 检查 eslint-configuration-comments.js 文件 -> 控制台不会报出此前的错误信息: => 这样使用 虽然可以解决所面临的问题: 一行当中如果有多个问题存在的时候 那么所有的问题都被忽略了 -> 更好的做法就是: 在 eslint-disable-line + 需要禁用的规则名称

编辑 eslint-configuration-comments.js

const str1 = "${name} is a coder" // eslint-disable-line no-template-curly-in-string

console.log(str1)

运行 ESLInt 检查: => 此时 ESLint 在工作时就只会忽略掉当前指定的规则 其他的规则任然会被正常的发现 => 注释的方式不仅只用于禁用某种规则 还能申明全局变量、修改某个规则的配置、临时开始某个环境等等 -> 如果你需要 可以通过 eslint.cn/docs/user-g… 中的文档进行具体的使用

7. ESLint 结合自动化工具

我们都知道 ESLint 是一个独立的工具 如果现在在一个有自动化工作流的项目中 -> 建议你将 ESLint 集成到自动化的工作流中 -> 这样做有两个优点:

  • 集成之后 ESLint 一定会工作

    自动化工作流中 肯定会执行自动化构建的 将 ESLint 集成到构建的过程中 就可以确保 ESLint 一定会工作

  • 与项目统一 管理更加方便

    整合在一起管理 也会更加方便 与项目相关的命令也会更加统一 不用一会执行 Gulp 一会执行 ESLint

=> 前期准备工作:

  • github.com/zce/zce-gul… 克隆项目
  • 完成相关的依赖安装
  • 完成 ESLint 模块安装
  • 完成 gulp-eslint 模块安装

打开 gulpfile.js

折叠代码 -> 找到构建 JS 的构建任务函数: 简单的分析下 可以发现 JS 的构建任务使用了 babel 转换了源代码 而我们现在要做的就是将 ESLint 操作集成进 -> 因为 Gulp 是一种管道工作机制 如果要将 ESLint 集成进去 就应该在 babel 转换之前进行 ESLint 操作 -> 否则的话 经过 babel 之后 代码就不再是真正的源代码

编辑 gulpfile.js

......
const script = () => {
  return src('src/assets/script/*.js', { base: 'src' })
  .pipe(plugins.eslint())
  .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
  .pipe(dest('temp'))
  .pipe(bs.reload({ stream: true }))
}
......
module.exports = {
  clean, build, develop, script
}

这样之后 当前 script 任务就会先去执行对 JS 代码的 ESLint 操作 再去执行 babel 的编译

通过 gulp 执行 script 任务

yarn gulp script

执行后控制台报错: -> 没有找到 ESLint 的配置文件

再次执行 eslint script 命令

这次 eslit 检查就被正常的执行了

在 mian.js 中故意书写错误代码

......
const a = 1

执行 eslint script 命令

该命令同样是可以正常执行的 这就显得不合理的 -> 因为在最初的设想就是当 ESLint 发现问题后就可以直接体现出来 同时也终止后续的编译任务 -> 这里为什么可以成功的执行: 因为默认情况下 这里的 ESLint 插件只会检查代码中的问题 并不会根据检查的结果做出任何的反馈 -> 正确的做法: 在 ESLint 处理完成以后 先去使用 ESLint 的 format 方法在控制台众打印出错误信息 -> 之后再使用 ESLint 的 failAfterError方法 让 ESLint 在检查出错误之后可以直接终止任务管道

编辑 gulpfile.js

......
const script = () => {
  return src('src/assets/script/*.js', { base: 'src' })
  .pipe(plugins.eslint())
  .pipe(plugins.eslint.format())
  .pipe(plugins.eslint.failAfterError())
  .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
  .pipe(dest('temp'))
  .pipe(bs.reload({ stream: true }))
}
......

通过命令行重新执行 script 任务(yarn gulp script) -> 这时在控制台中就输出了错误信息: -> 这时 ESLint 就算是集成到编辑 JS 的任务中了

8. ESLint 结合 Webpack

8.1 ESLint 结合 Webpack 配置

如果你现在正在开发使用 Webpack 打包的项目 ESLint 同样也可以集成进去 -> 只不过 Webpack 集成 ESLint 并不是以插件的方式完成的 而是通过 Loader 机制 => Webpack 在打包模块之前 会先将遇到的模块交给对应的 Loader 进行处理 -> 所以 ESLint 就可以通过 Loader 的形式集成到 Webpack 当中 -> 这样就可以实现在打包 JS 代码之前 先通过 ESLint 来校验 JS 代码 => 提前准备工作:

  • 通过 github.com/zce/zce-rea… 克隆仓库

  • 安装对应模块

  • 安装 ESLint 模块

  • 安装 eslint-loader 模块

  • 初始化 .eslintrc.js 配置文件

    => 这就是i一个普通的 React 应用 并没有使用官方所提供 CLI 工具 而是使用 Webpack 完成应用的构建

编辑 webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  mode: 'production',
  entry: './src/main.js',
  module: {
    rules: [
      // 目前所有的模块都是交给 babel-loader 处理 如果想要集成 ESLint 同样需要在 babel-loader 之前使用 eslint-loader 进行处理 -> 因为在这之前完成了模块的安装
        //这里直接将 JS 使用的 Loader 修改为数组 然后将 eslint-loader 放在数组的后面 -> 这里一定要注意: Loader 的顺序 -> 这里的 Loader 是从后向前执行的 
        // 这里还有另外一个更为常见的配置方法: 单独为 JS 文件再添加一个 Loader 规则 -> 在这个规则中添加一个 enfore 属性 属性值设置为 pre: 确保这个规则中配置的 Loader 的优先级是优于其他 Loader (推荐) 
      {
        test: /\.js$/,
        exclude: /node_modules/,        
        use: 'babel-loader'
      },
      //第二种做法
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'eslint-loader',
        enfore: 'pre'
      },
      ......
    ]
  },
  plugins: [
      new HtmlWebpackPlugin({
      	template: 'src/index.html'
      })
    ]
}

通过命令行执行 Webpack 打包命令

yarn webpack

执行完成后 控制台报错: ESLint结合Webpack报错信息 -> 这也是实现了将 ESLint 通过 Loader 的方式集成到了 Webpack 中

8.2. ESLint 结合 Webpack 后续配置

之前已经使用 eslint-loader 的方式在使用 Webpack 的项目中集成了 ESLint -> 接下来就需要添加 ESLint 相对应的配置 从而完成后续的代码检查操作

查看 .eslintrc.js

这里的配置刚好可以满足 React 项目的需求 -> 但是执行 Webpack 打包 报错(报错信息见 7.1) => 找到 main.js 单纯的从代码本身分析ESLint结合Webpack-main.js -> 这里的 React 的确并没有被使用 -> 但是这里的 React 是 JSX 代码编译之后代码所必须的 ->像这种特殊的情况 ESLint 就必须靠一些额外的插件来实现: eslint-plugin-react

通过命令行安装 eslint-plugin-react

cnpm i eslint-plugin-react -D

安装完成后 在 node_modules 目录下找到 eslint-plugin-react 模块 -> 这个模块中定义了很多校验规则 这些规则都是专门针对于 React 项目的 -> 想要使用这些规则: 在 .eslintrc.js 中通过 plugins 属性进行配置

编辑 .eslintrc.js

module.exports = {
  ......,
  rules: {
  	// 这里属性的值 可以设置为 Error/warn/off 也可以使用 2/1/0
  	'react/jsx-uses-react': 2, // 该规则可以避免 React 定义了 未被使用的报错
	},
  // plugins 的值是一个数组 数组的成员可以直接指定使用某些插件(插件的名称需要去掉 eslint-plugin) 
  // 完成配置后 eslint-plugin-react 模块中的所有规则都可以使用了
  plugins: [ 'react' ]
}

通过命令行执行 Webpack 打包

yarn webpack

执行完毕后: 控制台错误信息中 之前的 React 报错没有出现eslint-plugin-react规则配置-> 但是这里还有一个 APP 没有定义的错误 => 这里同样使用刚才的方法 -> 只不过这里要换成另外的规则: react/jsx-uses-vars

编辑 .eslintrc.js

module.exports = {
  ......,
  rules: {
  	'react/jsx-uses-react': 2,
  	'react/jsx-uses-vars': 2
	},
  plugins: [ 'react' ]
}

运行 Webpack 打包

控制台不在输出错误 -> 这就是插件的作用以及基本使用 不过对于大多数 ESLint 插件来说 一般都会提供贡献的配置 从而降低使用成本 => 这里使用的 eslint-plugin-react 导出了两个共享配置: recommended 和 All -> 而我们现在要使用的就是 recommended -> 这个共享配置就可以直接通过继承来使用 -> 不过在继承时需要遵循他的语法规则: plugin: 插件名/共享配置名

编辑 .eslintrc.js

module.exports = {
  ......,
  extends: [
  	'standard',
  	'plugin:react/recommended'
  ]
  ......,
  rules: {
  	 /* 'react/jsx-uses-react': 2,
  	'react/jsx-uses-vars': 2 */
	}/*,
  plugins: [ 'react' ]*/
}

执行 Webpack 打包 和 不使用 共享配置的结果是一样的

9. 现代化项目集成 ESLint

随着 React 或者 Vue 等框架的普及 框架的生态已经非常的完善了 最明显的感觉就是: 现阶段开发一个基于 React 或者 Vue 的项目 基本上不需要自己配置 Webpack 或者 ESLint 这些工程化的工具了 而在官方的 CLI 工具中都已经将 他们集成进去了 => 这里就以使用 Vue-CLI 创建一个 Vue.js 的项目作为演示

通过命令行安装 vue-cli

cnpm i @vue/cli -g

通过命令行 执行 vue create xxxx 创建项目

vue create syy-vue-app

控制台交互信息:

其中需要注意的是 询问在什么样的环节需要 Lint 操作: Lint on save : 在 Webpack 构建时自动进行校验: 因为通常采用的都是监视模式开发项目 -> 也就是文件被修改之后 Webpack 就会自动执行编译 -> 这里就称作为保存时的校验 Lint and fix on commit: commit 环节 -> 利用 git 的钩子在 git 的commit 之前自动校验当前的代码 -> 这样就确保了提交到仓库中的代码都是经过校验的 建议将两个都勾选上

=> 完成相关操作之后 -> Vue-CLI 就会自动安装相关的依赖 在最后创建基本的项目结构 在这个过程中 ESLint 就被集成进去了

通过命令行进入项目 -> 启动项目

cd syy-vue-app
npm run serve

编辑 src/main.js 故意添加错误代码

......
const a = 1

保存之后 控制台输出错误信息: -> 通过这样 开发者不需要在工具的配置和使用上花太多的时间 开发者可以专注于业务功能的开发

10. ESLint 检查 TypeScript

在现阶段 前端项目中使用 TypeScript 开发的情况越来越多 这里就来看看 ESLint 是如何来校验 TypeScript 代码的 => 提前准备: 一个案例项目、npm 初始化、ESLint 模块的安装、TypeScript 模块的安装 -> 这里注意一定要安装 TypeSc 模块 否则在后续生成 ESLint 配置文件的时候就会报错 -> 对于 TypeScript 代码的 Lint 来说 以前本来都是使用 tslint 的工具 但是后来 tslint 的官方就放起维护了 然后转而建议我们使用 ESLint 配合 TypeScript 插件来实现 TypeScript 的校验

初始化 ESLint 配置操作

yarn eslint --init

这里需要注意的是: 问题交付中 涉及到 TypeScript 模块的时候要选择 Yes -> 最后的交互需要安装两个额外的模块 这两个模块是 ESLint 检查 TypeScript 代码所必须的

=> 交互问题完成完成之后就可以直接使用 ESLint 来检查 TypeScript 的代码了

编辑 index.ts

function foo (ms: string): void {
  console.log(msg)
  
}

foo("hello TS ~")

查看 .eslintrc.js

这里会有一个特别的选项: parser -> 它的作用: 指定一个语法解析器 这里需要配置语法解析器的原因: 因为 TypeScript 相比较于普通的 JS 代码 会有很多特殊的语法 -> 所以需要制定一个语法解析器

通过命令行校验 index.ts

yarn eslint ./index.ts

执行完毕后 控制台报错:

11. StyleLint 认识

11.1. StyleLint 对普通 CSS 代码的检查

目前在前端项目中 除了 JS 代码需要被 Lint 外 CSS 代码也需要被 Lint -> 对于 CSS 代码的 Lint 一般都会使用 StyleLint 的工具来完成 StyleLint 的使用和 ESLint 的使用基本上是一致的

=> StyleLint 使用介绍:

  • 提供默认的代码检查规则
  • 提供 CLI 工具 快速调用
  • 通过插件支持 Sass Less PostCSS
  • 支持 Gulp 或 Webpack 集成

=> 提前准备: npm 初始化、css 和 Sass 文件的准备

通过命令行安装 StyleLint 模块

cnpm i stylelint -D

安装完成之后 在 node_modules/.bin 目录中可以找到 stylelint 的 CLI 命令 有了这个命令之后就可以通过这个命令检查样式文件代码了

通过命令行运行 StyleLint 检查 index.css

yarn stylelint ./index.css

控制台输出错误: 没有找到相对应的配置文件

在根目录下手动添加 .stylelintrc.js 并编辑

StyleLint 里面的配置项基本和 ESLint 是相同的

module.exports = {
  // StyleLint 的内部并没有提供任何可用的共享配置 所以需要自行的安装一些模块
  extends: "",
}

通过命令行安装 stylelint-config-standard

stylelint-config-standard: StyleLint 共享配置模块

cnpm i stylelint-config-standard -D

编辑 .stylelintrc.js

安装完成后 直接使用该模块 -> 但是这里有一些和 ESLint 不一样的地方: 这里的共享配置名称必须是一个完成的模块名称

module.exports = {
  extends: "stylelint-config-standard"
}

再次通过命令行检查 index.css

yarn stylelint ./index.css

执行完毕后 这次就可以找到 CSS 代码中的问题了: -> 发现这些问题之后 可以直接定位去修改 -> 也可以通过 --fix 命令行参数直接完成大多数问题的自动化修复

11.2. StyleLint 对 Sass 代码的检查

如果需要通过 StyleLint 校验项目中的 Sass 代码 -> 需要安装另外的模块: stylelint-config-sass-guidelines -> 该模块中安装了 StyleLint 的 sass 插件 可以直接使用

通过命令行安装 stylelint-config-sass-guidelines

cnpm i stylelint-config-sass-guidelines -D

编辑 .stylelintrc.js

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

通过命令行执行 StyleLint 检查 index.sass

yarn stylelint ./index.sass

执行完成后 StyleLint 检查出 Sass 代码问题: -> 除了对 Sass 代码的校验 Less PostCSS 代码的校验 他们的操作都是类似的 这里就不在一一讲述了

=> 如果你想把 StyleLint 集成到 Gulp 或者 Webpack 中 你可以参考 ESLint 的集成方法

12. Prettier 的使用

Prettier 是近两年来使用频率特别高的通用的前端代码格式化工具 它很强大 几乎可以完成所有类型代码文件的格式化工作 -> 在日常的使用中 也可以通过它来完成代码的自动格式化 或者说 针对于 markdown 这样的文档进行格式化操作-> 简单的说就是: 通过 Prettier 就可以很容易的落实前端项目中的规范化标准 而且他的使用也是非常简单的

=> 提前准备工作: 将日常前端开发过程中所能够遇到的不同代码文件做了准备

通过命令行安装 Prettier

yarn i Prettier -D

安装完成后就可以直接使用模块中所提供的 prettier 命令格式化测试代码

通过命令行执行 prettier 命令格式化 style.css

yarn prettier ./style.css

执行命令后: 控制台输出格式化的 css 代码 -> 默认情况下 执行 prettier 之后的结果是将格式化之后的代码直接输出到控制台中 -> 要将格式化后的代码直接覆盖源文件 -> 需要在尾部加上命令行参数 --write

通过命令行执行 prettier 命令并将格式化之后的代码覆盖源文件

yarn prettier ./style.css --write

执行命令之后 Prettier 就可以自动的格式化文件了

通过命令行 利用通配符的方式 一次性将所有的代码都格式化

yarn prettier . --write

执行命令后: prettier 将所有的代码都进行了格式化并覆盖了源文件

13. Git Hooks 工作机制

这里介绍 Git Hooks 的一些使用内容的介绍 因为在后续中需要使用 ESLint 和 Git Hooks 的结合 -> 目前 都已经了解了代码规范化的重要性 以及 如何通过使用一些工具确保代码的规范 -> 但是在这个过程中还是有一些遗漏的问题 Ex: 代码提交至仓库之前未执行 Lint 工作 -> 这会导致在后期在进行项目集成时 整个项目的代码通过不了 CI -> 所以这时 Lint 工具就丧失了它的意义 -> 使用 Lint 工具就是为了确保代码提交到仓库是没有问题的 而且格式也是良好的 -> 我们该怎样去解决这个问题呢? => 通过 Git Hooks 在代码提交前强制 lint

=> Git Hooks 介绍

  • Git Hooks 也称之为 Git 钩子, 每个钩子都对应一个任务

    每个钩子都连着一些具体的 Gti 操作 Ex: Commit push

  • 通过 shell 脚本可以编写钩子任务触发时要具体执行的操作

    找到某个具体的钩子 通过编写一个具体的 shell 脚本定义在钩子动作在触发时要执行的任务: pre-commit 钩子 -> 提交之前触发

14. ESLint 结合 Git Hooks

需求: 通过 Git 钩子 在代码提交之前强制实现对代码的 Lint 操作 => 这里遇到一个很现实的问题: 当下很多前端开发者并不擅长使用 shell 脚本编写功能 -> 而当前这个功能又是必须使用的 -> 所以就有人开发了一个 npm 的模块: Husky -> 可以实现 Git Hooks 的使用需求 可以在不编写 shell 脚本的情况下也能使用 Git 钩子带来的功能

=> 初始准备工作: npm 初始化、ESlint 配置初始化、用于测试的 index 的脚本

通过命令行 安装 husky 模块

cnpm i husky -D

编辑 package.json

{
  "script": {
    "ESLint": "eslint ./index.js"
  },
  ......,
  "husky": {
  	"hooks": {
  		"pre-commit": "npm run ESLint"
		}
	}
}

编辑 index.js

const a = 1

3333

通过命令行将代码 commit 到仓库

git add .
git commit -m '111'

111 为随便书写的信息 => 执行完毕后: 控制台输出 Lint 错误: -> 这时会发现: 在代码 commit 之前 会执行 Lint 的操作 -> Lint 到错误时 代码将不会被提交到仓库 -> 这样已经可以让开发者在 commit 之前完成对代码的检查 => 但是如果想要在检查之后再继续做一些后续的操作 Ex: 将检查后的代码进行格式化 或者说 将格式化的代码添加到暂存区 -> 这时 husky 就显得不够用了

=> 所以 这里继续介绍另外一个功能模块 lint-staged: 配合 husky 继续提供一些其他的功能

通过命令行安装 lint-staged

cnpm i lint-staged -D

编辑 package.json

{
  ......,
  "script": {
    "ESLint": "eslint ./index.js",
  	"preCommit": "lint-staged"
  },
  ......,
  "husky": {
  	"hooks": {
  		"pre-commit": "npm run preCommit"
		}
	},
	"lint-staged": {
    "*js": [
      "eslint",
      "git add"
    ]
  }
}

通过命令行 执行 commit 操作

git add .
git commit -m '222'

执行完成后发现: 程序依次执行了 eslint 和 git add 操作-> 这样就可以在代码提交之前强制的校验提交的代码 同时还可以在验证之前后者验证之后完成其他的一些操作