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
相关产品推荐
相关产品推荐

