【前端进阶】什么是AST?什么是ESLint?如何快速发布自定义ESLint插件?

news2024/11/24 1:37:53

文章目录

    • 什么是AST
      • AST在线可视化网站
      • 代码如何转化AST
      • acorn基本使用
    • 什么是ESLint
    • ESLint解析原理
    • 如何制作ESLint插件
      • 安装yeoman
      • 创建插件
      • 创建规则
      • 目录结构
      • 实现警告console.error()方法
    • npm发布
      • 如何注册
      • 如何登录
      • 发布
      • 应用
      • 问题
    • nrm
      • 下载
      • 查看可用镜像源
      • 切换镜像源
    • 结束
    • 参考文章

什么是AST

AST 叫虚拟语法树(Abstract Syntax Tree)它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。

大白话来讲:就是通过这种方式可以去解剖你身上的所有细节来描述你的身体。

注意:抽象语法树并不是单纯指在前端存在,其实所有的语言都可以抽象成语法树,它只是一种语法分析的结果

例如这段python代码:
在这里插入图片描述
AST解析:
在这里插入图片描述

AST在线可视化网站

https://astexplorer.net/

利用这个网站我们可以很清晰的看到各种语言的 AST 结构

代码如何转化AST

这里我们只针对JavaScript如何去转化成AST,可以使用两款插件acornrecast

  • acorn
    acron 代码比较精简,且 webpack 和 eslint 都依赖 acorn

acorn基本使用

import * as acorn from 'acorn';  //引入
const code = 'xxx';				//解析代码块
const ast = acorn.parse(code, options)			//解析

options的定义如下

如果你学过Ts应该就很清楚下面的参数在讲什么,简单来说除了ecmaVersion是必填参数,其他都是可选参数,ecmaVersion代表你的代码是属于es的哪一个版本,如果为6,那么es5的代码就不支持了解析了。

ecmaVersion ECMA 版本,默认时 es7

locations 默认为 false,设置为 true 时节点会携带一个 loc 对象来表示当前开始与结束的行数。

onComment 回调函数,每当代码执行到注释的时候都会触发,可以获取当前的注释内容

interface Options {
    ecmaVersion: 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 'latest'
    sourceType?: 'script' | 'module'
    onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
    onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
    allowReserved?: boolean | 'never'
    allowReturnOutsideFunction?: boolean
    allowImportExportEverywhere?: boolean
    allowAwaitOutsideFunction?: boolean
    allowSuperOutsideMethod?: boolean
    allowHashBang?: boolean
    locations?: boolean
    onToken?: ((token: Token) => any) | Token[]
    onComment?: ((
      isBlock: boolean, text: string, start: number, end: number, startLoc?: Position,
      endLoc?: Position
    ) => void) | Comment[]
    ranges?: boolean
    program?: Node
    sourceFile?: string
    directSourceFile?: string
    preserveParens?: boolean
  }

还原

import * as astring from 'astring'; //引入
 
const code = astring.generate(ast);		//ast
  • recast

recast也是类似的。

recast.parse(code) //解析
recast.print(ast).code  //还原

什么是ESLint

ESLint是一个用来识别 ECMAScript 并且按照规则给出报告的代码检测工具,使用它可以避免低级错误和统一代码的风格。如果每次在代码提交之前都进行一次eslint代码检查,就不会因为某个字段未定义为undefined或null这样的错误而导致服务崩溃,可以有效的控制项目代码的质量。

在许多方面,它和 JSLint、JSHint 相似,除了少数的例外:

  • ESLint 使用 Espree 解析 JavaScript
  • ESLint 使用 AST 去分析代码中的模式
  • ESLint 是完全插件化的。每一个规则都是一个插件并且你可以在运行时添加更多的规则。

因此,在介绍ESLint之前需要先明白AST的相关知识。

ESLint解析原理

在这里插入图片描述

  • 解析:将源代码解析成AST
  • 遍历:遍历每个选择器两次
  • 回调:根据规则触发回调
  • 生成:修改AST,生成代码

如何制作ESLint插件

官方是非常欢迎开发者参与到ESLint插件的制作,为此官方提供了一个脚手架便于开发者快速开发插件—— yeoman

如何参与ESLint插件贡献
如何制作插件

安装yeoman

npm install -g yo generator-eslint

创建插件

yo eslint:plugin

在这里插入图片描述

创建规则

在这里插入图片描述

目录结构

在这里插入图片描述

实现警告console.error()方法

