自定义解析器
ESLint 自定义解析器让你可以扩展 ESLint 以支持在你的代码中检查新的非标准 JavaScript 语言功能或自定义语法。解析器负责获取你的代码并将其转换为抽象语法树 (AST),然后 ESLint 可以对其进行分析和 lint。
¥ESLint custom parsers let you extend ESLint to support linting new non-standard JavaScript language features or custom syntax in your code. A parser is responsible for taking your code and transforming it into an abstract syntax tree (AST) that ESLint can then analyze and lint.
创建自定义解析器
¥Creating a Custom Parser
自定义解析器中的方法
¥Methods in Custom Parsers
自定义解析器是具有 parse()
或 parseForESLint()
方法的 JavaScript 对象。parse
方法只返回 AST,而 parseForESLint()
还返回额外的值,让解析器更多地自定义 ESLint 的行为。
¥A custom parser is a JavaScript object with either a parse()
or parseForESLint()
method. The parse
method only returns the AST, whereas parseForESLint()
also returns additional values that let the parser customize the behavior of ESLint even more.
这两种方法都应该是实例(自己的)属性,并将源代码作为第一个参数,将可选配置对象作为第二个参数,在配置文件中作为 parserOptions
提供。
¥Both methods should be instance (own) properties and take in the source code as the first argument, and an optional configuration object as the second argument, which is provided as parserOptions
in a configuration file.
// customParser.js
const espree = require("espree");
// Logs the duration it takes to parse each file.
function parse(code, options) {
const label = `Parsing file "${options.filePath}"`;
console.time(label);
const ast = espree.parse(code, options);
console.timeEnd(label);
return ast; // Only the AST is returned.
};
module.exports = { parse };
parse
返回对象
¥parse
Return Object
parse
方法应该简单地返回 AST 对象。
¥The parse
method should simply return the AST object.
parseForESLint
返回对象
¥parseForESLint
Return Object
parseForESLint
方法应返回一个对象,该对象包含必需属性 ast
和可选属性 services
、scopeManager
和 visitorKeys
。
¥The parseForESLint
method should return an object that contains the required property ast
and optional properties services
, scopeManager
, and visitorKeys
.
-
ast
应包含 AST 对象。¥
ast
should contain the AST object. -
services
可以包含任何依赖于解析器的服务(例如节点的类型检查器)。services
属性的值可作为context.sourceCode.parserServices
用于规则。默认为空对象。¥
services
can contain any parser-dependent services (such as type checkers for nodes). The value of theservices
property is available to rules ascontext.sourceCode.parserServices
. Default is an empty object. -
scopeManager
可以是 ScopeManager 对象。自定义解析器可以对实验/增强语法使用自定义范围分析。默认是由 eslint-scope 创建的ScopeManager
对象。¥
scopeManager
can be a ScopeManager object. Custom parsers can use customized scope analysis for experimental/enhancement syntaxes. The default is theScopeManager
object which is created by eslint-scope.-
在 ESLint v4.14.0 中添加了对
scopeManager
的支持。支持scopeManager
的 ESLint 版本会在parserOptions
中提供一个eslintScopeManager: true
属性,可用于特性检测。¥Support for
scopeManager
was added in ESLint v4.14.0. ESLint versions that supportscopeManager
will provide aneslintScopeManager: true
property inparserOptions
, which can be used for feature detection.
-
-
visitorKeys
可以是自定义 AST 遍历的对象。对象的键是 AST 节点的类型。每个值都是应该遍历的属性名称数组。默认值为eslint-visitor-keys
的键。¥
visitorKeys
can be an object to customize AST traversal. The keys of the object are the type of AST nodes. Each value is an array of the property names which should be traversed. The default is KEYS ofeslint-visitor-keys
.-
在 ESLint v4.14.0 中添加了对
visitorKeys
的支持。支持visitorKeys
的 ESLint 版本会在parserOptions
中提供一个eslintVisitorKeys: true
属性,可用于特性检测。¥Support for
visitorKeys
was added in ESLint v4.14.0. ESLint versions that supportvisitorKeys
will provide aneslintVisitorKeys: true
property inparserOptions
, which can be used for feature detection.
-
自定义解析器中的元数据
¥Meta Data in Custom Parsers
为了更轻松地调试和更有效地缓存自定义解析器,建议在自定义解析器根目录的 meta
对象中提供名称和版本,如下所示:
¥For easier debugging and more effective caching of custom parsers, it’s recommended to provide a name and version in a meta
object at the root of your custom parsers, like this:
// preferred location of name and version
module.exports = {
meta: {
name: "eslint-parser-custom",
version: "1.2.3"
}
};
meta.name
属性应与自定义解析器的 npm 包名称匹配,meta.version
属性应与自定义解析器的 npm 包版本匹配。完成此操作的最简单方法是从你的 package.json
读取此信息。
¥The meta.name
property should match the npm package name for your custom parser and the meta.version
property should match the npm package version for your custom parser. The easiest way to accomplish this is by reading this information from your package.json
.
AST 规范
¥AST Specification
自定义解析器应创建的 AST 基于 ESTree。AST 需要一些关于源代码详细信息的附加属性。
¥The AST that custom parsers should create is based on ESTree. The AST requires some additional properties about detail information of the source code.
所有节点
¥All Nodes
所有节点都必须具有 range
属性。
¥All nodes must have range
property.
-
range
(number[]
) 是两个数字的数组。这两个数字都是基于 0 的索引,它是源代码字符数组中的位置。第一个是节点的起始位置,第二个是节点的结束位置。code.slice(node.range[0], node.range[1])
必须是节点的文本。此范围不包括节点周围的空格/括号。¥
range
(number[]
) is an array of two numbers. Both numbers are a 0-based index which is the position in the array of source code characters. The first is the start position of the node, the second is the end position of the node.code.slice(node.range[0], node.range[1])
must be the text of the node. This range does not include spaces/parentheses which are around the node. -
loc
(SourceLocation
) 不能是null
。loc
属性被 ESTree 定义为可为空,但 ESLint 需要此属性。SourceLocation#source
属性可以是undefined
。ESLint 不使用SourceLocation#source
属性。¥
loc
(SourceLocation
) must not benull
. Theloc
property is defined as nullable by ESTree, but ESLint requires this property. TheSourceLocation#source
property can beundefined
. ESLint does not use theSourceLocation#source
property.
所有节点的 parent
属性必须是可重写的。在任何规则访问 AST 之前,ESLint 在遍历时将每个节点的 parent
属性设置为其父节点。
¥The parent
property of all nodes must be rewritable. Before any rules have access to the AST, ESLint sets each node’s parent
property to its parent node while traversing.
Program
节点
¥The Program
Node
Program
节点必须具有 tokens
和 comments
属性。这两个属性都是以下 Token
接口的数组。
¥The Program
node must have tokens
and comments
properties. Both properties are an array of the below Token
interface.
interface Token {
type: string;
loc: SourceLocation;
// See the "All Nodes" section for details of the `range` property.
range: [number, number];
value: string;
}
-
tokens
(Token[]
) 是影响程序行为的标记数组。标记之间可以存在任意空格,因此规则检查Token#range
以检测标记之间的空格。这必须按Token#range[0]
排序。¥
tokens
(Token[]
) is the array of tokens which affect the behavior of programs. Arbitrary spaces can exist between tokens, so rules check theToken#range
to detect spaces between tokens. This must be sorted byToken#range[0]
. -
comments
(Token[]
) 是注释标记数组。这必须按Token#range[0]
排序。¥
comments
(Token[]
) is the array of comment tokens. This must be sorted byToken#range[0]
.
所有标记和注释的范围索引不得与其他标记和注释的范围重叠。
¥The range indexes of all tokens and comments must not overlap with the range of other tokens and comments.
Literal
节点
¥The Literal
Node
Literal
节点必须具有 raw
属性。
¥The Literal
node must have raw
property.
-
raw
(string
) 是这个字面的源代码。这与code.slice(node.range[0], node.range[1])
相同。¥
raw
(string
) is the source code of this literal. This is the same ascode.slice(node.range[0], node.range[1])
.
打包自定义解析器
¥Packaging a Custom Parser
要将自定义解析器发布到 npm,请执行以下操作:
¥To publish your custom parser to npm, perform the following:
-
按照上面的 创建自定义解析器 部分创建自定义解析器。
¥Create a custom parser following the Creating a Custom Parser section above.
-
创建一个 npm 包 用于自定义解析器。
¥Create an npm package for the custom parser.
-
在你的
package.json
文件中,将main
字段设置为导出自定义解析器的文件。¥In your
package.json
file, set themain
field as the file that exports your custom parser.
有关发布 npm 包的更多信息,请参阅 npm 文档。
¥For more information on publishing an npm package, refer to the npm documentation.
发布 npm 包后,你可以通过将包添加到你的项目来使用它。例如:
¥Once you’ve published the npm package, you can use it by adding the package to your project. For example:
npm install eslint-parser-myparser --save-dev
然后使用 parser
属性将自定义解析器添加到你的 ESLint 配置文件中。例如:
¥Then add the custom parser to your ESLint configuration file with the parser
property. For example:
// .eslintrc.js
module.exports = {
parser: 'eslint-parser-myparser',
// ... rest of configuration
};
要了解有关在项目中使用 ESLint 解析器的更多信息,请参阅 配置解析器。
¥To learn more about using ESLint parsers in your project, refer to Configure a Parser.
示例
¥Example
有关自定义解析器的复杂示例,请参阅 @typescript-eslint/parser
源代码。
¥For a complex example of a custom parser, refer to the @typescript-eslint/parser
source code.
一个简单的自定义解析器,为规则提供 context.sourceCode.parserServices.foo()
方法。
¥A simple custom parser that provides a context.sourceCode.parserServices.foo()
method to rules.
// awesome-custom-parser.js
var espree = require("espree");
function parseForESLint(code, options) {
return {
ast: espree.parse(code, options),
services: {
foo: function() {
console.log("foo");
}
},
scopeManager: null,
visitorKeys: null
};
};
module.exports = { parseForESLint };
在 ESLint 配置文件中包含自定义解析器:
¥Include the custom parser in an ESLint configuration file:
// .eslintrc.json
{
"parser": "./path/to/awesome-custom-parser.js"
}