diff --git a/package.json b/package.json index 39cbc1d1ba..de0ac29bb1 100644 --- a/package.json +++ b/package.json @@ -77,18 +77,12 @@ ] } }, - "imports": { - "#build/ui/*": "./.nuxt/ui/*.ts", - "#build/ui.css": "./.nuxt/ui.css" - }, "bin": { "nuxt-ui": "./cli/index.mjs" }, "style": "./dist/runtime/index.css", "main": "./dist/module.mjs", "files": [ - ".nuxt/ui", - ".nuxt/ui.css", "dist", "cli", "vue-plugin.d.ts" diff --git a/src/plugins/templates.ts b/src/plugins/templates.ts index 39d66dc7a2..ed3ca5d02c 100644 --- a/src/plugins/templates.ts +++ b/src/plugins/templates.ts @@ -1,3 +1,6 @@ +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { writeFileSync, mkdirSync, realpathSync } from 'node:fs' import type { UnpluginOptions } from 'unplugin' import type { NuxtUIOptions } from '../unplugin' import { getTemplates } from '../templates' @@ -7,21 +10,58 @@ import { getTemplates } from '../templates' * making them available to the Vue build. */ export default function TemplatePlugin(options: NuxtUIOptions, appConfig: Record) { - const templates = getTemplates(options, appConfig.ui) - const templateKeys = new Set(templates.map(t => `#build/${t.filename}`)) + let detectionComplete = false + const aliases: Record = {} + + // Write templates to a temporary directory (for Tailwind to read) + const tempDir = join(tmpdir(), 'nuxt-ui-templates') + mkdirSync(tempDir, { recursive: true }) + // Resolve to real path (handles symlinks like /var -> /private/var on macOS) + const realTempDir = realpathSync(tempDir) + + async function initializeTemplates() { + if (detectionComplete) return + + const templates = getTemplates(options, appConfig.ui, undefined) + + for (const template of templates) { + if (template.write && template.filename) { + const filepath = join(realTempDir, template.filename) + const dir = join(filepath, '..') + mkdirSync(dir, { recursive: true }) + const contents = await template.getContents!({} as any) + writeFileSync(filepath, contents as string) + + aliases[`#build/${template.filename}`] = filepath + } + } + + detectionComplete = true + } + + const initPromise = initializeTemplates() return { name: 'nuxt:ui:templates', enforce: 'pre', - resolveId(id) { - if (templateKeys.has(id + '.ts')) { - return id.replace('#build/', 'virtual:nuxt-ui-templates/') + '.ts' + async resolveId(id) { + await initPromise + + const aliasPath = aliases[id + '.ts'] + if (aliasPath) { + return { id: aliasPath } } }, - loadInclude: id => templateKeys.has(id.replace('virtual:nuxt-ui-templates/', '#build/')), - load(id) { - id = id.replace('virtual:nuxt-ui-templates/', '#build/') - return templates.find(t => `#build/${t.filename}` === id)!.getContents!({} as any) + vite: { + async config() { + await initPromise + + return { + resolve: { + alias: aliases + } + } + } } } satisfies UnpluginOptions } diff --git a/src/unplugin.ts b/src/unplugin.ts index 1e26ef5a0e..f572f79583 100644 --- a/src/unplugin.ts +++ b/src/unplugin.ts @@ -70,9 +70,9 @@ export const NuxtUIPlugin = createUnplugin((_options NuxtEnvironmentPlugin(options), ComponentImportPlugin(options, meta), AutoImportPlugin(options, meta), + TemplatePlugin(options, appConfig), tailwind(), PluginsPlugin(options), - TemplatePlugin(options, appConfig), AppConfigPlugin(options, appConfig), { name: 'nuxt:ui:plugins-duplication-detection',