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