Learn about Babel from the webpack-route-plugin

A plug-in Babel related source code analysis

Plugin address: github.com/hxfdarling/…

The webpack-route-plugin is more interesting than other automatic routing plug-ins. Its core idea is to operate ast, and check whether there is export const routes =[] in the AST of each file. If the AST is extracted and added to componentNode, the route data is generated and written into the file. Only the logic related to ast is shown here.

parseFilesToNodes.ts function getRouterNode({ code, file, baseDir, RouteFile}) {const routeFunction = arrowFunctionExpression([], routeFunction = arrowFunctionExpression([], callExpression(identifier('import'), [ stringLiteral('.' + path.sep + path.relative(baseDir, file)), ]), ); // generate componentAst const componentNode = objectProperty(Identifier (' Component '), routeFunction); . . Export const routes =[] const routesDeclaration = body.find(node => {if (isExportNamedDeclaration(node) && isVariableDeclaration(node.declaration) && isVariableDeclarator(node.declaration.declarations[0]) && [ROUTES_KEY, ROUTE_KEY].indexOf( (node.declaration.declarations[0].id as Identifier).name, ) >= 0 && isArrayExpression(node.declaration.declarations[0].init) ) { return true; } return false; }); . . return toArray(router) .map(node => { if (isObjectExpression(node)) { if (! isRedirect(node.properties)) { ... . . // Add the generated componentNode to each pulled router ast. Node.properties.push (componentNode); } return node; } else { console.warn('route item must is pure object:', node); } }) .filter(Boolean); } genCode.ts ... . Function genRoutesCode(Nodes, const routes = []) outputFile) { const ast = file( program([ variableDeclaration('const', [ variableDeclarator(identifier(ROUTES_KEY), arrayExpression(nodes)), ]), ]), '', '', ); return transformFromAstSync(ast, '', { filename: outputFile }).code; } genFile.ts ... . // Write the generated routing data to export default (options: RouteOptions | BootstrapOptions) => { fs.writeFileSync(options.outputFile, genBootstrapCode(options)); return options.outputFile; };Copy the code

Introduction to Babel

Cheogo. Making. IO/learn – javas…

Juejin. Cn/post / 684490…

Segmentfault.com/a/119000002…

www.babeljs.cn/docs/plugin…

zhuanlan.zhihu.com/p/72995336

Developer.mozilla.org/zh-CN/docs/…

Juejin. Cn/post / 684490…

Cheogo. Making. IO/learn – javas…

The link above is quite detailed, so I don’t need to write in the code word, simply write my learning process:

Esprima.org/demo/parse…. This address is a javascript online conversion tool. At the beginning, I am not familiar with AST, so I don’t know how to start. Through online conversion, I can intuitively see what the javascript is converted into each node, such as:

js
var answer = 6 * 7;

ast
{
  "type": "Program",
  "body": [
    {
      "type": "VariableDeclaration",
      "declarations": [
        {
          "type": "VariableDeclarator",
          "id": {
            "type": "Identifier",
            "name": "answer"
          },
          "init": {
            "type": "BinaryExpression",
            "operator": "*",
            "left": {
              "type": "Literal",
              "value": 6,
              "raw": "6"
            },
            "right": {
              "type": "Literal",
              "value": 7,
              "raw": "7"
            }
          }
        }
      ],
      "kind": "var"
    }
  ],
  "sourceType": "script"
}
Copy the code

Such as the “type” : “VariableDeclaration”,

In developer.mozilla.org/zh-CN/docs/…

You can query the specific use of node types

variableDeclaration(kind, dtors[, loc]) kind: "const" | "let" | "var" dtors: [ CustomDeclarator ] loc: SourceLocation Is returned: CustomDeclarationCopy the code

In www.babeljs.cn/docs/babel-…

Babel Types can be queried using apis that generate the corresponding ast

variableDeclaration
  t.variableDeclaration(kind, declarations)
   See also t.isVariableDeclaration(node, opts) and t.assertVariableDeclaration(node, opts).

Aliases: Statement, Declaration
  kind: "var" | "let" | "const" (required)
  declarations: Array<VariableDeclarator> (required)
  declare: boolean (default: null)
Copy the code

The above flow corresponds to the following AST code that declares the Router in the webpack-Route-Plugin logic

function genRoutesCode(nodes, outputFile) {
  const ast = file(
    program([
      variableDeclaration('const', [
        variableDeclarator(identifier(ROUTES_KEY), arrayExpression(nodes)),
      ]),
    ]),
    '',
    '',
  );
  return transformFromAstSync(ast, '', { filename: outputFile }).code;
}
Copy the code

Maybe this is stupid, but I really can’t find a good and effective way to analyze javascript generated AST nodes, write more, look more, and then look at the AST is relatively better