Espree 是 ESLint 使用的 JavaScript 解析器,基于 Acorn 实现,结合 Acorn-JSX 插件也可解析 React.js JSX。
    Espree 将 JavaScript 解析成 AST ,再将 AST Node 传递给 ESLint rule 获得 report 给开发工具,在代码中错误和不符合规范的地方给予开发者提示。当我们在开发 ESLint 规则时,node 将作为参数获取,用于分析代码风格。
    以下是解析一段 js 代码的示例:

    1. // demo.js
    2. const a = "123";
    3. console.log("xxx", a);
    4. const jsx = <div className="test">{a}</div>
    5. const issueName = { a: 123, b: 123, c: 123 };
    6. for (let i = 0; i < 99; i++) {
    7. console.log('xxx', i)
    8. }
    9. if (1 > 0) {
    10. console.log('xxx', true)
    11. }
    1. // 使用 espree 解析 demo.js 文件
    2. import { readFile, writeFile } from "fs/promises";
    3. import * as espree from "espree";
    4. // 解析成 AST 并保存
    5. async function parseSave(code) {
    6. const node = espree.parse(code, {
    7. ecmaVersion: 11,
    8. ecmaFeatures: { jsx: true },
    9. })
    10. await writeFile("./file/nodeResult.json", JSON.stringify(node, null, 4))
    11. }
    12. // 解析成 token 并保存
    13. async function tokenSave(code) {
    14. const token = espree.tokenize(code, {
    15. ecmaVersion: 11,
    16. ecmaFeatures: { jsx: true },
    17. })
    18. await writeFile("./file/tokenResult.json", JSON.stringify(token, null, 4))
    19. }
    20. async function parseFile(filePath) {
    21. const file = readFile(filePath, { encoding: "utf-8" })
    22. const code = await file
    23. parseSave(code)
    24. tokenSave(code)
    25. }
    26. parseFile('./file/demo.js')
    1. // tokenResult.json 解析为 token 结果(部分)
    2. [
    3. {
    4. "type": "Keyword",
    5. "value": "const",
    6. "start": 0,
    7. "end": 5
    8. },
    9. // ...
    10. ]
    1. // nodeResult.json 解析为 node 结果(部分)
    2. {
    3. "type": "Program",
    4. "start": 0,
    5. "end": 233,
    6. "body": [
    7. {
    8. "type": "VariableDeclaration",
    9. "start": 0,
    10. "end": 16,
    11. "declarations": [
    12. {
    13. "type": "VariableDeclarator",
    14. "start": 6,
    15. "end": 15,
    16. "id": {
    17. "type": "Identifier",
    18. "start": 6,
    19. "end": 7,
    20. "name": "a"
    21. },
    22. "init": {
    23. "type": "Literal",
    24. "start": 10,
    25. "end": 15,
    26. "value": "123",
    27. "raw": "\"123\""
    28. }
    29. }
    30. ],
    31. "kind": "const"
    32. },
    33. // ...
    34. ],
    35. "sourceType": "script"
    36. }
    1. // VisitorKeys.json AST 中的 node 类型,
    2. // 通过 espree.VisitorKeys 获取,
    3. // 用于遍历 AST(all visitor keys for traversing the AST)
    4. {
    5. "AssignmentExpression": ["left", "right"],
    6. "AssignmentPattern": ["left", "right"],
    7. "ArrayExpression": ["elements"],
    8. "ArrayPattern": ["elements"],
    9. "ArrowFunctionExpression": ["params", "body"],
    10. "AwaitExpression": ["argument"],
    11. "BlockStatement": ["body"],
    12. "BinaryExpression": ["left", "right"],
    13. "BreakStatement": ["label"],
    14. "CallExpression": ["callee", "arguments"],
    15. "CatchClause": ["param", "body"],
    16. "ChainExpression": ["expression"],
    17. "ClassBody": ["body"],
    18. "ClassDeclaration": ["id", "superClass", "body"],
    19. "ClassExpression": ["id", "superClass", "body"],
    20. "ConditionalExpression": ["test", "consequent", "alternate"],
    21. "ContinueStatement": ["label"],
    22. "DebuggerStatement": [],
    23. "DoWhileStatement": ["body", "test"],
    24. "EmptyStatement": [],
    25. "ExportAllDeclaration": ["exported", "source"],
    26. "ExportDefaultDeclaration": ["declaration"],
    27. "ExportNamedDeclaration": ["declaration", "specifiers", "source"],
    28. "ExportSpecifier": ["exported", "local"],
    29. "ExpressionStatement": ["expression"],
    30. "ExperimentalRestProperty": ["argument"],
    31. "ExperimentalSpreadProperty": ["argument"],
    32. "ForStatement": ["init", "test", "update", "body"],
    33. "ForInStatement": ["left", "right", "body"],
    34. "ForOfStatement": ["left", "right", "body"],
    35. "FunctionDeclaration": ["id", "params", "body"],
    36. "FunctionExpression": ["id", "params", "body"],
    37. "Identifier": [],
    38. "IfStatement": ["test", "consequent", "alternate"],
    39. "ImportDeclaration": ["specifiers", "source"],
    40. "ImportDefaultSpecifier": ["local"],
    41. "ImportExpression": ["source"],
    42. "ImportNamespaceSpecifier": ["local"],
    43. "ImportSpecifier": ["imported", "local"],
    44. "JSXAttribute": ["name", "value"],
    45. "JSXClosingElement": ["name"],
    46. "JSXElement": ["openingElement", "children", "closingElement"],
    47. "JSXEmptyExpression": [],
    48. "JSXExpressionContainer": ["expression"],
    49. "JSXIdentifier": [],
    50. "JSXMemberExpression": ["object", "property"],
    51. "JSXNamespacedName": ["namespace", "name"],
    52. "JSXOpeningElement": ["name", "attributes"],
    53. "JSXSpreadAttribute": ["argument"],
    54. "JSXText": [],
    55. "JSXFragment": ["openingFragment", "children", "closingFragment"],
    56. "Literal": [],
    57. "LabeledStatement": ["label", "body"],
    58. "LogicalExpression": ["left", "right"],
    59. "MemberExpression": ["object", "property"],
    60. "MetaProperty": ["meta", "property"],
    61. "MethodDefinition": ["key", "value"],
    62. "NewExpression": ["callee", "arguments"],
    63. "ObjectExpression": ["properties"],
    64. "ObjectPattern": ["properties"],
    65. "PrivateIdentifier": [],
    66. "Program": ["body"],
    67. "Property": ["key", "value"],
    68. "PropertyDefinition": ["key", "value"],
    69. "RestElement": ["argument"],
    70. "ReturnStatement": ["argument"],
    71. "SequenceExpression": ["expressions"],
    72. "SpreadElement": ["argument"],
    73. "StaticBlock": ["body"],
    74. "Super": [],
    75. "SwitchStatement": ["discriminant", "cases"],
    76. "SwitchCase": ["test", "consequent"],
    77. "TaggedTemplateExpression": ["tag", "quasi"],
    78. "TemplateElement": [],
    79. "TemplateLiteral": ["quasis", "expressions"],
    80. "ThisExpression": [],
    81. "ThrowStatement": ["argument"],
    82. "TryStatement": ["block", "handler", "finalizer"],
    83. "UnaryExpression": ["argument"],
    84. "UpdateExpression": ["argument"],
    85. "VariableDeclaration": ["declarations"],
    86. "VariableDeclarator": ["id", "init"],
    87. "WhileStatement": ["test", "body"],
    88. "WithStatement": ["object", "body"],
    89. "YieldExpression": ["argument"]
    90. }