Skip to main content

使用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版本呢,是使用链式调用的,那我们在做转换的第一步就是先分析切入点

  1. 首先我们要确定的是只转换validateFields这一块的代码,那么我们可以从当前的回调去入手转换,拿到我们当前节点的父节点,如果父节点的node.callee.property.name是我们的validateFields那我们就去走下一步
  2. 既然我们要转换v4写法,那我们就要先抽离出我们回调里的主逻辑,然后分别拿到我们if,else这块的逻辑代码
  3. 拿到上述逻辑代码后,我们单独再对其使用babel的templete进行拼接包装
  4. 最后我们再使用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);