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

Vue3+Vite项目中FontAwesome图标懒加载开发环境失效问题

Vue3+Vite中FontAwesome按需加载的开发环境异常问题

在Vue3+Vite项目中使用官方FontAwesome Vue3包时,静态预加载图标(通过library.add)可正常运行,但通过import.meta.glob实现点击按需加载时,开发环境出现异常,生产构建后却能正常工作。

静态加载正常代码

<script setup>
import { ref } from "vue";
import { library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

import { definition } from "@fortawesome/free-solid-svg-icons/faTruck";
library.add(definition);

const icon = ref("");
const showIcon = () => { icon.value = `fa-solid fa-truck`; };
</script>

<template>
  <button @click="showIcon">Show Truck Icon</button>
  <div v-if="icon">
    <font-awesome-icon :icon="icon" />
  </div>
</template>

按需加载异常代码

<script setup>
import { ref } from "vue";
import { library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

const modules = import.meta.glob(
  "../node_modules/@fortawesome/free-solid-svg-icons/faTruck.js",
  { eager: false, import: "definition" }
);

const icon = ref("");
const showIcon = () => {
  Object.values(modules)[0]().then((elem) => {
    library.add(elem);
    icon.value = `fa-solid fa-truck`;
  });
};
</script>

<template>
  <button @click="showIcon">Show Truck Icon</button>
  <div v-if="icon">
    <font-awesome-icon :icon="icon" />
  </div>
</template>

开发环境异常现象

  • 浏览器发起请求到http://localhost:5173/node_modules/@fortawesome/free-solid-svg-icons/faTruck.js
  • 控制台抛出错误:Uncaught (in promise) ReferenceError: exports is not defined

复现步骤

npm create vue@3 # 接受所有默认配置
cd vue-project
npm i @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/vue-fontawesome
# 将src/App.vue替换为上述按需加载代码

# 启动开发环境
npm run dev

# 生产构建验证
npm run build
npx http-server dist

解决方案

1. 配置Vite转译FontAwesome图标模块

问题根源是开发环境中Vite未转译@fortawesome/free-solid-svg-icons模块,导致CommonJS格式的代码直接在浏览器中运行报错。修改vite.config.js,让Vite优化该依赖:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  optimizeDeps: {
    include: ['@fortawesome/free-solid-svg-icons']
  }
})

同时修正import.meta.glob的路径,避免直接引用node_modules,改用包路径写法(支持批量匹配):

const modules = import.meta.glob(
  "@fortawesome/free-solid-svg-icons/fa*.js",
  { eager: false, import: "definition" }
);

2. 直接使用动态import(单图标场景)

如果不需要批量匹配图标,直接用动态import替代import.meta.glob,更简洁且无需额外配置:

<script setup>
import { ref } from "vue";
import { library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

const icon = ref("");
const showIcon = () => {
  import("@fortawesome/free-solid-svg-icons/faTruck")
    .then(({ definition }) => {
      library.add(definition);
      icon.value = `fa-solid fa-truck`;
    });
};
</script>

<template>
  <button @click="showIcon">Show Truck Icon</button>
  <div v-if="icon">
    <font-awesome-icon :icon="icon" />
  </div>
</template>

3. 利用FontAwesome的动态注册API

可以结合fontawesome-svg-core的icon()方法,在动态加载后直接注册,无需通过library.add,不过同样需要确保模块被Vite转译:

<script setup>
import { ref } from "vue";
import { icon } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

const iconData = ref(null);
const showIcon = () => {
  import("@fortawesome/free-solid-svg-icons/faTruck")
    .then(({ definition }) => {
      iconData.value = icon(definition);
    });
};
</script>

<template>
  <button @click="showIcon">Show Truck Icon</button>
  <div v-if="iconData">
    <font-awesome-icon :icon="iconData" />
  </div>
</template>

内容的提问来源于stack exchange,提问作者digEmAll

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 22:50:23