We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
上一篇写了通过写babel插件来入门ast, 在组内分享的时候,有同学说是不是可以写一个判空的插件呢? 把a.b => a && a.b呢?我觉得是的,这完全可以做呀!然后就尝试着在分享后写了一个。
a.b
a && a.b
https://astexplorer.net/#/gist/a54996b88a3fd57b65dbd9f2a14b4c91/fd5dbe0ea9ca616226980861f9d81e0984568753
var change = babelCheckEmpty(a.b.c.d); var notChange = d && d.e;
var change = a && (a.b && a.b.c && a.b.c.d); var notChange = d && d.e;
我只会去转换带有babelCheckEmpty 包裹的方法,这样避免影响其他方法的调用, 代码我贴在下面
module.exports = function (babel) { const {types: t} = babel; let isEnter = false; let objectName = ''; let stack = []; function getTemplateAst(tpl, opts = {}) { let ast = babel.template(tpl, opts)({}); if (Array.isArray(ast)) { return ast; } else { return [ast]; } } function generateExpressionStack(stack = []) { if (stack.length === 0) { return []; } let result = []; stack.reduce((sum, current) => { const nowStr = sum.concat('.').concat(current); result.push(nowStr); return nowStr; }); return result; } return { name: "ast-transform", // not required visitor: { CallExpression: { enter(path) { if (path.node.callee.name !== 'babelCheckEmpty') { return; } isEnter = true; }, exit(path) { if (path.node.callee.name !== 'babelCheckEmpty') { return; } isEnter = false; const resultArr = generateExpressionStack(stack); const arr = getTemplateAst(resultArr.join('&&')) || []; if (arr.length === 0 || stack.length === 0) { return; } path.replaceWith( t.logicalExpression('&&', t.identifier(stack[0]), arr[0].expression), ); stack = []; }, }, MemberExpression(path) { if (!isEnter || !path.node) return; objectName = path.node.object.name; if (t.isIdentifier(path.node.property)) { stack.unshift(path.node.property.name); } if (objectName) { stack.unshift(objectName); } }, }, }; };
由于直接用逻辑运算自己去构造一个 a.b && a.b.c && a.b.c.d 的ast过于复杂,其实是我不知道到底要怎么去写,所以我就使用了一个上一篇内容没有讲到的一个方法,直接利用babel.template 的API 根据传入的内容直接生成ast
let ast = babel.template(tpl, opts)({});
参考资料: 1.Babel 从入门到插件开发 https://juejin.im/entry/5912ba62a22b9d005819cff7 2.ast 入门(从写babel插件来深入了解ast #26
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
上一篇写了通过写babel插件来入门ast, 在组内分享的时候,有同学说是不是可以写一个判空的插件呢?
把
a.b
=>a && a.b
呢?我觉得是的,这完全可以做呀!然后就尝试着在分享后写了一个。在线示例:
https://astexplorer.net/#/gist/a54996b88a3fd57b65dbd9f2a14b4c91/fd5dbe0ea9ca616226980861f9d81e0984568753
转换前:
转换后
我只会去转换带有babelCheckEmpty 包裹的方法,这样避免影响其他方法的调用, 代码我贴在下面
由于直接用逻辑运算自己去构造一个 a.b && a.b.c && a.b.c.d 的ast过于复杂,其实是我不知道到底要怎么去写,所以我就使用了一个上一篇内容没有讲到的一个方法,直接利用babel.template 的API 根据传入的内容直接生成ast
放入工程里的截图
参考资料:
1.Babel 从入门到插件开发
https://juejin.im/entry/5912ba62a22b9d005819cff7
2.ast 入门(从写babel插件来深入了解ast
#26
The text was updated successfully, but these errors were encountered: