From 26d0e1806183dbfb1a8d23c6d7dcf336fb74f51f Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 18 Mar 2025 22:44:23 +0000 Subject: [PATCH] fix(nuxt): fully resolve nuxt dependencies (#31436) --- eslint.config.mjs | 20 +++---------------- .../src/core/plugins/resolved-externals.ts | 19 ++++++++++++++---- packages/nuxt/src/meta.mjs | 19 ++++++++++++++++++ 3 files changed, 37 insertions(+), 21 deletions(-) create mode 100644 packages/nuxt/src/meta.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs index bae65d6ce3..2c77012d0f 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,6 +5,8 @@ import noOnlyTests from 'eslint-plugin-no-only-tests' import typegen from 'eslint-typegen' import perfectionist from 'eslint-plugin-perfectionist' +import { runtimeDependencies } from './packages/nuxt/src/meta.mjs' + export default createConfigForNuxt({ features: { stylistic: { @@ -188,23 +190,7 @@ export default createConfigForNuxt({ 'vue/server-renderer', 'vue', 'vue-router', - // other deps - 'devalue', - 'klona', - // unjs ecosystem - 'defu', - 'ufo', - 'h3', - 'destr', - 'consola', - 'hookable', - 'unctx', - 'cookie-es', - 'perfect-debounce', - 'radix3', - 'ohash', - 'pathe', - 'uncrypto', + ...runtimeDependencies, 'errx', /* only used in dev */ // internal deps 'nuxt/app', diff --git a/packages/nuxt/src/core/plugins/resolved-externals.ts b/packages/nuxt/src/core/plugins/resolved-externals.ts index 222030f5a3..31f2cace03 100644 --- a/packages/nuxt/src/core/plugins/resolved-externals.ts +++ b/packages/nuxt/src/core/plugins/resolved-externals.ts @@ -2,6 +2,9 @@ import type { Plugin } from 'vite' import { tryImportModule } from '@nuxt/kit' import type { Nuxt } from '@nuxt/schema' import type { Nitro } from 'nitro/types' +import { resolveModulePath } from 'exsolve' + +import { runtimeDependencies as runtimeNuxtDependencies } from '../../meta.mjs' export function ResolveExternalsPlugin (nuxt: Nuxt): Plugin { let external: Set = new Set() @@ -11,17 +14,18 @@ export function ResolveExternalsPlugin (nuxt: Nuxt): Plugin { enforce: 'pre', async configResolved () { if (!nuxt.options.dev) { - const { runtimeDependencies = [] } = await tryImportModule('nitro/runtime/meta', { + const { runtimeDependencies: runtimeNitroDependencies = [] } = await tryImportModule('nitro/runtime/meta', { url: new URL(import.meta.url), }) || {} external = new Set([ // explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build - 'unhead', '@unhead/vue', 'unctx', 'h3', 'devalue', '@nuxt/devalue', 'radix3', 'rou3', 'unstorage', 'hookable', + 'unhead', '@unhead/vue', '@nuxt/devalue', 'rou3', 'unstorage', // ensure we only have one version of vue if nitro is going to inline anyway - ...((nuxt as any)._nitro as Nitro).options.inlineDynamicImports ? ['vue', '@vue/server-renderer', '@unhead/vue'] : [], + ...((nuxt as any)._nitro as Nitro).options.inlineDynamicImports ? ['vue', '@vue/server-renderer'] : [], + ...runtimeNuxtDependencies, // dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build - ...runtimeDependencies, + ...runtimeNitroDependencies, ]) } }, @@ -32,6 +36,13 @@ export function ResolveExternalsPlugin (nuxt: Nuxt): Plugin { const res = await this.resolve?.(id, importer, { skipSelf: true }) if (res !== undefined && res !== null) { + if (res.id === id) { + res.id = resolveModulePath(res.id, { + try: true, + from: importer, + extensions: nuxt.options.extensions, + }) || res.id + } return { ...res, external: 'absolute', diff --git a/packages/nuxt/src/meta.mjs b/packages/nuxt/src/meta.mjs new file mode 100644 index 0000000000..f003614f8a --- /dev/null +++ b/packages/nuxt/src/meta.mjs @@ -0,0 +1,19 @@ +export const runtimeDependencies = [ + // other deps + 'devalue', + 'klona', + // unjs ecosystem + 'defu', + 'ufo', + 'h3', + 'destr', + 'consola', + 'hookable', + 'unctx', + 'cookie-es', + 'perfect-debounce', + 'radix3', + 'ohash', + 'pathe', + 'uncrypto', +]