Skip to content

Commit 0d125c6

Browse files
committed
fix: better type detection and exclude duplicate components
1 parent fa5bf4b commit 0d125c6

File tree

4 files changed

+35
-25
lines changed

4 files changed

+35
-25
lines changed

src/module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export default defineNuxtModule<ModuleOptions>({
4444
'nuxt/dist/app/components/nuxt-route-announcer',
4545
'nuxt/dist/app/components/nuxt-stubs',
4646
(component) => component.filePath.endsWith('.svg')
47+
// exclude d.vue.ts files, main vue files are already included and we don't need to include the d.vue.ts files
48+
|| component.filePath.endsWith('.d.vue.ts')
4749
],
4850
include: [],
4951
metaFields: {

src/parser/index.ts

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createCheckerByJson } from "vue-component-meta"
22
import type { ComponentMeta } from 'vue-component-meta'
3-
import { refineMeta } from "./utils"
3+
import { refineMeta, tryResolveTypesDeclaration } from "./utils"
44
import { isAbsolute, join } from "pathe"
55
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'
66
import { withBase } from "ufo"
@@ -57,26 +57,7 @@ export function getComponentMeta(component: string, options?: Options): Componen
5757
* @returns component meta
5858
*/
5959
function _getComponentMeta(fullPath: string, opts: Options) {
60-
// Check if the component is in node_modules and adjust configuration accordingly
61-
const isNodeModule = fullPath.includes('node_modules')
62-
63-
// For node_modules components, try to find the TypeScript declaration file first
64-
let resolvedPath = fullPath
65-
if (isNodeModule && fullPath.endsWith('.vue')) {
66-
// Try different TypeScript declaration file patterns
67-
const patterns = [
68-
fullPath.replace('.vue', '.d.vue.ts'),
69-
fullPath.replace('.vue', '.vue.d.ts'),
70-
fullPath.replace('.vue', '.d.ts')
71-
]
72-
73-
for (const pattern of patterns) {
74-
if (existsSync(pattern)) {
75-
resolvedPath = pattern
76-
break
77-
}
78-
}
79-
}
60+
let resolvedPath = tryResolveTypesDeclaration(fullPath)
8061

8162
const checker = createCheckerByJson(
8263
opts.rootDir,

src/parser/meta-parser.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { resolvePathSync } from 'mlly'
77
import { hash } from 'ohash'
88
import type { ComponentMetaParserOptions, NuxtComponentMeta } from '../types/parser'
99
import { defu } from 'defu'
10-
import { refineMeta } from './utils'
10+
import { refineMeta, tryResolveTypesDeclaration } from './utils'
1111

1212
export function useComponentMetaParser (
1313
{
@@ -168,9 +168,10 @@ export function useComponentMetaParser (
168168
// We assume that components from node_modules don't change
169169
return
170170
}
171+
const resolvedPath = tryResolveTypesDeclaration(component.fullPath)
171172

172173
// Read component code
173-
let code = fs.readFileSync(component.fullPath, 'utf-8')
174+
let code = fs.readFileSync(resolvedPath, 'utf-8')
174175
const codeHash = hash(code)
175176
if (codeHash === component.meta.hash) {
176177
return
@@ -195,10 +196,10 @@ export function useComponentMetaParser (
195196

196197

197198
// Ensure file is updated
198-
checker.updateFile(component.fullPath, code)
199+
checker.updateFile(resolvedPath, code)
199200
}
200201

201-
const meta = checker.getComponentMeta(component.fullPath)
202+
const meta = checker.getComponentMeta(resolvedPath)
202203

203204
Object.assign(
204205
component.meta,

src/parser/utils.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { camelCase } from "scule"
22
import type { ComponentMeta } from 'vue-component-meta'
33
import type { ModuleOptions } from '../types/module'
4+
import { existsSync } from "fs"
45

56
export function refineMeta(meta: ComponentMeta, fields: ModuleOptions['metaFields'] = { type: true, props: true, slots: true, events: true, exposed: true }, overrides: ModuleOptions['overrides'][string] = {}): ComponentMeta {
67
const eventProps = new Set<string>(meta.events.map((event :any) => camelCase(`on_${event.name}`)))
@@ -133,3 +134,28 @@ function removeFields(obj: Record<string, any>, fieldsToRemove: string[]): any {
133134
}
134135
return obj;
135136
}
137+
138+
export function tryResolveTypesDeclaration(fullPath: string): string {
139+
// Check if the component is in node_modules and adjust configuration accordingly
140+
const isNodeModule = fullPath.includes('node_modules')
141+
142+
// For node_modules components, try to find the TypeScript declaration file first
143+
let resolvedPath = fullPath
144+
if (isNodeModule && fullPath.endsWith('.vue')) {
145+
// Try different TypeScript declaration file patterns
146+
const patterns = [
147+
fullPath.replace('.vue', '.d.vue.ts'),
148+
fullPath.replace('.vue', '.vue.d.ts'),
149+
fullPath.replace('.vue', '.d.ts')
150+
]
151+
152+
for (const pattern of patterns) {
153+
if (existsSync(pattern)) {
154+
resolvedPath = pattern
155+
break
156+
}
157+
}
158+
}
159+
160+
return resolvedPath
161+
}

0 commit comments

Comments
 (0)