Antd imports and customizes antd class names on demand

Antd imports and customizes antd class names on demand

1: antd style can be introduced in two ways

  1. All at once (not recommended)

    • All the antd styles are introduced at one time. When packaging, the style file will become very large, resulting in a long time when loading for the first time and poor user experience
// Entry style file import style
@import 'antd/dist/antd.less';
  1. Import on demand (recommended) (the principle of tree shaking is used to automatically filter the styles that are not introduced)

    • The style of antd is introduced on demand. When packaging, only the style of the components used will be packaged into the style file. The style file will be much smaller, the first loading time will be much faster, and the user experience will be improved
// .babelrc.js
// Install the plugin yarn add Babel plugin import
module.exports = {
    // This configuration uses antd to load on demand
    "plugins":[
     [
      "import",
      {
        "libraryName": "antd",
        // This can also be changed to "CSS Style" by default
        "style": true
      }
     ]
    ]
}
// In this way, the on-demand loading is done. If you don't believe it, you can package the project and see the css code

2: antd custom class name

  1. Scenarios requiring custom antd class names
    • Encapsulate common components to prevent style attacks (to prevent styles in components from affecting styles in business code)
// webpack.config.js
{
    loader: 'less-loader',
        options: {
            lessOptions:{
                javascriptEnabled: true,
                    modifyVars: {
                        // The following two configurations are used on the premise that "style" must be configured on demand: true, otherwise it will not work, because the less variable is used here
                        // @Primary color is the theme color of antd, which is blue by default
                        // @Ant prefix is the prefix of custom antd component class name, which needs to be used in conjunction with < configprovider prefixcls = "YMX" >
                        "@primary-color": "red",
                        "@ant-prefix": "ymx",
                    },
              }
        },
}
  1. The principle of this custom class name configuration

    • The prefixCls in < configprovider prefixCls = "YMX" > is to change the className of the dom node in the jsx file
    • "@ ant prefix": "YMX", here is only to change the prefix of the code in the packaged css file
  2. Take a look at the portal component configuration < configprovider prefixcls = "YMX" > and webpack config. JS is configured with "@ ant prefix": "YMX", and then the effect is

    (1) What the browser console looks like:

    (2) After the packaged css code, the class is changed from ant to ymx

    • Red box: prefixCls is not used inside the component

      Class = "ant BTN" becomes class = "YMX BTN"

      Class = "ant collapse ant collapse icon position left" becomes class = "YMX collapse YMX collapse icon position left"

    • Blue box: configure prefixCls="innerPrefixCls" directly inside the component

      Class = "ant collapse ant collapse icon position left" becomes class = "innerprefixcls innerprefixcls icon position left"

  3. Next, use a relatively simple Collapse component source code on antd/github to explain why the above two items can be configured to modify the antd class name

Source address:

Since the amount of code involved is still a little large, here are the key parts

  • The getPrefixCls method in the ConfigProvider source code means that if the internal user of the component uses the custom class name customizePrefixCls, the class name will use customizePrefixCls
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
    if (customizePrefixCls) return customizePrefixCls;
    return suffixCls ? `ant-${suffixCls}` : 'ant';
},
  • The getPrefixClsWrapper method in the ConfigProvider source code means that if customizePrefixCls is used in the component, customizePrefixCls is used. If not used in the component, mergedPrefixCls is calculated according to the prefixCls on ConfigProvider. If not, mergedPrefixCls=prefixCls, otherwise mergedPrefixCls = context Getprefixcls ('') -- ant
const getPrefixClsWrapper = (context: ConfigConsumerProps) => {
    return (suffixCls: string, customizePrefixCls?: string) => {
      const { prefixCls } = props;
      if (customizePrefixCls) return customizePrefixCls;
      const mergedPrefixCls = prefixCls || context.getPrefixCls('');
      return suffixCls ? `${mergedPrefixCls}-${suffixCls}` : mergedPrefixCls;
    };
};
  • Collapse part of the source code
// Get prefixCls from the Collapse source code
// This means to get prefixCls. getPrefixCls is a method to get prefixCls. If the user has customized prefixCls, the previous default value collapse will be overwritten
const prefixCls = getPrefixCls('collapse', customizePrefixCls);

// The reorganized className in the Collapse source code
 const collapseClassName = classNames(
    {
      [`${prefixCls}-borderless`]: !bordered,
      [`${prefixCls}-icon-position-${iconPosition}`]: true,
      [`${prefixCls}-rtl`]: direction === 'rtl',
      [`${prefixCls}-ghost`]: !!ghost,
    },
    className,
  );

// The render method in the Collapse source code gives the reorganized className to the component
 <RcCollapse
    openAnimation={openAnimation}
    {...props}
    expandIcon={(panelProps: PanelProps) => renderExpandIcon(panelProps)}
    prefixCls={prefixCls}
    className={collapseClassName}
/>

Posted by brandonr on Tue, 17 May 2022 13:02:31 +0300