Article directory
What is AST
AST is called Virtual Syntax Tree (Abstract Syntax Tree), which expresses the grammatical structure of a programming language in the form of a tree. Each node on the tree represents a structure in the source code. The reason why grammar is "abstract" is that the grammar here does not represent every detail that appears in real grammar.
To put it bluntly: This is how you can dissect all the details on your body to describe your body.
Note: Abstract syntax tree does not simply mean that it exists on the front end. In fact, all languages can be abstracted into syntax trees. It is just the result of syntax analysis.
For example, this python code:
AST parsing:
AST online visualization website
https://astexplorer.net/
Using this website, we can clearly see the AST structure of various languages.
How code converts AST
Here we only focus on how to convert JavaScript into AST. You can use two plug- ins acorn
andrecast
- acorn
acron code is relatively streamlined, and both webpack and eslint rely on acorn
Basic use of acorn
import * as acorn from 'acorn'; //引入
const code = 'xxx'; //解析代码块
const ast = acorn.parse(code, options) //解析
options are defined as follows
If you have studied Ts, you should know very well what the following parameters are talking about. Simply put, except ecmaVersion, which is a required parameter, the other parameters are optional. ecmaVersion represents which version of es your code belongs to. If it is 6, Then the es5 code does not support parsing.
ecmaVersion ECMA version, default is es7
locations defaults to false. When set to true, the node will carry a loc object to represent the current start and end row numbers.
onComment callback function, which will be triggered whenever the code executes to a comment, and can get the current comment content
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
}
reduction
import * as astring from 'astring'; //引入
const code = astring.generate(ast); //ast
- recast
Recast is similar.
recast.parse(code) //解析
recast.print(ast).code //还原
What is ESLint
ESLint is a code detection tool used to identify ECMAScript and give reports according to rules . Use it to avoid low-level errors and unify the code style. If an eslint code check is performed every time before the code is submitted, the service will not crash due to errors such as a field being undefined or null, and the quality of the project code can be effectively controlled.
In many respects, it is similar to JSLint and JSHint, with a few exceptions:
- ESLint uses Espree to parse JavaScript
- ESLint uses AST to analyze patterns in code
- ESLint is fully pluggable. Each rule is a plugin and you can add more rules at runtime.
Therefore, you need to understand the relevant knowledge of AST before introducing ESLint.
ESLint parsing principle
- Parsing: Parse source code into AST
- Traverse: Traverse each selector twice
- Callback: Trigger callback based on rules
- Generation: modify AST and generate code
How to make an ESLint plugin
The official welcomes developers to participate in the production of ESLint plug-ins. For this reason, the official provides a scaffolding to facilitate developers to quickly develop plug-ins - yeoman
How to contribute to ESLint plug-insHow
to make plug-ins
Install yeoman
npm install -g yo generator-eslint
Create plugin
yo eslint:plugin
Create rules
Directory Structure
Implement warning console.error() method
1. Modify the lib/rules/no-console-error.js file
/**
* @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. Export rules 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. Unit test./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.Finally execute the test
npm run test
npm publish
How to register
https://www.npmjs.com/
Log in to the official website, enter your username, email and password. After completing the email verification, the registration is successful. The process requires a ladder.
How to log in
Enter the command: a ladder is needed, and the npm address needs to be modified
npm login
After the input is successful, you will be prompted to enter your username, password and email address. You also need to verify that the login is successful. You
can use npm whoami
the command to check whether the login is successful. If successful, the username will pop up.
Note: When entering the password, the command line may be empty, which is normal, just make sure the password is correct to enter the next step
release
npm publish
You can view it at the link below,
https://www.npmjs.com/settings/username/packages
application
Install eslint
npm i eslint --save-dev
Install eslint plugin
npm install eslint-plugin-noconsole --save-dev
Initial configuration
npx eslint --init
Configuration
{
"plugins": [
// 这是此前使用yo eslint:plugin 生成自定义插件的ID
"diylint"
],
extends: ["plugin:ecdemo/recommended"],
}
question
If the following error occurs when you use the npm login command, it means that your npm mirror address is not the original address and needs to be replaced
Unexpected token < in JSON at position 0 while parsing near '<html>
solution:
npm set registry https://registry.npmjs.org/
It is recommended to use nrm
it to manage the mirror source address, please see the instructions below!
nrm
nrm (npm registry manager) is the mirror source management tool of npm, which can conveniently switch the mirror source through nrm.
Nvm is a tool that can easily switch node versions, similar to nrm
download
npm install -g nrm
View available image sources
// 显示当前可使用的镜像源列表
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/
Switch mirror source
nrm use taobao
Finish
Presumably, you should have a rough idea of how Babel converts es6 syntax to es5, and how ESLint does rule verification. If you want to understand further, you also need to understand how the code and AST are transformed into each other.
Reference article
How to register an npm account
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