You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中实现react-icons动态导入的优化方案求助

Next.js中实现react-icons动态导入的优化方案求助

大家好,我正在开发Next.js项目,想要通过参数动态从react-icons npm包中导入对应的图标库。

举个例子,fa库中的FaAws图标是这样导入的:

import { FaAws } from 'react-icons/fa';

我目前有一段可以正常运行的代码,但它的问题在于会把所有图标库都打包进构建产物里,导致体积过于庞大,急需优化:

import { ComponentType } from "react";
import { IconType as IconLibrary } from "react-icons";

import * as Fa from "react-icons/fa";
import * as Fa6 from "react-icons/fa6";
import * as Ai from "react-icons/ai";
import * as Md from "react-icons/md";
import * as Si from "react-icons/si";
import * as Vsc from "react-icons/vsc";
import * as Gr from "react-icons/gr";
import * as Ri from "react-icons/ri";
import * as Fc from "react-icons/fc";
import * as Bi from "react-icons/bi";
import * as Bs from "react-icons/bs";
import * as Cg from "react-icons/cg";
import * as Ci from "react-icons/ci";
import * as Go from "react-icons/go";
import * as Gi from "react-icons/gi";
import * as Pi from "react-icons/pi";
import * as Di from "react-icons/di";

import { IconTypesType } from "./IconTypes";

type IconLibraryType = {
  [key: string]: ComponentType<IconLibrary>;
}

type IconLibraryPropsType = {
  type: IconTypesType;
  code: string;
}

const Icon: React.FC<IconLibraryPropsType> = ({ type, code }) => {
  const libraries = new Map([
    ['fa', (Fa as IconLibraryType)],
    ['fa6', (Fa6 as IconLibraryType)],
    ['ai', (Ai as IconLibraryType)],
    ['vsc', (Vsc as IconLibraryType)],
    ['si', (Si as IconLibraryType)],
    ['gr', (Gr as IconLibraryType)],
    ['ri', (Ri as IconLibraryType)],
    ['fc', (Fc as IconLibraryType)],
    ['bi', (Bi as IconLibraryType)],
    ['cg', (Cg as IconLibraryType)],
    ['ci', (Ci as IconLibraryType)],
    ['go', (Go as IconLibraryType)],
    ['gi', (Gi as IconLibraryType)],
    ['pi', (Pi as IconLibraryType)],
    ['di', (Di as IconLibraryType)],
    ['bs', (Bs as IconLibraryType)],
    ['md', (Md as IconLibraryType)]
  ]);

  const IconComponent: ComponentType<any> = (libraries.get(type) as IconLibraryType)[code];

  if (IconComponent) {
    return <IconComponent />;
  }

  throw new Error(`Icon type : ${type} with name ${code} not found`);
};

export default Icon;

这段代码能正常工作,但构建时会加载所有图标库,导致包体积过大。我想利用Next.js文档里提到的模块化导入来解决这个问题,但不知道怎么适配所有需要的图标。另外,我还希望借助Next.js的服务端渲染性能,避免在前端懒加载所有图标(那样会增加用户端的加载时间)。

我尝试过用next/dynamic来做动态导入,但都失败了,下面是我的尝试和遇到的错误:

尝试1:

const IconComponent: ComponentType<any> = dynamic(() =>
  import(`react-icons/${type}`).then((module: IconLibraryType) => module[code]), {
    ssr: false
  }
);

错误信息:

- wait compiling...
- error ./node_modules/react-icons/LICENSE
Module parse failed: Unexpected token (1:10)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.

尝试2:

const IconComponent: ComponentType<any> = dynamic(() =>
  import(`react-icons/${type}/${code}`).then((module: IconLibraryType) => module.default), {
    ssr: false
  }
);

错误信息:

./node_modules/react-icons/ai/index.d.ts
Module parse failed: Unexpected token (3:7)
You may need an appropriate loader to handle this file type,
currently no loaders are configured to process this file.
| // THIS FILE IS AUTO GENERATED
| import { IconTree, IconType } from '../lib'
> export declare const AiFillAccountBook: IconType;
| export declare const AiFillAlert: IconType;
| export declare const AiFillAlipayCircle: IconType;

有没有大佬能帮忙解决这个问题呀?谢谢大家!

备注:内容来源于stack exchange,提问作者Youssef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 15:48:05