diff --git a/specs/fixtures/issues/1740/app.vue b/specs/fixtures/issues/1740/app.vue new file mode 100644 index 000000000..99b20a8a8 --- /dev/null +++ b/specs/fixtures/issues/1740/app.vue @@ -0,0 +1,7 @@ + + + diff --git a/specs/fixtures/issues/1740/nuxt.config.ts b/specs/fixtures/issues/1740/nuxt.config.ts new file mode 100644 index 000000000..dbf89fe3b --- /dev/null +++ b/specs/fixtures/issues/1740/nuxt.config.ts @@ -0,0 +1,4 @@ +// https://v3.nuxtjs.org/api/configuration/nuxt.config +export default defineNuxtConfig({ + extends: './playground' +}) diff --git a/specs/fixtures/issues/1740/package.json b/specs/fixtures/issues/1740/package.json new file mode 100644 index 000000000..a43690172 --- /dev/null +++ b/specs/fixtures/issues/1740/package.json @@ -0,0 +1,12 @@ +{ + "private": true, + "scripts": { + "dev": "nuxi prepare", + "build": "nuxi build", + "generate": "nuxi generate", + "preview": "nuxi preview" + }, + "devDependencies": { + "nuxt": "latest" + } +} diff --git a/specs/fixtures/issues/1740/playground/app.config.ts b/specs/fixtures/issues/1740/playground/app.config.ts new file mode 100644 index 000000000..51053f698 --- /dev/null +++ b/specs/fixtures/issues/1740/playground/app.config.ts @@ -0,0 +1,14 @@ +export default defineAppConfig({ + myProject: { + name: 'This is Nuxt layer' + } +}) + +declare module '@nuxt/schema' { + interface AppConfigInput { + myProject?: { + /** Project name */ + name?: string + } + } +} diff --git a/specs/fixtures/issues/1740/playground/nuxt.config.ts b/specs/fixtures/issues/1740/playground/nuxt.config.ts new file mode 100644 index 000000000..ee28fc058 --- /dev/null +++ b/specs/fixtures/issues/1740/playground/nuxt.config.ts @@ -0,0 +1,3 @@ +export default defineNuxtConfig({ + modules: ['@nuxtjs/i18n'] +}) diff --git a/specs/fixtures/issues/1740/playground/package.json b/specs/fixtures/issues/1740/playground/package.json new file mode 100644 index 000000000..79d21d067 --- /dev/null +++ b/specs/fixtures/issues/1740/playground/package.json @@ -0,0 +1,15 @@ +{ + "private": true, + "type": "module", + "main": "./nuxt.config.ts", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview" + }, + "devDependencies": { + "@nuxtjs/i18n": "latest", + "nuxt": "latest" + } +} diff --git a/specs/issues/1740.spec.ts b/specs/issues/1740.spec.ts new file mode 100644 index 000000000..61ca4114e --- /dev/null +++ b/specs/issues/1740.spec.ts @@ -0,0 +1,19 @@ +import { test, describe, expect } from 'vitest' +import { fileURLToPath } from 'node:url' +import { setup, createPage, url } from '@nuxt/test-utils' +import { getText } from '../helper' + +describe('#1740', async () => { + await setup({ + rootDir: fileURLToPath(new URL(`../fixtures/issues/1740`, import.meta.url)), + browser: true + }) + + test('should be loaded vue-i18n related modules', async () => { + const home = url('/') + const page = await createPage() + await page.goto(home) + + expect(await getText(page, '#render')).toEqual('This is Nuxt layer') + }) +}) diff --git a/src/alias.ts b/src/alias.ts index cbaafc574..c46c49579 100644 --- a/src/alias.ts +++ b/src/alias.ts @@ -3,7 +3,7 @@ import { resolvePath } from '@nuxt/kit' import { pkgModulesDir } from './dirs' import { resolve } from 'pathe' import { VUE_I18N_PKG, VUE_I18N_BRIDGE_PKG, VUE_ROUTER_BRIDGE_PKG, VUE_I18N_ROUTING_PKG } from './constants' -import { tryResolve, getPackageManagerType } from './utils' +import { tryResolve, getLayerRootDirs, getPackageManagerType } from './utils' import type { Nuxt } from '@nuxt/schema' import type { PackageManager } from './utils' @@ -56,6 +56,8 @@ export async function resolveVueI18nAlias(pkgModulesDir: string, nuxt: Nuxt, pkg ? `${VUE_I18N_PKG}/dist/vue-i18n.mjs` : `${VUE_I18N_PKG}/dist/vue-i18n.runtime.mjs` const targets = [ + // for Nuxt layer + ...getLayerRootDirs(nuxt).map(root => resolve(root, 'node_modules', modulePath)), // 1st, try to resolve from `node_modules` (hoisted case) resolve(rootDir, 'node_modules', modulePath), // 2nd, try to resolve from `node_modules/@nuxtjs/i18n` (not hoisted case) @@ -72,6 +74,9 @@ async function resolveVueI18nBridgeAlias(pkgModulesDir: string, nuxt: Nuxt, pkgM const { rootDir, workspaceDir } = nuxt.options const modulePath = `${VUE_I18N_BRIDGE_PKG}/lib/index.mjs` as const const targets = [ + // for Nuxt layer + ...getLayerRootDirs(nuxt).map(root => resolve(root, 'node_modules', modulePath)), + ...getLayerRootDirs(nuxt).map(root => resolve(root, `${VUE_I18N_ROUTING_PKG}/node_modules`, modulePath)), // 1st, try to resolve from `node_modules` (hoisted case) resolve(rootDir, 'node_modules', modulePath), // 2nd, try to resolve from `node_modules/vue-i18n-routing` (not hoisted case) @@ -93,6 +98,9 @@ async function resolveVueRouterBridgeAlias(pkgModulesDir: string, nuxt: Nuxt, pk const { rootDir, workspaceDir } = nuxt.options const modulePath = `${VUE_ROUTER_BRIDGE_PKG}/lib/index.mjs` as const const targets = [ + // for Nuxt layer + ...getLayerRootDirs(nuxt).map(root => resolve(root, 'node_modules', modulePath)), + ...getLayerRootDirs(nuxt).map(root => resolve(root, `${VUE_I18N_ROUTING_PKG}/node_modules`, modulePath)), // 1st, try to resolve from `node_modules` (hoisted case) resolve(rootDir, 'node_modules', modulePath), // 2nd, try to resolve from `node_modules/vue-i18n-routing` (not hoisted case) @@ -114,6 +122,8 @@ export async function resolveVueI18nRoutingAlias(pkgModulesDir: string, nuxt: Nu const { rootDir, workspaceDir } = nuxt.options const modulePath = `${VUE_I18N_ROUTING_PKG}/dist/vue-i18n-routing.mjs` as const const targets = [ + // for Nuxt layer + ...getLayerRootDirs(nuxt).map(root => resolve(root, 'node_modules', modulePath)), // 1st, try to resolve from `node_modules` (hoisted case) resolve(rootDir, 'node_modules', modulePath), // 2nd, try to resolve from `node_modules/@nuxtjs/i18n` (not hoisted case) diff --git a/src/utils.ts b/src/utils.ts index 588c33ce9..aef86b2b6 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,6 +8,7 @@ import { NUXT_I18N_MODULE_ID } from './constants' import type { LocaleObject } from 'vue-i18n-routing' import type { NuxtI18nOptions, LocaleInfo } from './types' +import type { Nuxt } from '@nuxt/schema' const PackageManagerLockFiles = { 'npm-shrinkwrap.json': 'npm-legacy', @@ -66,6 +67,11 @@ export async function resolveLocales(path: string, locales: LocaleObject[]): Pro }) } +export function getLayerRootDirs(nuxt: Nuxt) { + const layers = nuxt.options._layers + return layers.length > 1 ? layers.map(layer => layer.config.rootDir) : [] +} + export async function tryResolve(id: string, targets: string[], pkgMgr: PackageManager, extention = '') { for (const target of targets) { if (await isExists(target + extention)) {