理解代码检测的方法非常重要,它直接体现了你对代码检测本身概念的掌握。 废话不多说,下面进入代码检测工具的分析。
3. 代码检测工具
代码检测的实现一般不仅仅是字符串分析处理,其中会涉及到大量的句子分析。 由于涉及到句型,因此针对不同的代码需要使用不同的代码检测工具。 一般来说,我们会使用Eslint工具来检测JavaScript和Typescript代码,使用stylelint工具来检测样式代码。 对于stylelint,本文不做太多说明。 我们把舞台交给Eslint,讲解一下如何使用Eslint来实现JavaScript代码和Typescript代码的检测。
好了,在按顺序讲解编码后检测、编码时检测、构建前检测、git 提交前检测这四种代码检测方法之前,我们首先将 Eslint 连接到项目中,并配置各种代码检测所需的检测方法规则。
2:将项目连接到Eslint实现代码检测
很多同学可能对Eslint不太了解,所以我们先简单介绍一下。
Eslint是一个插件(检测规则)JavaScript代码检测工具。 概念简洁、简洁。 需要说明的是,eslint在概念上是一个插件式的检测工具,这意味着eslint的设计是在检测工具和检测规则之间进行前馈。 也就是说,在安装了eslint的开发依赖之后,我们可以而且需要选择安装我们喜欢的检测规则。
好了,理论就讲到这里,接下来我们就要从实践中得到真正的知识了。 练习步骤如下:
step1:安装检测工具eslint
yarn add eslint --dev 复制代码
步骤2:安装并配置检测规则
在解释配置和安装检测规则之前,我们需要明确我们的检测目标是什么。 我认为检测目标自然是建立之前的代码,但是是我自己/我们自己的团队编译的代码(不是第三方模块)。 虽然检测的最终目的是为了修复服务,但我们只负责修复我们自己/我们自己团队编译的代码。 即使构建后的代码和第三方代码未通过检测,我们也不会也不应该被我们修复。
项目中检测规则的表达方式一般有两种,即:
生成 eslint 配置文件:
对于配置文件,我们以后一般使用eslint --init命令来创建这个配置文件。 下表列出了调用该命令后经常出现的一些配置问题(不一定是以下问题的顺序)。
注意:我认为回答这些问题是谨慎的,因为问题的答案会影响配置,配置会影响检测规则webpack代码检查,检测规则会影响检测结果。 其实回答这些问题的目的就是为了生成想要的配置文件。 如果问题答案错误或者后续规则有变化,可以直接更改eslint配置文件。
序列号功能问题
选择使用eslint的目的,常选3
您想如何使用 ESLint?(使用箭头键)
仅检查语法
检查语法并发现问题
检查语法、查找问题并强制执行代码风格
选择项目使用的模块化规格
您的项目使用什么类型的模块? (使用箭头键)
仅 JavaScript 模块(导入/导出)
CommonJS(需要/导出)
都不是
选择用于您的项目的框架
您的项目使用哪个框架?(使用箭头键)
反应
Vue.js
都不是
是否使用Typescript
你的项目使用 TypeScript 吗?(是/否)
选择代码的运行环境(可多选)
你的代码在哪里运行? (按选择、切换全部、反转选择)
()浏览器
()节点
选择如何为您的项目定义风格,通常选择1
您希望如何为您的项目定义风格? (使用箭头键)
使用流行的风格指南
回答有关你的风格的问题
检查您的 JavaScript 文件
选择使用特定的流行编码风格
您想遵循哪种风格指南?(使用箭头键)
爱彼迎()
标准()
谷歌()
选择配置文件格式,通常选择1(比较灵活)
您希望配置文件采用什么格式? (使用箭头键)
JavaScript
YAML
JSON
如何在代码中编写神奇的注释:
不仅规则是在配置文件中配置的,eslint还有一种方法可以通过代码中的魔术注释来修补规则,如下例所示:
// 屏蔽整行的代码检查 const str1 = "${name} is a coder" // eslint-disable-line // 屏蔽某一个规则:如此行的no-template-curly-in-string规则 const str1 = "${name} is a coder" // eslint-disable-line no-template-curly-in-string 复制代码
温馨提示:规则名称可以从检测结果提示或输出信息中获取
三:基于Eslint及其规则实现
对于工作流程的解释,我还是更喜欢直接演示一个简单的demo。 在这个写作思路下,我们下面将分别演示一个Eslint检测JS代码的例子和一个Eslint检测TS代码的例子。 根据代码检测的逻辑,我在演示和讲解demo时会遵循以下思路,即:
好了,下面我们就进入Eslint对JS代码编码后检测示例的讲解。
1.eslint编码检测JS代码示例1):目标问题代码
const noUsedVar = 1; function fn() { console.log('hello') cnsole.log('eslint'); } fn( fn2(); 复制代码
上面短短几行代码就可以代表eslit代码检测的三个部分,分别是:
2):代码检测规则配置
通过eslint--initwebpack代码检查,根据项目的特点回答问题后得到的eslint配置文件如下:
module.exports = { env: { browser: true, es6: true, }, extends: [ 'airbnb-base', ], globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly', }, parserOptions: { ecmaVersion: 2018, }, rules: { }, }; 复制代码
3):代码检测操作及结果
第一轮测试的结果首先报了一个句型错误。 句型错误修复后,第二轮测试报告了很多编码和风格上的错误。 将两次检测结果与问题代码关联起来,可以得到如下分析:
const noUsedVar = 1; // find program:'noUsedVar' is assigned a value but never used function fn() { console.log('hello') // enforce code style:Missing semicolon(分号) cnsole.log('eslint'); // find program:'cnsole' is not defined } fn( // syntax error fn2(); // find program:'fn2' is not defined 复制代码
4):修补代码
根据上述测试结果进行修复。 对于代码风格不一致导致的错误,大部分问题都可以通过参数--fix手动修复。 大多数句型和编码中的错误只能由开发人员自己自动修复。 经过自动补丁和手动补丁后,问题代码可能会变成如下:
import { fn2 } from './test2'; function fn() { console.log('hello'); console.log('eslint'); } fn(); fn2(); 复制代码
2、Eslint编码后的TS代码检测示例1):目标问题代码
function foo(ms: string): void{ console.log(msg); } foo("hello typescript~") 复制代码
2):代码检测规则配置
项目中安装好typescript依赖后(没有先安装typescript依赖就执行eslint--init会报错),根据项目特性(typesrciptyes)使用eslint--init命令回答问题,然后获取eslint配置文件如下:
module.exports = { "env": { "browser": true, "es6": true }, "extends": [ "airbnb-base" ], "globals": { "Atomics": "readonly", "SharedArrayBuffer": "readonly" }, "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 2018 }, "plugins": [ "@typescript-eslint" ], "rules": { } }; 复制代码
与 JavaScript 代码检测相比,Typescript 检测需要额外的句子解析器(即上述配置中解析器配置项的内容)。
3):代码检测操作及结果
eslint用--fix参数检测后,主要报两个编码错误,映射到文件上,分析如下:
function foo(ms: string): void { // 'ms' is defined but never used console.log(msg); // 'msg' is not defined } foo('hello typescript~'); 复制代码
4):修补代码
本例中,fix手动修复代码风格后,可以自动将foo函数的实参改为msg。
function foo(msg: string): void { console.log(msg); } foo('hello typescript~'); 复制代码
四:基于Eslint及其规则的实现
说到编码时的检测,就不得不提到代码提示,还要联系我们选择使用的具体IDE。 另外,为了保证各种形式的代码检测规则的统一配置,我们需要做的关键一点是IDE可以读取我们在项目中配置的eslint规则文件来实时检测代码。
因为我主要使用VScode进行开发,所以下面的demo和讲解都默认在vscode环境下。 官方相关信息:文档中。
说实话,我现在也在学习和销售这个东西。 虽然后端需要学习的东西太多了,但本文的初衷并不是要涵盖某个技术点的所有内容,而是帮助大家建立一个系统的理解和指导。
因为我们需要在IDE中进行实时代码检测时能够读取到读取项目下的eslint规则。 所以下面两个步骤是必不可少的:
根据上面的实现步骤,我们将在vscode环境下做一个基于Eslint及其规则的编码检测的demo。
1.安装eslint并配置eslint规则
yarn add eslint --dev # 安装 eslint --init # 初始化配置 复制代码
eslint的规则配置方法已经在里面讲过了,这里不再赘述。
2、IDE实时代码检测功能相关的安装和配置
eslint工具和检测规则准备好后(规则是IDE代码检测的规则),剩下的具体检测行为触发和代码提示将由IDE来实现。 对于vscode来说,我们这里的实现思路是安装eslint扩展插件(个人使用2.1.14版本,下面的配置1.x可能不适用),然后注意开启eslint的代码检测功能vscode(vscode下的eslint开关右下角的eslint文字标记)可以在vscode环境下实现eslint实时代码检测。
配置IDE的实时检测功能
如果需要配置IDE的实时检测功能,可以通过打开vscode的setting->找到eslint->打开setting.json来找到相关的配置文件。 下面是配置vscode代码检测功能的示例:
//配置eslint "editor.codeActionsOnSave": { // 保存时自动fix "source.fixAll.eslint": true }, "eslint.quiet": true, // warning时不报红色下划线,可用于处理no-console规则爆的warning 复制代码
实时代码检测和错误后修复
在IDE手动检测的过程中,如果错误提示是代码违反规则,可以更改项目下的检测规则文件(.eslintrc.js)。 比如我在demo实践中遇到了ESLintExpectedlinebreakstobe'LF'butfound'CRLF'规则错误,但它的情况还是有点特殊。 IDE实时检测到的时候会报告,自动调用eslint命令的时候不会报告。 具体原因这里我就不做过多分析了。 我个人是通过直接在规则文件(.eslintrc.js)中添加以下规则来解决的:
rules: { 'linebreak-style': [0, 'error', 'windows'], }, 复制代码
五:基于Eslint及其规则实现
我们直接来分析一下比较常用的gulp和webpack构建工具是如何实现构建前检测的。
1.建立前gulp检测
通过gulp实现这个代码检测方面的思路如下:
1):初始化eslint配置文件
yarn add eslint --dev eslint --init 复制代码
2):下载并安装gulp-eslint插件
yarn add gulp-eslint --dev 复制代码
3):针对js文件处理的编译代码检测方面
示例如下:
// ... 其它代码 const eslint = require('gulp-eslint'); const script = (0 => { return src(['scripts/*.js']) .pipe(eslint()) // 代码检查 .pipe(eslint.format()) // 将lint结果输出到控制台。 .pipe(eslint.failAfterError()) // lint错误,进程退出,结束构建。 .pipe(babel({ presets: ['@babel/preset-env']})) .pipe(dest('temp')) .pipe(bs.reload( { stream: true } )) } // ... 其它代码 复制代码
2、建立前的Webpack检测
通过webpack实现这个代码检测方面的思路如下:
(1):安装eslint并初始化eslint配置文件
yarn add eslint --dev eslint --init 复制代码
(2): 安装eslint-loader
yarn add eslint-loader --dev 复制代码
(3): 编译webpack配置文件,并将这个eslint-loader添加到js文件中
rules: [ { test: /.js$/, exclude: /node_modules/, use: [ 'babel-loader', 'eslint-loader' // 更后的先执行 ] } ] 复制代码
六:基于Eslint及其规则的实现
这部分讲解完毕后,我将从以下四个方面逐步讲解Eslint是如何实现git预提交检测的:
我们进入第一点,git预提交检测的原理:GitHooks的分析。
1.提交前git检测原理:GitHooks
Eslint通过GitHooks实现了git的提交前检测。 GitHook 也称为 git hook。 每个钩子对应一个任务。 通过shell脚本,可以编译触发钩子任务时要执行的具体操作。
本文重点是在git提交之前实现代码检测,因此我们重点关注gitcommit钩子。 使用步骤如下:
#!/bin/sh echo "before commit" 复制代码
执行gitcommit命令后可以发现,无论commit操作是否成功,都可以看到输出的beforecommit信息。
上述方法是可行的,但仍然不适合实际生产。 虽然对于后端开发者来说,使用shell脚本编译Githook的方式还是难以接受。 下面我们就来介绍一下husky库的使用,帮助我们实现js以代码的形式编译hook任务的目的。
2.使用husky实现:编译node代码而不是shell代码
实施步骤如下:
1):安装哈士奇
yarn add husky --dev 复制代码
安装此模块后,您可以在.git/hooks文件夹中看到以下新添加的文件。
2):配置husky的hook任务:如下package.json任务
"scripts": { "test1": "echo before commit", "test2": "node test2.js" }, "husky": { "hooks": { "pre-commit": "yarn test2" } }, 复制代码
3):触发钩子:gitadd->gitcommit
gitcommit命令执行后,可以触发通过husky实现的js代码编译的hook任务。
接下来我们来改进一下。 通过lint-staged库,该钩子不仅支持单个任务,还支持任务流的触发。
3.实现hook任务流程:使用lint-staged配合husky
实施步骤如下:
1): 安装 husky 和 lint-staged 模块
yarn add husky --dev yarn add lint-staged --dev 复制代码
2):配置husky的hook任务流程:如下package.json任务
"scripts": { "precommit": "lint-staged" }, "husky": { "hooks": { "pre-commit": "yarn precommit" } }, "lint-staged": { "*.js":[ "echo task1", "echo task2", "echo task3" ] }