1.修改lib/rules/no-console-error.js文件

/**
 * @fileoverview no console.error() in your code
 * @author yjian
 */
"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
  meta: {
    type: 'problem', // `problem`, `suggestion`, or `layout`
    docs: {  //文档描述
      description: "no console.error() in your code",
      recommended: false,
      url: null, // URL to the documentation page for this rule
    },
    fixable: null, // Or `code` or `whitespace`
    schema: [], // Add a schema if the rule has options
    // 报错信息描述
    messages: {
      avoidMethod: "'{{name}}' function of console is forbidden in code",
    },
  },

  create(context) {
    return {
      // 'MemberExpression'  这个就是AST的节点选择器,在遍历AST时,如果命中该选择器,就会触发回调
      // 关于选择器的名称,我们可以事先在 https://astexplorer.net/ 中找到目标解析器然后将其作为key即可
      //  这里的选择器会在AST"自上至下"过程中触发,如果希望是"自下至上"过程中触发,需要加':exit'即MemberExpression:exit
      'MemberExpression': (node) => {
        // 如果在AST遍历中满足以下条件,就用 context.report() 进行对外警告⚠️
        if (node.property.name === 'error' && node.object.name === 'console') {
            context.report({
                node,
                messageId: 'avoidMethod', //错误类型
                data: {
                    name: node.property.name,  //这里的name会传递到上面的messages中的name,类似于vue的双向绑定
                },
            });
        }
      },
    };
  },
};

2.导出规则lib/rules/index

/**
 * @fileoverview 自定义eslint规则
 * @author yjian
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Plugin Definition
//------------------------------------------------------------------------------


// import all rules in lib/rules
module.exports = {
  rules: {
  	  // 项目在使用时,对应的规则名称
      'no-console-error': require('./rules/no-console-error'),
  },
  configs: {
      recommended: {
          rules: {
              'demo/no-console-error': 2, // 可以省略 eslint-plugin 前缀
          },
      },
  },
}

3.单元测试./tests/lib/rules/no-console-error.js

/**
 * @fileoverview 不允许使用 console.time()
 * @author lzx
 */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/no-console-time"),
  RuleTester = require("eslint").RuleTester;


//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester();
ruleTester.run("no-console-error", rule, {
  valid: [
    // give me some code that won't trigger a warning
  ],

  invalid: [
    {
      code: "console.error('test');",
      errors: [{ message: "Fill me in.", type: "Me too" }],
    },
  ],
});

4.最后执行测试

npm run test

npm发布

如何注册

https://www.npmjs.com/

登录官网,输入用户名,邮箱和密码,完成邮箱校验之后即注册成功,过程需要梯子。

如何登录

输入命令:需要梯子,需要修改npm地址

npm login

输入成功之后,会提示你输入用户名,密码和邮箱,同样需要校验之后就登录成功了,
可以通过npm whoami命令去查看是否登录成功,如果成功,即会弹出用户名。

注意:输入密码的时候,命令行可能是空的,这是正常的,只需要确保密码正确能进入下一步即可

发布

npm publish

在这里插入图片描述
可以在下方链接查看到,
在这里插入图片描述

https://www.npmjs.com/settings/用户名/packages

应用

安装eslint

npm i eslint --save-dev

安装eslint插件

npm install eslint-plugin-noconsole --save-dev

初始化配置

npx eslint --init

配置

{
    "plugins": [
    	// 这是此前使用yo eslint:plugin 生成自定义插件的ID
        "diylint"
    ],
    extends: ["plugin:ecdemo/recommended"],
}

问题

如果你在使用npm login命令出现了以下错误,说明你的npm镜像地址不是原生地址,需要进行更换

Unexpected token < in JSON at position 0 while parsing near '<html>

解决方案:

npm set registry https://registry.npmjs.org/

推荐使用nrm进行镜像源地址的管理,请看下方说明!

nrm

nrm(npm registry manager )是npm的镜像源管理工具,可以通过nrm方便切换镜像源。

nvm是一个可以便捷切换node版本的工具,与nrm类似

下载

npm install -g nrm

查看可用镜像源

// 显示当前可使用的镜像源列表
nrm ls
* npm -------- https://registry.npmjs.org/
  yarn ------- https://registry.yarnpkg.com/
  cnpm ------- http://r.cnpmjs.org/
  taobao ----- https://registry.npm.taobao.org/
  nj --------- https://registry.nodejitsu.com/
  npmMirror -- https://skimdb.npmjs.com/registry/
  edunpm ----- http://registry.enpmjs.org/

