假设您有一个文件:
AddReactImport();
插件:
export default function ({types: t }) {
return {
visitor: {
CallExpression(p) {
if (p.node.callee.name === "AddReactImport") {
// add import if it's not there
}
}
}
};
}
如果文件/树的顶部没有import React from 'react';
,那么如何添加min-width: 100%
max-width: 100%
。
我认为比答案更重要的是你如何找到它。请告诉我,因为我很难找到有关如何开发Babel插件的信息来源。我现在的来源是:Plugin Handbook,Babel Types,AST Spec,this blog post和AST explorer。感觉就像用英语 - 德语词典试着说德语一样。
答案 0 :(得分:2)
export default function ({types: t }) {
return {
visitor: {
Program(path) {
const identifier = t.identifier('React');
const importDefaultSpecifier = t.importDefaultSpecifier(identifier);
const importDeclaration = t.importDeclaration([importDefaultSpecifier], t.stringLiteral('react'));
path.unshiftContainer('body', importDeclaration);
}
}
};
}
答案 1 :(得分:0)
我通常为此目的有帮手。如果要注入代码,只需使用@babel/parser
为其生成AST。然后根据需要注入它。
我也同意,即使在2019年,信息仍然很少。我实际上是通过研究babel
源代码,查看所有工具({{1},types
,traverse
,path
等来获取大部分信息的...),他们使用的助手,现有插件(例如code-frame
,以了解JS中的基本工具),webpack istanbul
等...
例如:babel-loader
并未在任何地方进行详细说明,但是您可以找到它的源代码here(非常有趣,它接受单个节点或节点数组!)
在这种情况下,我会:
unshiftContainer
)生成AST parseSource
(即根路径)中Program
由于您要添加导入语句,因此babel在不启用正确的插件且没有将程序类型设置为/**
* Helper: Generate AST from source through `@babel/parser`.
* Copied from somewhere... I think it was `@babel/traverse`
* @param {*} source
*/
export function parseSource(source) {
let ast;
try {
source = `${source}`;
ast = parse(source);
} catch (err) {
const loc = err.loc;
if (loc) {
err.message +=
"\n" +
codeFrameColumns(source, {
start: {
line: loc.line,
column: loc.column + 1,
},
});
}
throw err;
}
const nodes = ast.program.body;
nodes.forEach(n => traverse.removeProperties(n));
return nodes;
}
// ...
// actual plugin here
const plugin = function ({ types: t }) {
const importDeclaration = parseSource(`import React from 'react';`);
let imported = false;
let root;
return {
visitor: {
Program(path) {
root = path;
},
CallExpression(path) {
if (!imported && path.node.callee.name === "AddMyImport") {
// add import if it's not there
imported = true;
root.unshiftContainer('body', importDeclaration);
}
}
}
};
};
的情况下尝试解析它可能会很不高兴。