// https://nuxt.com/docs/api/configuration/nuxt-config import federation from "@originjs/vite-plugin-federation"; import topLevelAwait from "vite-plugin-top-level-await"; import { join } from "path"; import { promises as fs } from "fs"; export default defineNuxtConfig({ compatibilityDate: "2025-05-15", devtools: { enabled: false }, imports: { dirs: ["composables", "composables/**"], }, modules: [ "@nuxt/icon", "@nuxt/eslint", "@nuxtjs/tailwindcss", "~/modules/generate-manifest", ], // ssr: false, css: ["~/assets/css/tailwind.css"], postcss: { plugins: { tailwindcss: {}, autoprefixer: {}, "postcss-prefix-selector": { prefix: ".remote-ui", // 远程组件根 class transform(prefix: string, selector: string, prefixedSelector: string) { // 保留全局基础样式 if (selector.startsWith("html") || selector.startsWith("body")) { return selector; } return prefixedSelector; }, }, }, }, eslint: { config: { stylistic: { commaDangle: "never", braceStyle: "1tbs", }, }, }, vite: { $client: { base: process.env.NODE_ENV === "production" ? "/" : undefined, }, plugins: [ topLevelAwait({ promiseExportName: "__tla", promiseImportName: (i) => `__tla_${i}`, }), ], build: { lib: { entry: "./index.ts", name: "RemoteUI", fileName: "remote-ui-kit", formats: ["es"], }, }, }, hooks: { "vite:extendConfig": async (config, { isClient }) => { if (!isClient) return; // 动态导入 manifest,dev/build 都安全 let manifest; try { // Nuxt buildDir 是 .nuxt const manifestPath = join(process.cwd(), ".nuxt/generated/manifest.ts"); // 检查文件是否存在 await fs.access(manifestPath); // 动态导入 manifest = await import(manifestPath); } catch (err) { console.warn("manifest not found yet, using empty fallback."); manifest = { manifestInfo: { remoteEntry: "remoteEntry.js" }, exposes: {}, }; } const components = manifest.manifestInfo?.components || []; const exposes = components.map((c: { name: string; path: string }) => { return { [c.name]: c.path } as const; }); config.plugins = config.plugins || []; config.plugins.push( federation({ name: "dynamic-remote", filename: manifest.manifestInfo?.remoteEntry || "remoteEntry.js", exposes: exposes || {}, shared: { vue: { generate: false } }, }), ); }, }, routeRules: { "/_nuxt/**": { headers: { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type, Authorization", }, }, }, icon: { serverBundle: { collections: [ "ant-design", "carbon", "duo-icons", "fluent", "healthicons", "hugeicons", "icon-park", "line-md", "lsicon", "lucide", "material-symbols", "material-symbols-light", "mdi", "mingcute", "ph", "ri", "si", "solar", "stash", "streamline-plump", "tabler", "uil", "ic", "akar-icons", ], // 本地打包的内容 // remote: 'jsdelivr' // 'unpkg' or 'github-raw', or a custom function }, localApiEndpoint: "/icon/_nuxt_icon", }, });