ARTICLE · 1353386
如何优雅地偷懒?用 Babel 插件给全项目的 Antd Select 自动开启搜索功能
如何优雅地偷懒?用 Babel 插件给全项目的 Antd Select 自动开启搜索功能这篇文章分享了一个非常实用的前端技巧——通过编写 Babel 插件,自动为 Ant Design 的所有Select组件开启搜索功能(showSearch),省去了在每个组件上重复写属性的繁琐操作。 项目框架: "umi":"^3.5.41", "antd":"^4.5.3" 一、在项目根目录创建: config/babel-plugin-auto-select-search.js 2. 在 Umi 中配置 Babel 插件 在 config/config.ts或 .umirc.ts中配置:
/*** 自动开启 Select 组件的搜索功能*/const AutoSelectSearch = function ({ types: t }: any) {return {name: 'umi-auto-select-search',visitor: {// 访问者模式JSXOpeningElement(path: any) {// JSXOpeningElement 检查是否是 JSX 开始元素const node = path.node;const name = node.name;let isAntdSelect = false;// import { Select } from 'antd'// import { Select as ASelect } from 'antd'if (t.isJSXIdentifier(name)) {const binding = path.scope.getBinding(name.name);if (binding && binding.path.isImportSpecifier()) {const importPath = binding.path.parentPath;const imported = binding.path.node.imported;isAntdSelect =importPath.isImportDeclaration() &&importPath.node.source.value === 'antd' &&(imported.name || imported.value) === 'Select';}}// import * as Antd from 'antd'// <Antd.Select />if (t.isJSXMemberExpression(name)) {// isJSXMemberExpression 检查是否是 JSX 成员表达式if (t.isJSXIdentifier(name.object) && // 检查对象是否是 JSX 标识符t.isJSXIdentifier(name.property) &&name.property.name === 'Select') {const binding = path.scope.getBinding(name.object.name); // 获取对象的绑定isAntdSelect =!!binding &&binding.path.isImportNamespaceSpecifier() && // 检查是否是导入命名空间指定符binding.path.parentPath.node.source.value === 'antd';}}if (!isAntdSelect) return;const attrs = node.attributes;const hasAttr = (attrName: string) =>attrs.some((attr: any) =>t.isJSXAttribute(attr) &&t.isJSXIdentifier(attr.name, {name: attrName,}),);// 默认开启搜索if (!hasAttr('showSearch')) {// 检查是否有 showSearch 属性attrs.push(t.jsxAttribute(t.jsxIdentifier('showSearch'), null));}// 根据 options 或 children 选择搜索字段if (!hasAttr('optionFilterProp')) {// 检查是否有 optionFilterProp 属性const hasOptions = hasAttr('options'); // 检查是否有 options 属性attrs.push(t.jsxAttribute(t.jsxIdentifier('optionFilterProp'),t.stringLiteral(hasOptions ? 'label' : 'children', // 根据是否有 options 属性来选择搜索字段),),);}},},};};export default AutoSelectSearch;
import AutoSelectSearchfrom './babel-plugin-auto-select-search.js';export default defineConfig({...extraBabelPlugins: [AutoSelectSearch,]})















































































