mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-20 07:30:57 +00:00
feat(nuxt): allow access to components within app (#20604)
This commit is contained in:
parent
ecb2fda113
commit
8353e4c66e
@ -113,14 +113,14 @@ export default defineNuxtModule<ComponentsOptions>({
|
||||
})
|
||||
|
||||
// components.d.ts
|
||||
addTemplate({ ...componentsTypeTemplate, options: { getComponents } })
|
||||
addTemplate({ ...componentsTypeTemplate })
|
||||
// components.plugin.mjs
|
||||
addPluginTemplate({ ...componentsPluginTemplate, options: { getComponents } } as any)
|
||||
addPluginTemplate({ ...componentsPluginTemplate } as any)
|
||||
// component-names.mjs
|
||||
addTemplate({ ...componentNamesTemplate, options: { getComponents, mode: 'all' } })
|
||||
addTemplate({ ...componentNamesTemplate, options: { mode: 'all' } })
|
||||
// components.islands.mjs
|
||||
if (nuxt.options.experimental.componentIslands) {
|
||||
addTemplate({ ...componentsIslandsTemplate, filename: 'components.islands.mjs', options: { getComponents } })
|
||||
addTemplate({ ...componentsIslandsTemplate, filename: 'components.islands.mjs' })
|
||||
} else {
|
||||
addTemplate({ filename: 'components.islands.mjs', getContents: () => 'export default {}' })
|
||||
}
|
||||
@ -158,7 +158,7 @@ export default defineNuxtModule<ComponentsOptions>({
|
||||
})
|
||||
|
||||
// Scan components and add to plugin
|
||||
nuxt.hook('app:templates', async () => {
|
||||
nuxt.hook('app:templates', async (app) => {
|
||||
const newComponents = await scanComponents(componentDirs, nuxt.options.srcDir!)
|
||||
await nuxt.callHook('components:extend', newComponents)
|
||||
// add server placeholder for .client components server side. issue: #7085
|
||||
@ -173,6 +173,7 @@ export default defineNuxtModule<ComponentsOptions>({
|
||||
}
|
||||
}
|
||||
context.components = newComponents
|
||||
app.components = newComponents
|
||||
})
|
||||
|
||||
nuxt.hook('prepare:types', ({ references, tsConfig }) => {
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { isAbsolute, relative } from 'pathe'
|
||||
import { genDynamicImport } from 'knitwork'
|
||||
import type { Component, Nuxt, NuxtPluginTemplate, NuxtTemplate } from 'nuxt/schema'
|
||||
import type { Component, Nuxt, NuxtApp, NuxtPluginTemplate, NuxtTemplate } from 'nuxt/schema'
|
||||
|
||||
export interface ComponentsTemplateContext {
|
||||
app: NuxtApp
|
||||
nuxt: Nuxt
|
||||
options: {
|
||||
getComponents: (mode?: 'client' | 'server' | 'all') => Component[]
|
||||
@ -34,8 +35,8 @@ export default defineNuxtPlugin({
|
||||
|
||||
export const componentsPluginTemplate: NuxtPluginTemplate<ComponentsTemplateContext> = {
|
||||
filename: 'components.plugin.mjs',
|
||||
getContents ({ options }) {
|
||||
const globalComponents = options.getComponents().filter(c => c.global)
|
||||
getContents ({ app }) {
|
||||
const globalComponents = app.components.filter(c => c.global)
|
||||
if (!globalComponents.length) { return emptyComponentsPlugin }
|
||||
|
||||
return `import { defineNuxtPlugin } from '#app/nuxt'
|
||||
@ -59,15 +60,15 @@ export default defineNuxtPlugin({
|
||||
|
||||
export const componentNamesTemplate: NuxtPluginTemplate<ComponentsTemplateContext> = {
|
||||
filename: 'component-names.mjs',
|
||||
getContents ({ options }) {
|
||||
return `export const componentNames = ${JSON.stringify(options.getComponents().filter(c => !c.island).map(c => c.pascalName))}`
|
||||
getContents ({ app }) {
|
||||
return `export const componentNames = ${JSON.stringify(app.components.filter(c => !c.island).map(c => c.pascalName))}`
|
||||
}
|
||||
}
|
||||
|
||||
export const componentsIslandsTemplate: NuxtTemplate<ComponentsTemplateContext> = {
|
||||
// components.islands.mjs'
|
||||
getContents ({ options }) {
|
||||
const components = options.getComponents()
|
||||
getContents ({ app }) {
|
||||
const components = app.components
|
||||
const islands = components.filter(component =>
|
||||
component.island ||
|
||||
// .server components without a corresponding .client component will need to be rendered as an island
|
||||
@ -85,9 +86,9 @@ export const componentsIslandsTemplate: NuxtTemplate<ComponentsTemplateContext>
|
||||
|
||||
export const componentsTypeTemplate: NuxtTemplate<ComponentsTemplateContext> = {
|
||||
filename: 'components.d.ts',
|
||||
getContents: ({ options, nuxt }) => {
|
||||
getContents: ({ app, nuxt }) => {
|
||||
const buildDir = nuxt.options.buildDir
|
||||
const componentTypes = options.getComponents().filter(c => !c.island).map(c => [
|
||||
const componentTypes = app.components.filter(c => !c.island).map(c => [
|
||||
c.pascalName,
|
||||
`typeof ${genDynamicImport(isAbsolute(c.filePath)
|
||||
? relative(buildDir, c.filePath).replace(/(?<=\w)\.(?!vue)\w+$/g, '')
|
||||
|
@ -12,6 +12,7 @@ export function createApp (nuxt: Nuxt, options: Partial<NuxtApp> = {}): NuxtApp
|
||||
dir: nuxt.options.srcDir,
|
||||
extensions: nuxt.options.extensions,
|
||||
plugins: [],
|
||||
components: [],
|
||||
templates: []
|
||||
} as unknown as NuxtApp) as NuxtApp
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Hookable } from 'hookable'
|
||||
import type { Ignore } from 'ignore'
|
||||
import type { NuxtHooks, NuxtLayout, NuxtMiddleware } from './hooks'
|
||||
import type { Component } from './components'
|
||||
import type { NuxtOptions } from './config'
|
||||
|
||||
export interface Nuxt {
|
||||
@ -58,6 +59,7 @@ export interface NuxtApp {
|
||||
dir: string
|
||||
extensions: string[]
|
||||
plugins: NuxtPlugin[]
|
||||
components: Component[]
|
||||
layouts: Record<string, NuxtLayout>
|
||||
middleware: NuxtMiddleware[]
|
||||
templates: NuxtTemplate[]
|
||||
|
Loading…
Reference in New Issue
Block a user