Frontend Development 9 min read

Antd Icon Reduce Plugin: Design, Implementation, and Usage for Reducing Bundle Size

This article introduces the Antd Icon Reduce plugin, explains the problem of oversized Ant Design icon bundles, details the design and implementation of a webpack loader and plugin that dynamically extracts used icons and modifies alias configuration, and provides installation and configuration instructions to achieve significant bundle size reduction.

Fulu Network R&D Team
Fulu Network R&D Team
Fulu Network R&D Team
Antd Icon Reduce Plugin: Design, Implementation, and Usage for Reducing Bundle Size

Ant Design (antd) is a widely used UI component library, but when using version 3.x the icon package is bundled in full even if only a few icons are needed, leading to large bundle sizes. To address this, a custom webpack plugin and loader are created to enable on‑demand icon loading.

Solution Idea

The approach configures webpack to resolve the path @ant-design/icons/lib/dist$ to a generated youIcon.js file that only exports the icons actually used in the project.

resolve: {
  alias: {
    '@ant-design/icons/lib/dist$': './youIcon.js',
  }
}

The youIcon.js file is generated automatically, eliminating the need for manual maintenance.

Plugin Design

1. Execution Flow

2. Feature Design

The plugin must (1) dynamically extract icons used in the source code and (2) modify webpack’s alias configuration accordingly.

Dynamic Icon Extraction

Source files are parsed with Babel to obtain an AST, then traversed to locate icon‑related JSX/JS calls. Matching rules handle special cases such as Button components that use loading or icon props. Extracted icon names are matched against the official @ant-design/icons/lib/dist exports, and unique entries are written to antd-icon-reduce.js .

Dynamic Configuration Modification

The plugin generates antd-icon-reduce.js , feeds its path to a custom loader, and adds a rule that applies the loader to all files under node_modules/antd . After each compilation, the alias is updated to point to the generated file, and temporary files are cleaned up via webpack hooks.

Implementation Details

1. antd-icon-reduce-loader

module.exports = function(source) {
  parseOptions.call(this);
  // ...
  var ast = parser.parse(source, { sourceType: "module", plugins: ['dynamicImport'] }); // parse source code
  traverse(ast, {
    CallExpression: function(path) {
      // match Icon components
      if (isCreateIcon(Identifier)) {
        var iconProps = getIconProps(ObjectExpression.properties);
        if (Object.keys(iconProps).length > 0) {
          var type = iconProps.type;
          var theme = iconProps.theme || 'outline';
          if (isArray(type)) {
            type.forEach(function(item) { searchIconByName(item, theme); });
          } else {
            searchIconByName(type, theme);
          }
        }
      } else if (isButton(Identifier)) {
        var btnProps = getBtnProps(ObjectExpression.properties);
        Object.keys(btnProps).forEach(function(k) {
          searchIconByName(k === 'loading' ? k : btnProps[k]);
        });
      }
    },
  });
  return core.transformFromAstSync(ast).code;
};

2. antd-icon-reduce-plugin

AntdIconReducePlugin.prototype.apply = function(compiler) {
  // ...
  const rules = compiler.options.module.rules;
  rules.forEach(function(ruleItem) {
    // replace loader name with our loader and pass temporary file path
    if (ruleItem.use[i] === 'ant-icon-reduce-loader') {
      ruleItem.use[i] = {
        loader: loaderName,
        options: { filePath: tempFilePath },
      };
    }
  });
  // add rule to match all antd js files
  rules.push({
    test: (filePath) => {
      if (filePath.indexOf(antdModulePath) >= 0 && path.extname(filePath) === '.js') {
        return true;
      }
      return false;
    },
    use: [{
      loader: "antd-icon-reduce-loader",
      options: { filePath: tempFilePath },
    }]
  });
};

Plugin Usage

1. Install Dependencies

npm i antd-icon-reduce-loader antd-icon-reduce-plugin -D

2. Webpack Configuration

Add the loader:

module: {
  rules: [
    {
      test: /\.js(x)?$/,
      exclude: /node_modules/,
      use: ["antd-icon-reduce-loader", "babel-loader"],
    }
  ]
}

Add the plugin:

var AntdIconReducePlugin = require('antd-icon-reduce-plugin');
// ...
plugins: [
  new AntdIconReducePlugin({
    icons: ['download', { type: 'up', theme: 'outline' }],
    development: true,
  })
]

Effect Demonstration

The main.js bundle size decreased by approximately 500 KB after applying the plugin, showing a clear improvement.

Notes

The plugin only recognizes icons defined with string literals or simple ternary expressions; dynamic variables are ignored unless manually added via the icons option.

Conclusion

The Antd Icon Reduce plugin works with React, Ant Design 3.x, and webpack 4.x to automatically extract used icons and replace the full icon package with a minimal custom bundle, significantly reducing output size. For issues or contributions, visit the GitHub repository: https://github.com/fuluteam/antd-icon-reduce-plugin .

ReactpluginWebpackloaderantdicon optimization
Fulu Network R&D Team
Written by

Fulu Network R&D Team

Providing technical literature sharing for Fulu Holdings' tech elite, promoting its technologies through experience summaries, technology consolidation, and innovation sharing.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.