mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
feat(kit,nuxt): add component priority
to allow overriding (#19252)
This commit is contained in:
parent
a7d75a8465
commit
129bb4fa3a
@ -40,14 +40,24 @@ export async function addComponent (opts: AddComponentOptions) {
|
||||
preload: false,
|
||||
mode: 'all',
|
||||
shortPath: opts.filePath,
|
||||
priority: 0,
|
||||
...opts
|
||||
}
|
||||
|
||||
nuxt.hook('components:extend', (components: Component[]) => {
|
||||
const existingComponent = components.find(c => (c.pascalName === component.pascalName || c.kebabName === component.kebabName) && c.mode === component.mode)
|
||||
if (existingComponent) {
|
||||
const name = existingComponent.pascalName || existingComponent.kebabName
|
||||
console.warn(`Overriding ${name} component.`)
|
||||
const existingPriority = existingComponent.priority ?? 0
|
||||
const newPriority = component.priority ?? 0
|
||||
|
||||
if (newPriority < existingPriority) { return }
|
||||
|
||||
// We override where new component priority is equal or higher
|
||||
// but we warn if they are equal.
|
||||
if (newPriority === existingPriority) {
|
||||
const name = existingComponent.pascalName || existingComponent.kebabName
|
||||
console.warn(`Overriding ${name} component. You can specify a \`priority\` option when calling \`addComponent\` to avoid this warning.`)
|
||||
}
|
||||
Object.assign(existingComponent, component)
|
||||
} else {
|
||||
components.push(component)
|
||||
|
@ -118,7 +118,9 @@ export async function scanComponents (dirs: ComponentsDir[], srcDir: string): Pr
|
||||
kebabName,
|
||||
chunkName,
|
||||
shortPath,
|
||||
export: 'default'
|
||||
export: 'default',
|
||||
// by default, give priority to scanned components
|
||||
priority: 1
|
||||
}
|
||||
|
||||
if (typeof dir.extendComponent === 'function') {
|
||||
|
@ -158,47 +158,55 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
// Add <NuxtWelcome>
|
||||
addComponent({
|
||||
name: 'NuxtWelcome',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: tryResolveModule('@nuxt/ui-templates/templates/welcome.vue')!
|
||||
})
|
||||
|
||||
addComponent({
|
||||
name: 'NuxtLayout',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/layout')
|
||||
})
|
||||
|
||||
// Add <NuxtErrorBoundary>
|
||||
addComponent({
|
||||
name: 'NuxtErrorBoundary',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/nuxt-error-boundary')
|
||||
})
|
||||
|
||||
// Add <ClientOnly>
|
||||
addComponent({
|
||||
name: 'ClientOnly',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/client-only')
|
||||
})
|
||||
|
||||
// Add <DevOnly>
|
||||
addComponent({
|
||||
name: 'DevOnly',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/dev-only')
|
||||
})
|
||||
|
||||
// Add <ServerPlaceholder>
|
||||
addComponent({
|
||||
name: 'ServerPlaceholder',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/server-placeholder')
|
||||
})
|
||||
|
||||
// Add <NuxtLink>
|
||||
addComponent({
|
||||
name: 'NuxtLink',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/nuxt-link')
|
||||
})
|
||||
|
||||
// Add <NuxtLoadingIndicator>
|
||||
addComponent({
|
||||
name: 'NuxtLoadingIndicator',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/nuxt-loading-indicator')
|
||||
})
|
||||
|
||||
@ -206,6 +214,7 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
if (nuxt.options.experimental.componentIslands) {
|
||||
addComponent({
|
||||
name: 'NuxtIsland',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(nuxt.options.appDir, 'components/nuxt-island')
|
||||
})
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ export default defineNuxtModule({
|
||||
name: componentName,
|
||||
filePath: componentsPath,
|
||||
export: componentName,
|
||||
// built-in that we do not expect the user to override
|
||||
priority: 10,
|
||||
// kebab case version of these tags is not valid
|
||||
kebabName: componentName
|
||||
})
|
||||
|
@ -43,6 +43,7 @@ export default defineNuxtModule({
|
||||
})
|
||||
addComponent({
|
||||
name: 'NuxtPage',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(distDir, 'pages/runtime/page-placeholder')
|
||||
})
|
||||
return
|
||||
@ -256,6 +257,7 @@ export default defineNuxtModule({
|
||||
// Add <NuxtPage>
|
||||
addComponent({
|
||||
name: 'NuxtPage',
|
||||
priority: 10, // built-in that we do not expect the user to override
|
||||
filePath: resolve(distDir, 'pages/runtime/page')
|
||||
})
|
||||
|
||||
|
@ -97,6 +97,7 @@ const expectedComponents = [
|
||||
pascalName: 'Isle',
|
||||
prefetch: false,
|
||||
preload: false,
|
||||
priority: 1,
|
||||
shortPath: 'components/islands/Isle.vue'
|
||||
},
|
||||
{
|
||||
@ -109,6 +110,7 @@ const expectedComponents = [
|
||||
pascalName: 'Glob',
|
||||
prefetch: false,
|
||||
preload: false,
|
||||
priority: 1,
|
||||
shortPath: 'components/global/Glob.vue'
|
||||
},
|
||||
{
|
||||
@ -121,7 +123,8 @@ const expectedComponents = [
|
||||
global: undefined,
|
||||
island: undefined,
|
||||
prefetch: false,
|
||||
preload: false
|
||||
preload: false,
|
||||
priority: 1
|
||||
},
|
||||
{
|
||||
mode: 'client',
|
||||
@ -133,7 +136,8 @@ const expectedComponents = [
|
||||
global: undefined,
|
||||
island: undefined,
|
||||
prefetch: false,
|
||||
preload: false
|
||||
preload: false,
|
||||
priority: 1
|
||||
},
|
||||
{
|
||||
mode: 'server',
|
||||
@ -145,7 +149,8 @@ const expectedComponents = [
|
||||
global: undefined,
|
||||
island: undefined,
|
||||
prefetch: false,
|
||||
preload: false
|
||||
preload: false,
|
||||
priority: 1
|
||||
},
|
||||
{
|
||||
chunkName: 'components/client-component-with-props',
|
||||
@ -157,6 +162,7 @@ const expectedComponents = [
|
||||
pascalName: 'ClientComponentWithProps',
|
||||
prefetch: false,
|
||||
preload: false,
|
||||
priority: 1,
|
||||
shortPath: 'components/client/ComponentWithProps.vue'
|
||||
},
|
||||
{
|
||||
@ -169,6 +175,7 @@ const expectedComponents = [
|
||||
pascalName: 'ClientWithClientOnlySetup',
|
||||
prefetch: false,
|
||||
preload: false,
|
||||
priority: 1,
|
||||
shortPath: 'components/client/WithClientOnlySetup.vue'
|
||||
},
|
||||
{
|
||||
@ -181,7 +188,8 @@ const expectedComponents = [
|
||||
global: undefined,
|
||||
island: undefined,
|
||||
prefetch: false,
|
||||
preload: false
|
||||
preload: false,
|
||||
priority: 1
|
||||
},
|
||||
{
|
||||
chunkName: 'components/some-glob',
|
||||
@ -193,6 +201,7 @@ const expectedComponents = [
|
||||
pascalName: 'SomeGlob',
|
||||
prefetch: false,
|
||||
preload: false,
|
||||
priority: 1,
|
||||
shortPath: 'components/some-glob.global.vue'
|
||||
},
|
||||
{
|
||||
@ -205,6 +214,7 @@ const expectedComponents = [
|
||||
pascalName: 'Some',
|
||||
prefetch: false,
|
||||
preload: false,
|
||||
priority: 1,
|
||||
shortPath: 'components/some.island.vue'
|
||||
}
|
||||
]
|
||||
|
@ -10,6 +10,12 @@ export interface Component {
|
||||
global?: boolean
|
||||
island?: boolean
|
||||
mode?: 'client' | 'server' | 'all'
|
||||
/**
|
||||
* This number allows configuring the behavior of overriding Nuxt components.
|
||||
* If multiple components are provided with the same name, then higher priority
|
||||
* components will be used instead of lower priority components.
|
||||
*/
|
||||
priority?: number
|
||||
}
|
||||
|
||||
export interface ScanDir {
|
||||
|
Loading…
Reference in New Issue
Block a user