Skip to content

Commit

Permalink
fix(nuxt): avoid warning about unused page/layout components when mou…
Browse files Browse the repository at this point in the history
…nted asynchronously
  • Loading branch information
IonianPlayboy committed Mar 15, 2024
1 parent 5dc96de commit 35fb406
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 5 deletions.
4 changes: 3 additions & 1 deletion packages/nuxt/src/app/plugins/check-if-layout-used.ts
Expand Up @@ -5,14 +5,16 @@ import { useError } from '../composables/error'

// @ts-expect-error virtual file
import layouts from '#build/layouts'
// @ts-expect-error virtual file
import { isNuxtLayoutUsed } from '#build/detected-nuxt-layout-usage'

export default defineNuxtPlugin({
name: 'nuxt:checkIfLayoutUsed',
setup (nuxtApp) {
const error = useError()

function checkIfLayoutUsed () {
if (!error.value && !nuxtApp._isNuxtLayoutUsed && Object.keys(layouts).length > 0) {
if (!error.value && !nuxtApp._isNuxtLayoutUsed && !isNuxtLayoutUsed && Object.keys(layouts).length > 0) {
console.warn('[nuxt] Your project has layouts but the `<NuxtLayout />` component has not been used.')
}
}
Expand Down
14 changes: 13 additions & 1 deletion packages/nuxt/src/components/loader.ts
Expand Up @@ -5,7 +5,7 @@ import { pascalCase } from 'scule'
import { resolve } from 'pathe'
import type { Component, ComponentsOptions } from 'nuxt/schema'

import { logger, tryUseNuxt } from '@nuxt/kit'
import { logger, tryUseNuxt, updateTemplates } from '@nuxt/kit'
import { distDir } from '../dirs'
import { isVue } from '../core/utils'

Expand All @@ -15,6 +15,7 @@ interface LoaderOptions {
sourcemap?: boolean
transform?: ComponentsOptions['transform']
experimentalComponentIslands?: boolean
detectedComponentsUsage: Record<string, boolean>
}

export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
Expand Down Expand Up @@ -54,6 +55,8 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
let identifier = map.get(component) || `__nuxt_component_${num++}`
map.set(component, identifier)

detectComponentUsage(component, options.detectedComponentsUsage)

const isServerOnly = !component._raw && component.mode === 'server' &&
!components.some(c => c.pascalName === component.pascalName && c.mode === 'client')
if (isServerOnly) {
Expand Down Expand Up @@ -123,3 +126,12 @@ function findComponent (components: Component[], name: string, mode: LoaderOptio
// and createServerComponent above
return otherModeComponent
}

function detectComponentUsage (component: Component, detectedComponentsUsage: LoaderOptions['detectedComponentsUsage']) {
if (process.env.NODE_ENV !== 'development' || !(component.pascalName in detectedComponentsUsage)) { return }

detectedComponentsUsage[component.pascalName] = true
const virtualFilename = `detected-${component.kebabName}-usage.mjs`

updateTemplates({ filter: template => template.filename === virtualFilename })
}
28 changes: 26 additions & 2 deletions packages/nuxt/src/components/module.ts
Expand Up @@ -211,6 +211,28 @@ export default defineNuxtModule<ComponentsOptions>({
}
})

const detectedComponentsUsage = {
NuxtLayout: false,
NuxtPage: false
}

if (process.env.NODE_ENV === 'development') {
addTemplate({
filename: 'detected-nuxt-layout-usage.mjs',
options: detectedComponentsUsage,
getContents: data => `
export const isNuxtLayoutUsed = ${data.options.NuxtLayout}
`
})
addTemplate({
filename: 'detected-nuxt-page-usage.mjs',
options: detectedComponentsUsage,
getContents: data => `
export const isNuxtPageUsed = ${data.options.NuxtPage}
`
})
}

nuxt.hook('vite:extendConfig', (config, { isClient, isServer }) => {
const mode = isClient ? 'client' : 'server'

Expand All @@ -230,7 +252,8 @@ export default defineNuxtModule<ComponentsOptions>({
getComponents,
mode,
transform: typeof nuxt.options.components === 'object' && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : undefined,
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands,
detectedComponentsUsage
}))

if (nuxt.options.experimental.componentIslands) {
Expand Down Expand Up @@ -299,7 +322,8 @@ export default defineNuxtModule<ComponentsOptions>({
getComponents,
mode,
transform: typeof nuxt.options.components === 'object' && !Array.isArray(nuxt.options.components) ? nuxt.options.components.transform : undefined,
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands
experimentalComponentIslands: !!nuxt.options.experimental.componentIslands,
detectedComponentsUsage
}))

if (nuxt.options.experimental.componentIslands) {
Expand Down
Expand Up @@ -3,13 +3,16 @@ import { defineNuxtPlugin } from '#app/nuxt'
import { onNuxtReady } from '#app/composables/ready'
import { useError } from '#app/composables/error'

// @ts-expect-error virtual file
import { isNuxtPageUsed } from '#build/detected-nuxt-page-usage'

export default defineNuxtPlugin({
name: 'nuxt:checkIfPageUnused',
setup (nuxtApp) {
const error = useError()

function checkIfPageUnused () {
if (!error.value && !nuxtApp._isNuxtPageUsed) {
if (!error.value && !nuxtApp._isNuxtPageUsed && !isNuxtPageUsed) {
console.warn(
'[nuxt] Your project has pages but the `<NuxtPage />` component has not been used.' +
' You might be using the `<RouterView />` component instead, which will not work correctly in Nuxt.' +
Expand Down

0 comments on commit 35fb406

Please sign in to comment.