From 3d6af908549cb2d20ae9cf5fc5493cbbcfe700b6 Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Thu, 11 May 2023 17:30:25 +0800 Subject: [PATCH 1/9] fix(nuxt): fix scan components error --- packages/nuxt/src/components/scan.ts | 21 ++++++++++---- .../components/same-name/same/Same.vue | 7 +++++ packages/nuxt/test/scan-components.test.ts | 28 +++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 packages/nuxt/test/fixture/components/same-name/same/Same.vue diff --git a/packages/nuxt/src/components/scan.ts b/packages/nuxt/src/components/scan.ts index 7a0065c5743f..116bc7fc88bd 100644 --- a/packages/nuxt/src/components/scan.ts +++ b/packages/nuxt/src/components/scan.ts @@ -80,13 +80,22 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr */ const fileNameParts = splitByCase(fileName) - const componentNameParts: string[] = [] - - while (prefixParts.length && - (prefixParts[0] || '').toLowerCase() !== (fileNameParts[0] || '').toLowerCase() - ) { - componentNameParts.push(prefixParts.shift()!) + let componentNameParts: string[] = [] + + let index = prefixParts.length - 1 + let matched = false + while (index >= 0) { + const prefixPart = (prefixParts[index] || '').toLowerCase() + const fileNamePart = (fileNameParts[0] || '').toLowerCase() + if (prefixPart === fileNamePart && !matched) { + matched = true + componentNameParts = [] + } else { + componentNameParts.push(prefixParts[index]) + } + index-- } + componentNameParts = componentNameParts.reverse() const componentName = pascalCase(componentNameParts) + pascalCase(fileNameParts) const suffix = (mode !== 'all' ? `-${mode}` : '') diff --git a/packages/nuxt/test/fixture/components/same-name/same/Same.vue b/packages/nuxt/test/fixture/components/same-name/same/Same.vue new file mode 100644 index 000000000000..671ce6550ca7 --- /dev/null +++ b/packages/nuxt/test/fixture/components/same-name/same/Same.vue @@ -0,0 +1,7 @@ + + diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts index 5a1a26b05f35..caf6f02aa828 100644 --- a/packages/nuxt/test/scan-components.test.ts +++ b/packages/nuxt/test/scan-components.test.ts @@ -84,6 +84,21 @@ const dirs: ComponentsDir[] = [ '**/*.d.ts' ], transpile: false + }, + { + path: rFixture('components/same-name'), + enabled: true, + extensions: [ + 'vue' + ], + pattern: '**/*.{vue,}', + ignore: [ + '**/*.stories.{js,ts,jsx,tsx}', + '**/*{M,.m,-m}ixin.{js,ts,jsx,tsx}', + '**/*.d.ts' + ], + transpile: false, + island: false } ] @@ -192,6 +207,19 @@ const expectedComponents = [ preload: false, priority: 1 }, + { + chunkName: 'components/same-name', + export: 'default', + global: undefined, + island: undefined, + kebabName: 'same-name-same', + mode: 'all', + pascalName: 'SameNameSame', + prefetch: false, + preload: false, + priority: 1, + shortPath: 'components/same-name/same/Same.vue' + }, { chunkName: 'components/some-glob', export: 'default', From fdb0cd7819386c39ca96fe51ae6039817a0bda23 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 11 May 2023 11:42:08 +0100 Subject: [PATCH 2/9] refactor: extract `resolveComponentName` util --- packages/nuxt/src/components/scan.ts | 56 +++++++++++++++------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/packages/nuxt/src/components/scan.ts b/packages/nuxt/src/components/scan.ts index 116bc7fc88bd..34b849c4bf60 100644 --- a/packages/nuxt/src/components/scan.ts +++ b/packages/nuxt/src/components/scan.ts @@ -72,33 +72,8 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr fileName = dir.pathPrefix === false ? basename(dirname(filePath)) : '' /* inherits from path */ } - /** - * Array of fileName parts splitted by case, / or - - * - * @example third-component -> ['third', 'component'] - * @example AwesomeComponent -> ['Awesome', 'Component'] - */ - const fileNameParts = splitByCase(fileName) - - let componentNameParts: string[] = [] - - let index = prefixParts.length - 1 - let matched = false - while (index >= 0) { - const prefixPart = (prefixParts[index] || '').toLowerCase() - const fileNamePart = (fileNameParts[0] || '').toLowerCase() - if (prefixPart === fileNamePart && !matched) { - matched = true - componentNameParts = [] - } else { - componentNameParts.push(prefixParts[index]) - } - index-- - } - componentNameParts = componentNameParts.reverse() - - const componentName = pascalCase(componentNameParts) + pascalCase(fileNameParts) const suffix = (mode !== 'all' ? `-${mode}` : '') + const componentName = resolveComponentName(fileName, prefixParts) if (resolvedNames.has(componentName + suffix) || resolvedNames.has(componentName)) { console.warn(`Two component files resolving to the same name \`${componentName}\`:\n` + @@ -146,3 +121,32 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr return components } + +export function resolveComponentName (fileName: string, prefixParts: string[]) { + /** + * Array of fileName parts splitted by case, / or - + * + * @example third-component -> ['third', 'component'] + * @example AwesomeComponent -> ['Awesome', 'Component'] + */ + const fileNameParts = splitByCase(fileName) + + let componentNameParts: string[] = [] + + let index = prefixParts.length - 1 + let matched = false + while (index >= 0) { + const prefixPart = (prefixParts[index] || '').toLowerCase() + const fileNamePart = (fileNameParts[0] || '').toLowerCase() + if (prefixPart === fileNamePart && !matched) { + matched = true + componentNameParts = [] + } else { + componentNameParts.push(prefixParts[index]) + } + index-- + } + componentNameParts = componentNameParts.reverse() + + return pascalCase(componentNameParts) + pascalCase(fileNameParts) +} From 412cb03319c378a9b08ba104a0f76d79e42ea037 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 11 May 2023 11:42:38 +0100 Subject: [PATCH 3/9] test: add some tests --- packages/nuxt/test/scan-components.test.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts index caf6f02aa828..e5b79b22f4a4 100644 --- a/packages/nuxt/test/scan-components.test.ts +++ b/packages/nuxt/test/scan-components.test.ts @@ -1,8 +1,8 @@ import { resolve } from 'node:path' -import { expect, it, vi } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import type { ComponentsDir } from 'nuxt/schema' -import { scanComponents } from '../src/components/scan' +import { resolveComponentName, scanComponents } from '../src/components/scan' const fixtureDir = resolve(__dirname, 'fixture') const rFixture = (...p: string[]) => resolve(fixtureDir, ...p) @@ -258,3 +258,21 @@ it('components:scanComponents', async () => { } expect(scannedComponents).deep.eq(expectedComponents) }) + +const tests: Array<[string, string[], string]> = [ + ['WithClientOnlySetup', ['Client'], 'ClientWithClientOnlySetup'], + ['Item', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], + ['ItemHolder', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], + ['ItemHolderItem', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], + ['Item', ['Item'], 'Item'], + ['Item', ['Item', 'Item'], 'Item'], + ['ItemTest', ['Item', 'Test'], 'ItemTest'], + ['ThingItemTest', ['Item', 'Thing'], 'ItemThingItemTest'], + ['Item', ['Thing', 'Item'], 'ThingItem'] +] + +describe('components:resolveComponentName', () => { + it.each(tests)('resolves %s with prefix parts %s and filename %s', (fileName, prefixParts: string[], result) => { + expect(resolveComponentName(fileName, prefixParts)).toBe(result) + }) +}) From 91002da644994ac083133ab1af12f605611b1f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E9=9B=BE=E4=B8=89=E8=AF=AD?= <32354856+baiwusanyu-c@users.noreply.github.com> Date: Thu, 11 May 2023 23:00:27 +0800 Subject: [PATCH 4/9] fix(nuxt): updated code --- packages/nuxt/src/components/scan.ts | 29 +++++++++++----------- packages/nuxt/test/scan-components.test.ts | 2 +- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/nuxt/src/components/scan.ts b/packages/nuxt/src/components/scan.ts index 34b849c4bf60..c09aede26b62 100644 --- a/packages/nuxt/src/components/scan.ts +++ b/packages/nuxt/src/components/scan.ts @@ -131,22 +131,21 @@ export function resolveComponentName (fileName: string, prefixParts: string[]) { */ const fileNameParts = splitByCase(fileName) - let componentNameParts: string[] = [] - - let index = prefixParts.length - 1 - let matched = false - while (index >= 0) { - const prefixPart = (prefixParts[index] || '').toLowerCase() - const fileNamePart = (fileNameParts[0] || '').toLowerCase() - if (prefixPart === fileNamePart && !matched) { - matched = true - componentNameParts = [] - } else { - componentNameParts.push(prefixParts[index]) - } - index-- + const componentNameParts: string[] = [] + + const isMaybeNeedFilled = prefixParts.length > fileNameParts.length + + while (prefixParts.length && (prefixParts[0] || '').toLowerCase() !== (fileNameParts[0] || '').toLowerCase()) { + componentNameParts.push(prefixParts.shift()!) + } + + // #20613 + if (prefixParts.length > 0 && + isMaybeNeedFilled && + [...new Set(prefixParts)].length > 1) { + // Item/Holder/Item.vue -> ItemHolderItem + return pascalCase(componentNameParts.concat(prefixParts)) } - componentNameParts = componentNameParts.reverse() return pascalCase(componentNameParts) + pascalCase(fileNameParts) } diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts index e5b79b22f4a4..d6a6af34cedc 100644 --- a/packages/nuxt/test/scan-components.test.ts +++ b/packages/nuxt/test/scan-components.test.ts @@ -208,7 +208,7 @@ const expectedComponents = [ priority: 1 }, { - chunkName: 'components/same-name', + chunkName: 'components/same-name-same', export: 'default', global: undefined, island: undefined, From 34a2d03d4b90ec4b65e91130754cf9fd7c82323a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E9=9B=BE=E4=B8=89=E8=AF=AD?= <32354856+baiwusanyu-c@users.noreply.github.com> Date: Thu, 11 May 2023 23:02:26 +0800 Subject: [PATCH 5/9] fix(nuxt): remove unuseful test code --- packages/nuxt/test/scan-components.test.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts index d6a6af34cedc..81aa052cc52b 100644 --- a/packages/nuxt/test/scan-components.test.ts +++ b/packages/nuxt/test/scan-components.test.ts @@ -84,21 +84,6 @@ const dirs: ComponentsDir[] = [ '**/*.d.ts' ], transpile: false - }, - { - path: rFixture('components/same-name'), - enabled: true, - extensions: [ - 'vue' - ], - pattern: '**/*.{vue,}', - ignore: [ - '**/*.stories.{js,ts,jsx,tsx}', - '**/*{M,.m,-m}ixin.{js,ts,jsx,tsx}', - '**/*.d.ts' - ], - transpile: false, - island: false } ] From 72ea2bedf387a7f610349c346f8d89feabc05f25 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 11 May 2023 23:19:44 +0100 Subject: [PATCH 6/9] test: update test assertion --- packages/nuxt/test/scan-components.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts index 81aa052cc52b..1817dd56753e 100644 --- a/packages/nuxt/test/scan-components.test.ts +++ b/packages/nuxt/test/scan-components.test.ts @@ -247,7 +247,7 @@ it('components:scanComponents', async () => { const tests: Array<[string, string[], string]> = [ ['WithClientOnlySetup', ['Client'], 'ClientWithClientOnlySetup'], ['Item', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], - ['ItemHolder', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], + ['ItemHolder', ['Item', 'Holder', 'Item'], 'ItemHolderItemHolder'], ['ItemHolderItem', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], ['Item', ['Item'], 'Item'], ['Item', ['Item', 'Item'], 'Item'], From 05c4145db9f0599d0cfd44ede442b75dbf4ed97e Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Fri, 12 May 2023 11:21:50 +0800 Subject: [PATCH 7/9] fix(nuxt): updated code --- packages/nuxt/src/components/scan.ts | 33 +++++++++++++--------- packages/nuxt/test/scan-components.test.ts | 6 +++- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/packages/nuxt/src/components/scan.ts b/packages/nuxt/src/components/scan.ts index c09aede26b62..458bb4d7e357 100644 --- a/packages/nuxt/src/components/scan.ts +++ b/packages/nuxt/src/components/scan.ts @@ -131,21 +131,28 @@ export function resolveComponentName (fileName: string, prefixParts: string[]) { */ const fileNameParts = splitByCase(fileName) - const componentNameParts: string[] = [] - - const isMaybeNeedFilled = prefixParts.length > fileNameParts.length - - while (prefixParts.length && (prefixParts[0] || '').toLowerCase() !== (fileNameParts[0] || '').toLowerCase()) { - componentNameParts.push(prefixParts.shift()!) + // e.g Item/Holder/Item/ItemHolderItem.vue -> ItemHolderItem + if (fileNameParts.join('').toLowerCase() === prefixParts.join('').toLowerCase()) { + return pascalCase(fileNameParts) } - // #20613 - if (prefixParts.length > 0 && - isMaybeNeedFilled && - [...new Set(prefixParts)].length > 1) { - // Item/Holder/Item.vue -> ItemHolderItem - return pascalCase(componentNameParts.concat(prefixParts)) + // e.g Item/Item/Item.vue -> Item + if ([...new Set(prefixParts)].length === 1 && + (fileNameParts[0] || '').toLowerCase() === (prefixParts[0] || '').toLowerCase()) { + return pascalCase(fileNameParts) } - return pascalCase(componentNameParts) + pascalCase(fileNameParts) + const fileNamePartsContent = fileNameParts.join('').toLowerCase() + let index = prefixParts.length - 1 + const matchedSuffix:string[] = [] + while (index >= 0) { + matchedSuffix.unshift(prefixParts[index].toLowerCase()) + if (!fileNamePartsContent.startsWith(matchedSuffix.join(''))) { + index-- + } else { + prefixParts.length = index + break + } + } + return pascalCase(prefixParts) + pascalCase(fileNameParts) } diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts index 1817dd56753e..2ce09b1fe43f 100644 --- a/packages/nuxt/test/scan-components.test.ts +++ b/packages/nuxt/test/scan-components.test.ts @@ -253,7 +253,11 @@ const tests: Array<[string, string[], string]> = [ ['Item', ['Item', 'Item'], 'Item'], ['ItemTest', ['Item', 'Test'], 'ItemTest'], ['ThingItemTest', ['Item', 'Thing'], 'ItemThingItemTest'], - ['Item', ['Thing', 'Item'], 'ThingItem'] + ['Item', ['Thing', 'Item'], 'ThingItem'], + ['ThingItemTest', ['Item', 'Thing', 'Foo'], 'ItemThingFooThingItemTest'], + ['ItemIn', ['Item', 'Holder', 'Item', 'In'], 'ItemHolderItemIn'], + ['Item', ['Item', 'Holder', 'Test'], 'ItemHolderTestItem'], + ['ItemHolderItem', ['Item', 'Holder', 'Item', 'Holder'], 'ItemHolderItemHolderItem'] ] describe('components:resolveComponentName', () => { From 6a36d56fa61c95efeb3f2efdd04ed9d20203007d Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Fri, 12 May 2023 11:25:37 +0800 Subject: [PATCH 8/9] fix(nuxt): updated code --- packages/nuxt/src/components/scan.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/components/scan.ts b/packages/nuxt/src/components/scan.ts index 458bb4d7e357..309fb0365937 100644 --- a/packages/nuxt/src/components/scan.ts +++ b/packages/nuxt/src/components/scan.ts @@ -146,7 +146,7 @@ export function resolveComponentName (fileName: string, prefixParts: string[]) { let index = prefixParts.length - 1 const matchedSuffix:string[] = [] while (index >= 0) { - matchedSuffix.unshift(prefixParts[index].toLowerCase()) + matchedSuffix.unshift((prefixParts[index] || '').toLowerCase()) if (!fileNamePartsContent.startsWith(matchedSuffix.join(''))) { index-- } else { From 08ad5de21108cee42c74c2d6fe4ae3ef0866b2bc Mon Sep 17 00:00:00 2001 From: baiwusanyu-c <740132583@qq.com> Date: Mon, 15 May 2023 11:35:28 +0800 Subject: [PATCH 9/9] fix(nuxt): updated code --- packages/nuxt/src/components/scan.ts | 28 ++++++++-------------- packages/nuxt/test/scan-components.test.ts | 4 ++-- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/packages/nuxt/src/components/scan.ts b/packages/nuxt/src/components/scan.ts index 309fb0365937..4c755eec9d5a 100644 --- a/packages/nuxt/src/components/scan.ts +++ b/packages/nuxt/src/components/scan.ts @@ -130,29 +130,21 @@ export function resolveComponentName (fileName: string, prefixParts: string[]) { * @example AwesomeComponent -> ['Awesome', 'Component'] */ const fileNameParts = splitByCase(fileName) - - // e.g Item/Holder/Item/ItemHolderItem.vue -> ItemHolderItem - if (fileNameParts.join('').toLowerCase() === prefixParts.join('').toLowerCase()) { - return pascalCase(fileNameParts) - } - - // e.g Item/Item/Item.vue -> Item - if ([...new Set(prefixParts)].length === 1 && - (fileNameParts[0] || '').toLowerCase() === (prefixParts[0] || '').toLowerCase()) { - return pascalCase(fileNameParts) - } - const fileNamePartsContent = fileNameParts.join('').toLowerCase() + const componentNameParts: string[] = [...prefixParts] let index = prefixParts.length - 1 const matchedSuffix:string[] = [] while (index >= 0) { matchedSuffix.unshift((prefixParts[index] || '').toLowerCase()) - if (!fileNamePartsContent.startsWith(matchedSuffix.join(''))) { - index-- - } else { - prefixParts.length = index - break + if (fileNamePartsContent.startsWith(matchedSuffix.join('')) || + // e.g Item/Item/Item.vue -> Item + (prefixParts[index].toLowerCase() === fileNamePartsContent && + prefixParts[index + 1] && + prefixParts[index] === prefixParts[index + 1])) { + componentNameParts.length = index } + index-- } - return pascalCase(prefixParts) + pascalCase(fileNameParts) + + return pascalCase(componentNameParts) + pascalCase(fileNameParts) } diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts index 2ce09b1fe43f..0c4025f2a0fd 100644 --- a/packages/nuxt/test/scan-components.test.ts +++ b/packages/nuxt/test/scan-components.test.ts @@ -246,14 +246,14 @@ it('components:scanComponents', async () => { const tests: Array<[string, string[], string]> = [ ['WithClientOnlySetup', ['Client'], 'ClientWithClientOnlySetup'], - ['Item', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], - ['ItemHolder', ['Item', 'Holder', 'Item'], 'ItemHolderItemHolder'], ['ItemHolderItem', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], ['Item', ['Item'], 'Item'], ['Item', ['Item', 'Item'], 'Item'], ['ItemTest', ['Item', 'Test'], 'ItemTest'], ['ThingItemTest', ['Item', 'Thing'], 'ItemThingItemTest'], ['Item', ['Thing', 'Item'], 'ThingItem'], + ['Item', ['Item', 'Holder', 'Item'], 'ItemHolderItem'], + ['ItemHolder', ['Item', 'Holder', 'Item'], 'ItemHolderItemHolder'], ['ThingItemTest', ['Item', 'Thing', 'Foo'], 'ItemThingFooThingItemTest'], ['ItemIn', ['Item', 'Holder', 'Item', 'In'], 'ItemHolderItemIn'], ['Item', ['Item', 'Holder', 'Test'], 'ItemHolderTestItem'],