antd4发布也有一段时间了,也是时候来一波升级了。
antd v4版本对多个组件作了性能优化,日期选择也作了优化调整,icon移出到了单独的库中。
看了升级文档,主要是icon和form2大组件改动较大,官方也提供了升级工具,不过我并无去尝试使用,根据经验,这类工具坑较多,公司项目也作了其余封装,全部不考虑官方升级工具。
因为对ast有必定的了解和使用,对于此次升级是一个很是合适的方案,有大量的文件须要批量修改。
ast工具主要使用babel,支持tsx,仍是比较方便的,先贴下代码。node
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进行代码遍历和替换的文章~~babel