We want to write a Babel Plugin, which move ‘const versionRegex = /(/d+)\.(/d+)\.(/d+)/gi‘ out of function scope and put it into global scope.
Code:
function getVersion(versionString) { const versionRegex = /(\d+)\.(\d+)\.(\d+)/gi var x = /foo/.text(‘thing‘) const [, major, minor, patch] = versionRegex.exec(versionString) return {major, minor, patch} }
AST:
export default function (babel) { const { types: t } = babel; return { name: "ast-transform", // not required visitor: { RegExpLiteral(path) { // We only want to locate // const versionRegex = /(\d+)\.(\d+)\.(\d+)/gi // NOT // var x = /foo/.text(‘thing‘) // for versionRegex, because it is a VariableDeclarator, it has init prop // for /foo/, it is under MemeberExpression‘s object prop if(path.parentKey !== ‘init‘) { return; } // Now we locate const versionRegex = /(\d+)\.(\d+)\.(\d+)/gi // we want to generate a unqi id for id const program = path.find(parent => parent.isProgram()) const variableDeclarator = path.find(parent => parent.isVariableDeclarator()) const variableDeclaration = path.find(parent => parent.isVariableDeclaration()) const { node: { id: {name: originalName} } } = variableDeclarator const newName = program.scope.generateUidIdentifier(originalName) console.log(variableDeclaration) // rename the versionRegex path.scope.rename(newName.name, originalName) // move the regex out of function scope // create new versionRegex variable out of function scope // and assign the value to it const newVariableDeclaration = t.variableDeclaration(variableDeclaration.node.kind, [ t.variableDeclarator(newName, path.node) ]) program.node.body.unshift(newVariableDeclaration) // last remove the old one variableDeclarator.remove() } } }; }
时间: 2024-11-10 10:33:51