From d4177722f43223bd1d3e9e115f63d67a1ed40af8 Mon Sep 17 00:00:00 2001 From: norbiros Date: Tue, 14 Jul 2026 18:57:11 +0200 Subject: [PATCH 1/4] fix(core): resolve component file paths through symlinks (#104) --- packages/core/src/plugins/utils.ts | 5 +++-- packages/core/src/types.ts | 1 + packages/devtools/app/pages/components.vue | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core/src/plugins/utils.ts b/packages/core/src/plugins/utils.ts index 89552325..37d8bac6 100644 --- a/packages/core/src/plugins/utils.ts +++ b/packages/core/src/plugins/utils.ts @@ -111,11 +111,12 @@ export async function scanComponents(dirs: ComponentsDir[]): Promise = { mode, - filePath, - realPath: await realpath(filePath), + filePath: canonicalFilePath, + realPath: canonicalFilePath, pascalName, kebabName } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index c1c23713..e93e5a2e 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -127,6 +127,7 @@ export type Component = { shortPath: string mode?: 'client' | 'server' | 'all' priority?: number + /** @deprecated Use `filePath` instead. */ realPath: string wrapperComponent?: string docUrl?: string diff --git a/packages/devtools/app/pages/components.vue b/packages/devtools/app/pages/components.vue index 5e93e767..22b7202d 100644 --- a/packages/devtools/app/pages/components.vue +++ b/packages/devtools/app/pages/components.vue @@ -117,7 +117,7 @@ async function updateComponent() { if (!component.value) return await hooks.callHook('renderer:update-component', { - path: component.value.realPath, + path: component.value.filePath, props: props.value, wrapper: component.value?.wrapperComponent, events: componentMeta.value?.events From bb0fb46dda13520fc259f62ea3a83531113c24ca Mon Sep 17 00:00:00 2001 From: Romain Hamel Date: Wed, 15 Jul 2026 18:04:00 +0200 Subject: [PATCH 2/4] refactor(core): remove realPath from component collection --- packages/core/src/plugins/utils.ts | 4 +--- packages/core/src/types.ts | 2 -- packages/nuxt/test/playground.nuxt.test.ts | 2 +- packages/vue/test/playground.spec.ts | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/core/src/plugins/utils.ts b/packages/core/src/plugins/utils.ts index 37d8bac6..568c547d 100644 --- a/packages/core/src/plugins/utils.ts +++ b/packages/core/src/plugins/utils.ts @@ -111,12 +111,10 @@ export async function scanComponents(dirs: ComponentsDir[]): Promise = { mode, - filePath: canonicalFilePath, - realPath: canonicalFilePath, + filePath: await realpath(filePath), pascalName, kebabName } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index e93e5a2e..eb9b79f5 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -127,8 +127,6 @@ export type Component = { shortPath: string mode?: 'client' | 'server' | 'all' priority?: number - /** @deprecated Use `filePath` instead. */ - realPath: string wrapperComponent?: string docUrl?: string examples?: ComponentExample[] diff --git a/packages/nuxt/test/playground.nuxt.test.ts b/packages/nuxt/test/playground.nuxt.test.ts index 6777e5c2..4a48a38c 100644 --- a/packages/nuxt/test/playground.nuxt.test.ts +++ b/packages/nuxt/test/playground.nuxt.test.ts @@ -48,7 +48,7 @@ describe('nuxt playground', async () => { ? button.componentPath : undefined - const buttonSourcePath = [button.filePath, button.realPath, componentPath] + const buttonSourcePath = [button.filePath, componentPath] .find(path => path?.includes('@nuxt/ui')) if (!buttonSourcePath) { diff --git a/packages/vue/test/playground.spec.ts b/packages/vue/test/playground.spec.ts index 060dce02..f9d2b6c9 100644 --- a/packages/vue/test/playground.spec.ts +++ b/packages/vue/test/playground.spec.ts @@ -70,7 +70,7 @@ describe('vue playground', async () => { ? button.componentPath : undefined - const buttonSourcePath = [button.filePath, button.realPath, componentPath] + const buttonSourcePath = [button.filePath, componentPath] .find(path => path?.includes('@nuxt/ui')) if (!buttonSourcePath) { From ec5cb570b7880fc048f7f894b8210e93cd3bfc6a Mon Sep 17 00:00:00 2001 From: Romain Hamel Date: Wed, 15 Jul 2026 18:25:55 +0200 Subject: [PATCH 3/4] fix(core): resolve library collection realpath --- packages/core/src/plugins/collections.ts | 36 +++++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/core/src/plugins/collections.ts b/packages/core/src/plugins/collections.ts index 07d492bd..2514921b 100644 --- a/packages/core/src/plugins/collections.ts +++ b/packages/core/src/plugins/collections.ts @@ -7,6 +7,7 @@ import { resolve } from 'pathe' import { joinURL } from 'ufo' import type { Component } from 'vue' import { parseCompodiumMeta } from './meta/compodium-meta' +import { existsSync, realpathSync } from 'node:fs' export function resolveCollections(options: PluginOptions, viteConfig: any): Collection[] { const rootDir = options.rootDir ?? viteConfig.root @@ -33,20 +34,27 @@ export function resolveCollections(options: PluginOptions, viteConfig: any): Col } const libraryCollections = options.includeLibraryCollections - ? libraryCollectionsConfig.map(collection => ({ - ...collection, - exampleDir: { - path: collection.exampleDir, - pattern: '**/*.{vue,tsx}', - prefix: collection.prefix - }, - dirs: [{ - path: resolve(rootDir, collection.path), - pattern: '**/*.{vue,tsx}', - ignore: collection.ignore, - prefix: collection.prefix - }] - })) + ? libraryCollectionsConfig.map((collection) => { + const examplePath = existsSync(collection.exampleDir) ? realpathSync(collection.exampleDir) : collection.exampleDir + + const libPath = resolve(rootDir, collection.path) + const realLibPath = existsSync(libPath) ? realpathSync(libPath) : libPath + + return { + ...collection, + exampleDir: { + path: examplePath, + pattern: '**/*.{vue,tsx}', + prefix: collection.prefix + }, + dirs: [{ + path: realLibPath, + pattern: '**/*.{vue,tsx}', + ignore: collection.ignore, + prefix: collection.prefix + }] + } + }) : [] return [ From e607b5f134206afd7213dcd68010723b4d84ed1c Mon Sep 17 00:00:00 2001 From: Romain Hamel Date: Wed, 15 Jul 2026 20:04:31 +0200 Subject: [PATCH 4/4] fix(core): use import.meta.resolve to resolve library path --- packages/core/src/plugins/collections.ts | 24 +++++++++++++----------- packages/examples/src/index.ts | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/core/src/plugins/collections.ts b/packages/core/src/plugins/collections.ts index 2514921b..51d0cc18 100644 --- a/packages/core/src/plugins/collections.ts +++ b/packages/core/src/plugins/collections.ts @@ -3,11 +3,11 @@ import type { PluginOptions, Collection } from '../types' import { scanComponents } from './utils' import { watch } from 'chokidar' import type { VitePlugin } from 'unplugin' -import { resolve } from 'pathe' +import { dirname, resolve } from 'pathe' import { joinURL } from 'ufo' import type { Component } from 'vue' import { parseCompodiumMeta } from './meta/compodium-meta' -import { existsSync, realpathSync } from 'node:fs' +import { fileURLToPath } from 'node:url' export function resolveCollections(options: PluginOptions, viteConfig: any): Collection[] { const rootDir = options.rootDir ?? viteConfig.root @@ -34,26 +34,28 @@ export function resolveCollections(options: PluginOptions, viteConfig: any): Col } const libraryCollections = options.includeLibraryCollections - ? libraryCollectionsConfig.map((collection) => { - const examplePath = existsSync(collection.exampleDir) ? realpathSync(collection.exampleDir) : collection.exampleDir - - const libPath = resolve(rootDir, collection.path) - const realLibPath = existsSync(libPath) ? realpathSync(libPath) : libPath + ? libraryCollectionsConfig.flatMap((collection) => { + let pkgPath + try { + pkgPath = dirname(fileURLToPath(import.meta.resolve(collection.package))) + } catch { + return [] + } - return { + return [{ ...collection, exampleDir: { - path: examplePath, + path: resolve(collection.exampleDir), pattern: '**/*.{vue,tsx}', prefix: collection.prefix }, dirs: [{ - path: realLibPath, + path: resolve(pkgPath, collection.path), pattern: '**/*.{vue,tsx}', ignore: collection.ignore, prefix: collection.prefix }] - } + }] }) : [] diff --git a/packages/examples/src/index.ts b/packages/examples/src/index.ts index dc734953..77b409e8 100644 --- a/packages/examples/src/index.ts +++ b/packages/examples/src/index.ts @@ -24,7 +24,7 @@ export const libraryCollections = [ package: '@nuxt/ui', icon: 'lineicons:nuxt', exampleDir: resolve('./examples/ui'), - path: 'node_modules/@nuxt/ui/dist/runtime/components', + path: './runtime/components', ignore: ['App.vue', 'Toast.vue', '*Provider.vue', '*Base.vue', '*Content.vue'], prefix: 'U', wrapperComponent: resolve('./examples/ui.vue'),