切换镜像源

nrm use taobao

结束

想必,你应该大致清楚,babel是如何做到es6语法转es5,ESLint又是如何做到规则校验的。如果要进一步深入了解,还需要清楚,代码和AST之间是如何互相转化的。

参考文章

如何注册npm账号

ESLint简介

https://blog.csdn.net/qq_33396780/article/details/129935377

https://blog.csdn.net/KlausLily/article/details/124486883

https://blog.csdn.net/WTUDAN/article/details/127383560

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/719567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT会让软件测试人员失业吗?

首先&#xff0c;正视ChatGPT &#xff0c;它只是一款提升测试效率的工具&#xff0c;并不会让测试失业 ChatGPT 本质上就是一个搜索引擎的二次封装&#xff0c;它更能理解你的输入意图&#xff0c;它更精确的帮你拼接返回结果。但它就是一个辅助工具&#xff0c;用好了可以帮…

传统主从配置

传统主从配置 MySQL通过二进制文件写入和恢复数据 主服务器一定要打开二进制日志 必须两台服务器&#xff08;或者是多个实例&#xff09; 从服务器需要一次数据初始化 如果主从服务器都是新搭建的话&#xff0c;可以不做初始化 如果主服务器已经运行了很长时间了&#xff0c;可…

从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史

Bert最近很火,应该是最近最火爆的AI进展,网上的评价很高,那么Bert值得这么高的评价吗?我个人判断是值得。那为什么会有这么高的评价呢?是因为它有重大的理论或者模型创新吗?其实并没有,从模型创新角度看一般,创新不算大。但是架不住效果太好了,基本刷新了很多NLP的任务…

web服务端接收多用户并发上传同一文件,保证文件副本只存在一份(附go语言实现)

背景 对于一个文件服务器来说&#xff0c;对于同一文件&#xff0c;应该只保存一份在服务器上。基于这个原则&#xff0c;引发出本篇内容。 本篇仅阐述文件服务器在同一时间接收同一文件的并发问题&#xff0c;这种对于小体量的服务来说并不常见&#xff0c;但是最好还是要留…

存储协议——FC协议讲解

目录 FC基础概念 FC协议结构 FC通信 FC交换网络工作流程&#xff1a;&#xff08;以封装SCSI协议为例&#xff09; FC拓扑结构 FC协议的端口类型 FC适配器&#xff08;FC HBA卡&#xff09; FC基础概念 FC最开始为一种传输协议&#xff0c;由于其性能较高&#xff0c;逐…

我的小流量“转正”心得 --- 下载下方深度语义重排的实践

目录 一、背景 二、通过数据分析找到的问题 三、迭代流程 迭代一&#xff1a; 迭代二&#xff1a; 迭代三&#xff1a; 迭代成功的原因&#xff1a; 知识扩展 四、hnswlib调优过程 五、附录 5.1 hnsw 超参选择 一、背景 在分发中下载带来的收入占比排列仅次于搜索。…

重磅|2024年浙大MPA提前批面试政策公布:申请三步走

说曹操曹操到&#xff01;昨天还在说浙大MPA提面吃迟迟未公布的事情&#xff0c;晚些时候就来了&#xff01;等待许久的MPA考生们可以开始着手筹划自己的提面备考了&#xff01;提前批面试真题周期较长&#xff0c;但是需要做准备的内容确实也不少&#xff0c;本期专注浙大的杭…

如何区分bin log 、redo log 跟 undo log?

概要 MySQL 日志包含了错误日志、查询日志、慢查询日志、事务日志、二进制日志等&#xff0c;如果存储引擎使用的是 InnoDB &#xff0c;二进制日志(binlog)和事务日志(包括redo log和undo log) 是肯定绕不过去的&#xff0c;本篇接下来详细为大家介绍这三种日志。 redo log 为…

Android OpenGL ES实现简单绿幕抠图

目录 正文 OES FilterBlendShader Filter最后的效果缺陷 正文 实现绿幕抠图&#xff0c;其实想法很简单。 这里简单粗暴的使用着色器替换。 OES Filter 直接实现在相机预览上的Shader ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #extension GL_OE…

Spring Boot 中的 Sleuth 是什么, 如何使用

Spring Boot 是一个非常流行的 Java Web 开发框架&#xff0c;它提供了许多方便的功能&#xff0c;其中之一就是 Sleuth。Sleuth 是一个分布式跟踪系统&#xff0c;用于跟踪应用程序中的请求和操作。在本文中&#xff0c;我们将探讨 Spring Boot 中的 Sleuth 是什么&#xff0c…

