antd4发布也有一段时间了,也是时候来一波升级了。
antd v4版本对多个组件做了性能优化,日期选择也做了优化调整,icon移出到了单独的库中。
看了升级文档,主要是icon和form2大组件改动较大,官方也提供了升级工具,不过我并没有去尝试使用,根据经验,这类工具坑较多,公司项目也做了其他封装,所有不考虑官方升级工具。
由于对ast有一定的了解和使用,对于这次升级是一个非常合适的方案,有大量的文件需要批量修改。
ast工具主要使用babel,支持tsx,还是比较方便的,先贴下代码。
let newCode = convertCodeUseAst(code, {
Program(rootPath) {
rootPath.traverse({
JSXOpeningElement(path1) {
let newTagName = null, attributes = []
let node1 = path1.node
if (node1.name) {
let tagName = node1.name.name
if (tagName == 'Icon') {
attributes = [...node1.attributes]
if (attributes) {
let typeValue
let themeValue
path1.traverse({
JSXAttribute(path2) {
let node2 = path2.node
if (node2.name.name == 'type') {
if (node2.value.type == 'StringLiteral') {
typeValue = node2.value.value
path2.remove()
}
}
if (node2.name.name == 'theme') {
themeValue = node2.value.value
path2.remove()
}
}
})
if (typeValue == null) {
return
}
let typeValue1 = typeValue
.replace(/^\w/, (w) => w.toUpperCase())
.replace(/-\w/g, (w) => w.toUpperCase())
.replace(/-/g, '')
let theme = 'Outlined'
if (themeValue == 'filled') {
theme = 'Filled'
}
if (themeValue == 'twoTone') {
theme = 'TwoTone'
}
newTagName = typeValue1 + theme
if (iconTypeList.indexOf(newTagName) == -1) {
iconTypeList.push(newTagName)
}
converted = true
}
}
}
if (newTagName) {
let attributes1 = attributes.filter(attr => {
let name = attr.name.name
return name != 'type' && name != 'theme'
})
path1.replaceWith(
t.jsxOpeningElement(t.jsxIdentifier(newTagName), attributes1, node1.selfClosing)
)
}
}
})
for (let iconType of iconTypeList) {
let isImported = isModuleImported(rootPath, iconType)
if (!isImported) {
addImportItem(rootPath, `\nimport {${iconType}} from '@ant-design/icons'`)
}
}
}
}, filePath)
代码仅供参考,这段代码主要用于将icon转化到@ant-design/icon。
思路是先遍历jsx标签,找到Icon标签,然后找到type属性和theme属性,进行对应的转化到antd v4方式。
~下次单独写一遍关于babel进行代码遍历和替换的文章~~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。