fix: bundle frontend icons locally

This commit is contained in:
KokerZhou authored and digua committed 2026-07-20 16:36:32 +08:00
1 parent 5f92d953c0
commit 8e9e098391
11 files changed
+70 -8

No files matched your search

+2 -6
View File
@@ -3,6 +3,7 @@ import { readFileSync } from 'fs'
import { defineConfig } from 'electron-vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
import { chatlabIconBundle } from '../../vite.icon-bundle.config'
const rootDir = resolve(__dirname, '../..')
const rootPkg = JSON.parse(readFileSync(resolve(rootDir, 'package.json'), 'utf-8'))
@@ -107,6 +108,7 @@ export default defineConfig({
},
},
}),
chatlabIconBundle(rootDir),
],
root: resolve(rootDir, 'src/'),
build: {
@@ -126,12 +128,6 @@ export default defineConfig({
if (id.includes('node_modules/echarts')) {
return 'vendor-echarts'
}
if (id.includes('node_modules/@nuxt/ui')) {
return 'vendor-nuxt-ui'
}
if (id.includes('node_modules/reka-ui')) {
return 'vendor-reka-ui'
}
if (id.includes('node_modules/@zumer/snapdom')) {
return 'vendor-snapdom'
}
+1
View File
@@ -2,6 +2,7 @@
"extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
"include": [
"electron.vite.config.*",
"../../vite.icon-bundle.config.ts",
"main/**/*",
"preload/**/*",
"shared/**/*",
+3
View File
@@ -1,3 +1,6 @@
import '@/icons/disable-iconify-api'
import 'virtual:nuxt-icon-bundle/register'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
+5
View File
@@ -74,6 +74,11 @@
"@openchatlab/tools": "workspace:*",
"@openchatlab/web-runtime": "workspace:*",
"@electron-toolkit/tsconfig": "^1.0.1",
"@iconify-json/heroicons": "^1.2.3",
"@iconify-json/lucide": "^1.2.118",
"@iconify-json/simple-icons": "1.2.83",
"@iconify/vue": "5.0.1",
"@nuxt/icon": "2.3.1",
"@nuxt/ui": "^4.9.0",
"@tailwindcss/vite": "^4.0.0",
"@types/markdown-it": "^14.1.2",
+29
View File
@@ -39,6 +39,21 @@ importers:
'@electron-toolkit/tsconfig':
specifier: ^1.0.1
version: 1.0.1(@types/node@25.2.2)
'@iconify-json/heroicons':
specifier: ^1.2.3
version: 1.2.3
'@iconify-json/lucide':
specifier: ^1.2.118
version: 1.2.118
'@iconify-json/simple-icons':
specifier: 1.2.83
version: 1.2.83
'@iconify/vue':
specifier: 5.0.1
version: 5.0.1(vue@3.5.27(typescript@6.0.3))
'@nuxt/icon':
specifier: 2.3.1
version: 2.3.1(vite@7.3.3(@types/node@25.2.2)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.27(typescript@6.0.3))
'@nuxt/ui':
specifier: ^4.9.0
version: 4.9.0(s6g7ddwkwqprfo6zxngcqjtvte)
@@ -1441,6 +1456,12 @@ packages:
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'}
'@iconify-json/heroicons@1.2.3':
resolution: {integrity: sha512-n+vmCEgTesRsOpp5AB5ILB6srsgsYK+bieoQBNlafvoEhjVXLq8nIGN4B0v/s4DUfa0dOrjwE/cKJgIKdJXOEg==}
'@iconify-json/lucide@1.2.118':
resolution: {integrity: sha512-JBnK4YOq6K/lA0JP//27QxFxJ4120TjvfXAzGZZIGjCcXcRRRFxl1rcV7+IWdcVCe90KXdqVaAwLaLf6G3HELw==}
'@iconify-json/simple-icons@1.2.83':
resolution: {integrity: sha512-6Pp9V++XisT9RKH7FB4RLPqUDzcmLtSma0ovOEIoEWGrXtHwBFsH7oN1z8vvCVCb95fb87QgR46/zRLyN9Y3kg==}
@@ -8090,6 +8111,14 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {}
'@iconify-json/heroicons@1.2.3':
dependencies:
'@iconify/types': 2.0.0
'@iconify-json/lucide@1.2.118':
dependencies:
'@iconify/types': 2.0.0
'@iconify-json/simple-icons@1.2.83':
dependencies:
'@iconify/types': 2.0.0
+1
View File
@@ -1,4 +1,5 @@
/// <reference types="vite/client" />
/// <reference types="@nuxt/icon/client" />
declare const __IS_ELECTRON__: boolean | undefined
declare const __IS_WEB_WASM__: boolean | undefined
+5
View File
@@ -0,0 +1,5 @@
import { _api as iconifyAPI } from '@iconify/vue'
// All icons used by the app are registered by virtual:nuxt-icon-bundle/register.
// Disable Iconify's fallback fetcher so an unbundled dynamic name cannot contact a CDN.
iconifyAPI.setFetch(undefined as unknown as typeof globalThis.fetch)
+3
View File
@@ -1,3 +1,6 @@
import '@/icons/disable-iconify-api'
import 'virtual:nuxt-icon-bundle/register'
import { mountChatLabApp } from '@/bootstrap/mount-app'
void mountChatLabApp().catch((error) => {
+17
View File
@@ -0,0 +1,17 @@
import { NuxtIconBundle } from '@nuxt/icon/vite'
import type { PluginOption } from 'vite'
/** Bundle every icon used by ChatLab and Nuxt UI so rendering never depends on an icon CDN. */
export function chatlabIconBundle(rootDir: string): PluginOption {
return NuxtIconBundle({
cwd: rootDir,
scan: {
globInclude: [
'src/**/*.{vue,ts,tsx}',
'apps/web-wasm/src/**/*.{vue,ts,tsx}',
'node_modules/@nuxt/ui/dist/**/*.{vue,js,mjs,ts}',
],
globExclude: [],
},
})
}
+2
View File
@@ -3,6 +3,7 @@ import { resolve } from 'node:path'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
import { defineConfig } from 'vite'
import { chatlabIconBundle } from './vite.icon-bundle.config'
const rootDir = import.meta.dirname
@@ -20,6 +21,7 @@ export default defineConfig({
},
},
}),
chatlabIconBundle(rootDir),
],
resolve: {
alias: {
+2 -2
View File
@@ -19,6 +19,7 @@ import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
import { DEFAULT_API_PORT } from './packages/config/src/schema'
import { createChatlabStartCommand, terminateChatlabStartProcess } from './scripts/dev-server-command.mjs'
import { chatlabIconBundle } from './vite.icon-bundle.config'
const BACKEND_PORT = DEFAULT_API_PORT
@@ -167,6 +168,7 @@ export default defineConfig({
},
},
}),
chatlabIconBundle(__dirname),
chatlabServePlugin(),
],
build: {
@@ -182,8 +184,6 @@ export default defineConfig({
if (id.includes('node_modules/echarts-wordcloud')) return 'vendor-echarts-wordcloud'
if (id.includes('node_modules/zrender')) return 'vendor-zrender'
if (id.includes('node_modules/echarts')) return 'vendor-echarts'
if (id.includes('node_modules/@nuxt/ui')) return 'vendor-nuxt-ui'
if (id.includes('node_modules/reka-ui')) return 'vendor-reka-ui'
if (id.includes('node_modules/@zumer/snapdom')) return 'vendor-snapdom'
return undefined
},