git 新建分支,切换分支,上传到远程分支

git 在使用的过程中&#xff0c;有的时候我们需要更换一个分支才存贮数据&#xff0c;作为版本的一个迭代或者是阶段性成果的一个里程碑。 如何来做操作呢&#xff1f; 在git中&#xff0c;可利用checkout命令转换分支&#xff0c;该命令的作用就是切换分支或恢复工作树文件&a…

Linux串口应用编程——STM32MP157

文章目录 替换设备树文件串口API设置行规程struct termios 结构体行规程函数 串口应用——回环 替换设备树文件 挂载boot分区&#xff1a; mount /dev/mmcblk2 /boot拷贝新的设备树文件到boot分区 cp /mnt/stm32mp157c-100ask-512d-lcd-v1.dtb /bootreboot重启&#xff0c;查…

C++ set和map使用

搜索平衡二叉树的封装 1. 关联容器2. 键值对3. 树形结构的关联式容器3.1 set3.1.1 set介绍3.1.2 set 的使用1. set模板参数列表2. set的构造3. set 的迭代器4. set的容量5. set修改5. set的使用 3.2 multiset3.2.1 multiset的介绍3.2.1 multiset的使用 3.3 map3.3.1 map的介绍3…

Could not load the Qt platform plugin “xcb“

qt.core.plugin.loader: QLibraryPrivate::loadPlugin failed on “/home/ly/Qt/6.5.1/gcc_64/plugins/platforms/libqxcb.so” : “Cannot load library /home/ly/Qt/6.5.1/gcc_64/plugins/platforms/libqxcb.so: (libxcb-cursor.so.0: cannot open shared object file: No su…

VTK8.2手动卸载

利用源代码方式安装的VTK, 进行手动卸载[参考] 1、进入.. /VTK-8.2.0/build目录 make2、记录sudo make install的log log在uninstall.sh文件中 touch uninstall.sh && chmod 775 uninstall.sh && echo #!/bin/bash -v > uninstall.sh && sudo m…

【unity实战】制作俯视角射击游戏多种射击效果(一)

文章目录 本期目标前言欣赏开始1. 角色移动和场景搭建2. 绑定枪械2.1 首先将各种枪械的素材添加给人物作为子物体2.2 给枪械也分别添加两个子物体用作标记枪口和弹仓位置 3. 枪械动画4. 切换枪械5. 发射功能5.1 手枪(1) 枪械随着鼠标旋转(2) 射击时间间隔(3) 创建好子弹、弹壳和…

手把手教你如何做手机PCB电磁兼容性设计

电磁兼容性是指电子设备在各种电磁环境中仍能够协调、有效地进行工作的能力。电磁兼容性设计的目的是使电子设备既能抑制各种外来的干扰&#xff0c;使电子设备在特定的电磁环境中能够正常工作&#xff0c;同时又能减少电子设备本身对其它电子设备的电磁干扰。 1、选择合理的导…

【霹雳吧啦Wz】Transformer中Self-Attention以及Multi-Head Attention详解

文章目录 来源Transformer起源Self-Attention1. 求q、k、v2. 计算 a ^ ( s o f t m a x 那块 ) \hat{a} (softmax那块) a^(softmax那块)3. 乘V&#xff0c;计算结果 Multi-Head Attention位置编码 来源 b站视频 前天啥也不懂的时候点开来一看&#xff0c;各种模型和公式&#…

FreeRTOS 低功耗模式设计 STM32平台

1. STM32F105RBT6 的三种低功耗模式 1.1 sleep睡眠模式、stop停机模式、standby 待机模式 1.2 STM32中文参考手册有介绍STM32 低功耗模式的介绍 2. FreeRTOS 采用的是时间片轮转的抢占式任务调度机制&#xff0c;其低功耗设计思路一般是&#xff1a; ① 当运行空闲任务&#…

启动网站调试提示 HTTP 错误 403.14 – Forbidden Web 服务器被配置为不列出此目录的内容。

启动网站调试提示 HTTP 错误 403.14 – Forbidden Web 服务器被配置为不列出此目录的内容。 解决方案第一种.在网站的配置文件里添加第二种.ISS管理界面修改 解决方案 第一种.在网站的配置文件里添加 <system.webServer><directoryBrowse enabled"true" /&…