[TOC] >[success] # 为什么要规范化 ~~~ 1.'软件开发需要多人协同'、'不同开发者具有不同的编码习惯和喜好'、'不同的喜好会增加项目的维护成本' '每个项目或者团队需要明确统一的标准' 2.开发过程中需要规范化内容,'代码、文档、甚至是提交日志'、'开发过程中人为编写的成果物'、'代码标准化规范' 3.如何实时规范化'编码前人为的标准约定'、'通过工具实现 Lint' ~~~ >[info] ## 规范路上前端做了什么 ~~~ 1.JS的弱类型和动态类型,JS的变量在声明时无需指定其类型。并且在其声明之后,可以为其随便赋值不同的类型。 JS由于不需要关注变量的类型,可以使代码更加简洁,也能使开发者集中更多的精力在处理业务逻辑之上。 但由于其无法保证变量类型,从而在程序运行期可能发生跟类型相关的错误。 比如: var s = 1; s(); //Uncaught TypeError: s is not a function 而这样的错误对于JAVA在编译期间就会检查出来。 2.为了可以在编写中发现问题,前端出现了很多种尝试类似'TypeScript、CoffeeScript或Elm' 辅助工具出现了'Lint' 'Lint'工具最早是使用于UNIX系统中C语言的程式码静态分析工具,主要是用来标记语法结构上有可疑的、濳在的问题 语法或指令,在前端类似的这种类似工具有'JSLint与JSHint',随着时代推移'ESLint'由Nicholas C. Zakas创造,正如 是为ES新标准语法所设计,相比其他js 检查工具来说'ESLint'的功能具有 2.1. 有更多规则选项可以依需求或喜好设定 2.2. 函式库或框架的开发者可以依需求再开发扩充 2.3.支持更高的es 语法和实验特性和JSX 语法 2.4.提供错误警告 3.ESlint需要将源码转为AST 的特点并且还可以扩展规则,默认的解析器也能替换,这种自由度高 可插拔的形式,最后'ESLint' 成为现阶段'js' 代码质量检查的工具 ~~~ >[info] ## Eslint -- 专注于 JavaScript 代码质量检查 ~~~ 1.'Eslint'最为主流的 JavaScript Lint 工具,检测 JS 代码质量可以统一开发者的编码风格 2.'ESLint' 使用 Node.js 编写 ~~~ >[danger] ##### 安装eslint ~~~ 1.先初始化项目 -- 'npm init -y' 2.安装Eslint 模块为开发依赖 -- 'npm install eslint -D' 2.1.通过npx 可以产看'eslint' 版本 -- 'npx eslint --version' ~~~ >[danger] ##### 如何使用 ~~~ 1.初始化生成配置文件 -- 'npx eslint --init' 初始化的时候会询问几个问题: 问题1 : 如何使用ESLint ? 只检查语法错误 | 检测语法错误以及问题代码 | 检测语法错误以及问题代码以及代码风格 问题2: 你的项目模块化选择类型? JS modules(import/export) | CommonJS(require/exports) | None of these 问题3:项目使用框架 问题4: 是否使用TS 问题5: 运行环境 Browser | Node 问题6: 定义代码风格 主流代码风格 | 个人自定义 | 根据代码判断 问题7:配置文件格式 JS | YARM | JSON 问题8: 安装额外的插件Y 安装完成后会出现.eslintrc.js文件 2.根据上面的询问选好配置后 2.1.'npx eslint [文件路径]' -- 检查对应文件中编码格式。路径可以使用路径通配符 2.2.'npx eslint [文件路径] --fix' -- 自动修正代码风格 ~~~ >[danger] ##### eslint 检查的是什么 ~~~ 1.通过执行elint 的指令看到了编写文件产生的错误和帮助我们修改了错误,eslint 到底检查的是什么? 1.1.'语言语法检查':比如检查出字符串引号或者函数调用括号没有匹配等问题。 1.2.'编码错误检查':比如检查出开发者在使用一个不存在的变量或者变量定义了却没有使用等问题。 1.3.'代码风格检查':比如检查出开发者没有使用分号(与所选风格有关)等问题。 注意他不会检查你js api调用的是否正确,明确他能做的 ~~~ >[danger] ##### eslint 检查指令 ~~~ # 检测单个文件 npx eslint file1.js file2.js # 检测src和scripts目录 npx eslint src scripts 2.案例 var a = "1"; const zz = "1000" ~~~ * 检查对应文件中编码格式 给出了错误原因 ![](https://img.kancloud.cn/2f/54/2f54c221ffcea6245c24e495330e126b_691x220.png) >[danger] ##### 修复 fix ~~~ 1.--fix后缀,是ESLint提供自动修复基础错误的功能,它只能修复一些基础的不影响代码逻辑的 错误,比如代码末尾加上分号、表达式的空格等等。 2.例如:'npx eslint src scripts --fix' / 'npx eslint file1.js file2.js --fix' 3.案例 var a = "1"; const zz = "1000" ~~~ * 执行 --fix ~~~ 代码被自动修改 为下面代码 const a = '1'; const zz = '1000'; ~~~ ![](https://img.kancloud.cn/c2/3d/c23d4e8a9370c9a3c5bddcae36abf97a_549x77.png) >[danger] ##### 指定文件 -- ext ~~~ 1.eslint 修复和检查都可以指定具体文件或者具体文件夹,例如可以指定具体文件'aa.vue', 'aa.js',但是指定文件时候例如'/src' 这个文件下会有各种文件类型,但eslint 默认只会检测 文件夹中的'js' 文件,此时需要使用'ext' 2.注意只有在指定是文件夹时候使用'ext' 才会生效,举个例子"npx eslint --ext .js,.jsx,.vue src" ~~~ >[info] ## eslintignore 忽略指定文件 ~~~ 1.对于一些公共的js,或者测试脚本,不需要进行检测,我们可以通过在项目根目录创建一 个.eslintignore告诉ESLint去忽略特定的目录或者文件 ~~~ >[info] ## eslint 配置文件 -- .eslintrc.* ~~~ 1.eslint 提供了配置文件在里面可以配置想要检查的规则: 1.1.'JavaScript' - 使用 .eslintrc.js 然后输出一个配置对象。 1.2.'YAML' - 使用 .eslintrc.yaml 或 .eslintrc.yml 去定义配置的结构。 1.3.'JSON' - 使用 .eslintrc.json 去定义配置的结构,ESLint 的 JSON 文件允许 JavaScript 风格的注释。 1.4.'(弃用)' - 使用 .eslintrc,可以使 JSON 也可以是 YAML。 1.5.'package.json' - 在 package.json 里创建一个 eslintConfig属性,在那里定义你的配置。 优先级 '.eslintrc.js' > '.eslintrc.yaml' >'.eslintrc.yml' >'.eslintrc.json' >'.eslintrc'> 'package.json' 2.配置文件中的字段说明: 2.1.'parser' 解析器'ESLint '默认使用 'Espree' 作为其解析器,主要将写的内容转成ast 根据规则来验证 2.2.'extends'ESLint递归地扩展配置 2.3.'rules': 定义规则,可以覆盖掉extends的配置 2.4.'parserOptions':解析器配置 2.5.'plugins':为eslint新增一些检查规则 2.6.'env': 一个环境定义了一组预定义的全局变量 ~~~ >[danger] ##### parser -- 解析器 ~~~ 1.想成为eslint 的parser解析器需要满足两点 1.1.'它必须是一个 Node 模块,应该使用 npm 单独安装解析器包.' 1.2.'它必须符合 parser interface(https://eslint.bootcss.com/docs/developer-guide/working-with-plugins#working-with-custom-parsers)' 2.关于其他解析器'Esprima','Babel-ESLint','@typescript-eslint/parser ' 2.1.'esprima':ESLint最开始使用的解析器 2.2.'espree':由于后来'esprima'没有更新无法在支持,ESLint自己基于esprima v1.2.2开发的一个解析器(默认自带) 2.3.'babel-eslint':一个对Babel解析器的包装,使其能够与ESLint兼容。 2.4.'@babel/eslint-parser':从 v11.xx 版本开始,babel-eslint 不再维护和更新 2.5.'@typescript-eslint/parser':将TypeScript转换成与estree兼容的形式,以便在ESLint中使用。 关于解析器的选择,如果你是Ts那么你需要使用的是'@typescript-eslint/parser',如果你正在尝试新的一些'ES' 语法中的实验属性使用'babel' 提供的解析,当然如果你仅仅是想支持最新的最终 ES 标准可以使用eslint 默认 以目前写文章的节点装饰器为例属于一个实验属性,在使用默认的eslint的解析器 是不行的,你需要使用'babel' '简短的使用教程': 需要安装'npm install @babel/core @babel/eslint-parser @babel/plugin-proposal-decorators --save-dev' 解释一下'decorators' 装饰器目前在第二阶段因此需要下载'babel' 插件,关于配置 module.exports = { "parser":"@babel/eslint-parser", "env": { "browser": true, "es2021": true, "node": true }, "extends": "eslint:recommended", // 相当于配置@babel/eslint-parser 解析器的配置 parserOptions: { // 如果你 没有写 类似.babelrc 将需要requireConfigFile设置fasle // 表示不使用配置文件 requireConfigFile: false, // 因为没有配置类似.babelrc 所以需要配置babelOptions声明使用的插件 babelOptions: { plugins: [["@babel/plugin-proposal-decorators",{"legacy": true}]], } }, "rules": { } }; 如果你配置了类似'.babelrc' 文件那么你就可以不用配置'parserOptions' 这个参数 ~~~ [你使用@babel/eslint-parser 遇到了麻烦参考 Updating babel-eslint to @babel/eslint-parser for React apps ]( https://tjaddison.com/blog/2021/03/updating-babel-eslint-to-babeleslint-parser-for-react-apps/) >[danger] ##### parserOptions ~~~ 1.可以使用解析器选项覆盖该设置以启用对其他 ECMAScript 版本以及 JSX 的支持。简单理解配合你的 解析器,之前说过默认的解析器是'espree'去gitub 搜索你可以发现当传入不同参数的时候配置器将会 有不同的结果返回。 ~~~ >[danger] ##### plugins ~~~ 1.plugin插件主要是为eslint新增一些检查规则,ESLint 虽然可以定义很多的 rules,只是检查 JS 语法。如果需要检查 Vue 中的 template 或者 React 中的 jsx,就束手无策了。引入插件的目的就是为了增强 ESLint 的检查能力和范围 简单的说像vue react 这类新的框架会有自己的规则,这类规则需要去安装额外的插件 2.插件名称可以省略 'eslint-plugin- 前缀' { "plugins": [ "plugin1", // eslint-plugin-plugin1的简写 "eslint-plugin-plugin2" ] } 3.但是要说明一下:如果仅配置`"plugins": ["vue"]`,vue文件中template内容还是会解析失败。 这是因为不管是默认的espree还是babel-eslint解析器都无法解析.vue中template的内容; `eslint-plugin-vue`插件依赖`vue-eslint-parser`解析器,而`vue-eslint-parser`解析器只会解析template内容,不会检测`script`中的JS内容,因此我们还需要指定一下解析器: {     "extends": ["eslint:recommended"],     "plugins": ["vue"],     "parser": "vue-eslint-parser",     "parserOptions": {         "parser": "babel-eslint",         "ecmaVersion": 12,         "sourceType": "module",     }, } 上面`parserOptions.parser`看的有点迷糊,这是由于外层的解析器只能有一个,我们已经用了 `vue-eslint-parser`就不能再写其他的;因此`vue-eslint-parser`的做法是在解析器选项中再传 入一个解析器选项用来处理`script`中的JS内,相当于此时有两个解析器在工作 ~~~ >[danger] ##### extends -- 继承 ~~~ 1.'extends' 从零开始配置eslint 规则是一件麻烦的事但是可以引用其他已经配置好的完整规则文件 1.1."eslint:recommended" 启用 ESLint 推荐开启的规则 ( 查看具体开启规则'https://eslint.bootcss.com/docs/rules/') 1.2."eslint:all" 开启 ESLint 中所有核心规则 在初始化eslint 时候提供的另外三种选择: 1.3.'Google标准':安装 'npm install eslint-config-google -g' 1.4.'Airbnb标准':安装依赖'eslint-plugin-import, eslint-plugin-react, and eslint-plugin-jsx-a11y等插件',想查看 具体详细的依赖可以执行指令'npm info "eslint-config-airbnb@latest" peerDependencies' 1.5.'Standard标准,它是一些前端工程师自定的标准'安装执行 'npm install eslint-config-standard eslint-plugin-standard eslint-plugin-promise -g' 2.'extends 属性值的组成': 2.1.eslint:开头的ESLint官方扩展,有两个:eslint:recommended(推荐规范)和eslint:all(所有规范)。 2.2.plugin:开头的扩展是插件类型扩展 2.3.eslint-config:开头的来自npm包,使用时可以省略eslint-config-,比如上面的可以直接写成standard 2.4.@:开头的扩展和eslint-config一样,是在npm包上面加了一层作用域scope 举个例子(后面的规则会覆盖前面的): { "extends": [ "eslint:recommended" ,// 使用eslint 推荐规范 "airbnb" ,// 相当于使用了eslint-config-airbnb "plugin:vue/essential" ,// vue 必不可少的类型规则 'eslint-config-airbnb-base/rules/strict' // 去指定一个具体文件地址 ], } 3.社区封装的 ESLint plugin,在 npm 上搜索eslint-plugin-就能发现很多,比较出名的有 'eslint-plugin-react ,eslint-plugin-import' 为什么出现这些规则?首先eslint 自带的规则都是 'es'语法本身的规则,那像vue ,react 这种内置的'eslint' 规则并不包含因此出现,以vue 为例 "extends": [ ' plugin:vue/base '//:基础 'plugin:vue/essential '//:必不可少的 'plugin:vue/recommended ' //:推荐的 'plugin:vue/strongly-recommended ' //:强烈推荐 ] 4.如果 extends 配置的是一个数组,那么最终会将所有规则项进行合并,出现冲突的时候,后面的会覆盖前面的; ~~~ >[danger] ##### plugins 和 extends 中 plugin区别 ~~~ 1.'plugins' 理解成扩展校验规则,即原本'eslint' 是为了'js'出现的,随着前端的发展,出现一些其 他格式文件例如'vue',此时eslint 这种可插拔设计,在'plugins' 扩展将其检测规则扩展到eslint 2.规则就像是一个集合,真正想使用什么规则需要人为去配置,这种配置可以使用'rules' 一条 一条的去指定,当然也可以使用一组配置开启集合这个就是'extends ' 字段 3.extends除了使用plugin中 config name 的加载方式,往往也会使用eslint-config-xxxx这样命名的包 module.exports = { plugins: [ 'eslint-plugin-react' // 扩展的规则 ], extends: [ // 新提供的规则一个开启的配置集合 'eslint-plugin-react/recommended' ], rules: { 'eslint-plugin-react/jsx-boolean-value': 2 // 如果没有eslint-plugin-react/recommended需要自己慢慢配置 } } ~~~ >[danger] ##### rules ~~~ 1.规则的校验说明,有 3 个报错等级 1.1.'off 或 0':关闭对该规则的校验; 1.2.'warn 或 1':启用规则,不满足时抛出警告,且不会退出编译进程; 1.3.'error 或 2':启用规则,不满足时抛出错误,且会退出编译进程; 通常规则只需要配置开启还是关闭即可;但是也有些规则可以传入属性,比如: { rules: { 'quotes': ['error', 'single'], // 如果不是单引号,则报错 'one-var': ['error', { 'var': 'always', // 每个函数作用域中,只允许 1 个 var 声明 'let': 'never', // 每个块作用域中,允许多个 let 声明 'const': 'never', // 每个块作用域中,允许多个 const 声明 }] } } 2.通过 rules 单独配置的规则优先级比 extends 高 3.关于规则像在'extends ' 中介绍的根据开头找到他的组织去看他的规则都有哪些可以自己配置 4.也可以在文件中指定规则,主要注释要使用 /**/ 形式,并且 eslint + 规则 + 等级,下面例子 就是'no-var' 是不准使用var 的规则,error 就是使用了要报错的等级 /* eslint no-var: error */ var a = '1' 更多规则: /* eslint-disable */ -- '该注释放在文件顶部,eslint不会检查整个文件' /* eslint-enable */ -- '重新启用eslint检查' /* eslint-disable eqeqeq */'只禁止某一个或多个规则' /* eslint-disable-next-line */'下一行禁止eslint检查' // eslint-disable-line '当前行禁止eslint检查' ~~~ >[danger] ##### globals ~~~ 1.ESLint会检测未声明的变量,并发出报错,比如node环境中的process,浏览器环境下的全局 变量console,以及我们通过cdn引入的jQuery定义的$等;我们可以在`globals`中进行变量声明 2.但是node或者浏览器中的全局变量很多,如果我们一个个进行声明显得繁琐,因此就需要 用到我们的`env`,这是对环境定义的一组全局变量的预设,可以参考下面'env' 字段 ~~~ ~~~ {     "globals": {         // true表示该变量可读写,false表示变量是只读         "$": true,         "console": false     } } ~~~ >[danger] ##### env ~~~ 1.举个例子当我们在项目使用了 浏览器环境全局变量'window','node 环境global','jquery $',这些某种 环境特带的让eslint 知道不是我们用错了而是这类东西是某环境下的 2.es6 中除了模块之外的其他特性,同时将自动设置 parserOptions.ecmaVersion 参数为 6 以此类推 ES2017 是 8,而 ES2021 是 12(parserOptions.ecmaVersion 关于它可以看parserOptions) { "env": { "browser": true, // 项目中有代码在浏览器环境运行 "node": true, // 项目中有代码在 Node.js 环境下运行 "es6": true // 启动 ES6 全局变量和类型,同时会自动设置解析器为ES6 } } ~~~ [更多环境配置](https://eslint.bootcss.com/docs/user-guide/configuring#specifying-environments) >[info] ## 一个整体的配置 ~~~ // .eslintrc.js module.exports = { env: { // 标记当前代码最终的运行环境 browser: true, // 代码运行在浏览器环境 es2020: true }, // 语法解析器配置ts 语法需要自己的语法解析器因此要声明 // parser: '@typescript-eslint/parser', extends: [ // 记录共享配置类似继承的概念,下面的意思是使用node_modules 模块安装的'standard'检查作为模板 'standard' // 如果需要在多个项目共享一个eslin配置,可以定义一个公共配置文件并在此集成 // 继承规则配置 不需要单独配置开关 'plugin:react/recommended' ], parserOptions: { // 设置语法解析器的相关配置 控制是否允许使用某一个ES版本的语法 ecmaVersion: 11 }, rules: { // 配置eslint中每一个校验规则的开启/关闭 'no-alert': "error" // 内置规则名称: off/warn/error // // 2 - ERROR 该规则解决React未使用错误 // 'react/jsx-uses-react': 2 }, // plugins: [ // // eslint-plugin-react 插件 // 'react' // '@typescript-eslint' // ] global: { // 额外声明代码中可使用全局成员 最新版本默认配置已不再体现 // 例如要使用jQuery对象 "jQuery": "readonly" } } ~~~ https://developer.51cto.com/art/202103/650933.htm >[info] ## 参考文章 [eslint 官网](https://eslint.cn/docs/user-guide/) [从 ESLint 开始,说透我如何在团队项目中基于 Vue 做代码校验](https://mp.weixin.qq.com/s/iwm2UtEEmsJgZx0D7yT1zA) [eslint 配置文件 -- .eslintrc ](https://segmentfault.com/a/1190000020656606?utm_source=tag-newest) [eslint 配置文件 -- .eslintrc](https://www.cnblogs.com/taoshengyijiuai/p/8431413.html)