使用babel转换升级antdForm校验方法
V3 写法
//升级前 antdv3写法
const submit = () => {
this.props.form.validateFields((err,value)=> {
if(!err) {
// ##track(this.props)
dispath({
type:"home/login",
payload:value
})
} else {
message.error(err);
}
})
};
V4 写法
//升级后 antdv4写法
const submit = () => {
this.props.form.validateFields().then(value => {
// ##track(this.props)
dispath({
type: "home/login",
payload: value
});
}).catch(err => {
message.error(err);
});
};
babel转换
先说下思路,antdv3的form校验方法我们的主逻辑都是放在validateFields
这个方法里的回调内,而在v4版本呢,是使用链式调用的,那我们在做转换的第一步就是先分析切入点
- 首先我们要确定的是只转换
validateFields
这一块的代码,那么我们可以从当前的回调去入手转换,拿到我们当前节点的父节点,如果父节点的node.callee.property.name
是我们的validateFields
那我们就去走下一步 - 既然我们要转换v4写法,那我们就要先抽离出我们回调里的主逻辑,然后分别拿到我们
if
,else
这块的逻辑代码 - 拿到上述逻辑代码后,我们单独再对其使用
babel的templete
进行拼接包装 - 最后我们再使用
path.replaceWithMultiple
方法去对父节点进行替换
大概的思路就是这个样子,下面上代码
试一试代码放在了这里
首先安装以下依赖
- @babel/parser
- @babel/traverse
- @babel/generator
- @babel/template
- path
- fs
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const generate = require('@babel/generator').default;
const t = require('@babel/types');
const template = require("@babel/template").default;
const path = require('path');
const fs = require('fs');
let sourceCode = fs.readFileSync(path.join(__dirname, './test.js'), 'utf-8')
const ast = parser.parse(sourceCode, {
sourceType: 'unambiguous',
plugins: ['jsx']
});
const props_temp = template.statements(`
this.props.form.validateFields().then(FP).catch(EP)
`)
traverse(ast, {
ArrowFunctionExpression(path) {
let parentName = path.parentPath.node.callee && path.parentPath.node.callee.property.name == 'validateFields';
console.log(parentName)
if (parentName) {
let con = path.node.body.body[0].consequent,
alt = path.node.body.body[0].alternate;
let { params } = path.node;
const propsTemp = props_temp({
FP: t.arrowFunctionExpression([params[1]], con),
EP: t.arrowFunctionExpression([params[0]], alt)
})
path.parentPath.replaceWithMultiple(propsTemp)
}
}
});
const { code, map } = generate(ast);
fs.writeFileSync(path.join(__dirname, './test.js'), code);