From 02c08b03aaeecada41e78589eb11f50fbb032762 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 5 Sep 2024 22:36:15 +0200 Subject: [PATCH] fix(nuxt): improve accuracy of module resolution conditions (#28846) --- packages/nuxt/package.json | 2 + packages/nuxt/src/core/nuxt.ts | 3 +- .../src/core/plugins/resolve-deep-imports.ts | 9 +- packages/vite/src/client.ts | 13 +++ packages/vite/src/server.ts | 18 ++++ playground/package.json | 7 +- pnpm-lock.yaml | 102 ++++-------------- test/fixtures/basic/package.json | 5 - test/fixtures/minimal-types/package.json | 3 +- test/fixtures/minimal/package.json | 3 +- test/fixtures/runtime-compiler/package.json | 6 -- test/fixtures/suspense/package.json | 9 +- 12 files changed, 64 insertions(+), 116 deletions(-) diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 23ed0499c2..3252027735 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -66,6 +66,7 @@ "@nuxt/telemetry": "^2.5.4", "@nuxt/vite-builder": "workspace:*", "@unhead/dom": "^1.10.4", + "@unhead/shared": "^1.10.4", "@unhead/ssr": "^1.10.4", "@unhead/vue": "^1.10.4", "@vue/shared": "^3.5.1", @@ -112,6 +113,7 @@ "uncrypto": "^0.1.3", "unctx": "^2.3.1", "unenv": "^1.10.0", + "unhead": "^1.10.4", "unimport": "^3.11.1", "unplugin": "^1.13.1", "unplugin-vue-router": "^0.10.7", diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 04d69f829d..cbeb6c7491 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -257,7 +257,8 @@ async function initNuxt (nuxt: Nuxt) { addWebpackPlugin(() => ImpoundPlugin.webpack(config)) // add resolver for modules used in virtual files - addVitePlugin(() => resolveDeepImportsPlugin(nuxt)) + addVitePlugin(() => resolveDeepImportsPlugin(nuxt), { client: false }) + addVitePlugin(() => resolveDeepImportsPlugin(nuxt), { server: false }) // Add transform for `onPrehydrate` lifecycle hook addBuildPlugin(prehydrateTransformPlugin(nuxt)) diff --git a/packages/nuxt/src/core/plugins/resolve-deep-imports.ts b/packages/nuxt/src/core/plugins/resolve-deep-imports.ts index 0eb0e205ec..fee568d654 100644 --- a/packages/nuxt/src/core/plugins/resolve-deep-imports.ts +++ b/packages/nuxt/src/core/plugins/resolve-deep-imports.ts @@ -8,10 +8,14 @@ import { pkgDir } from '../../dirs' export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin { const exclude: string[] = ['virtual:', '\0virtual:', '/__skip_vite'] + let conditions: string[] return { name: 'nuxt:resolve-bare-imports', enforce: 'post', - async resolveId (id, importer, options) { + configResolved (config) { + conditions = config.mode === 'test' ? [...config.resolve.conditions, 'import', 'require'] : config.resolve.conditions + }, + async resolveId (id, importer) { if (!importer || isAbsolute(id) || (!isAbsolute(importer) && !importer.startsWith('virtual:')) || exclude.some(e => id.startsWith(e))) { return } @@ -22,8 +26,7 @@ export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin { return await this.resolve?.(normalisedId, dir, { skipSelf: true }) ?? await resolvePath(id, { url: [dir, ...nuxt.options.modulesDir], - // TODO: respect nitro runtime conditions - conditions: options.ssr ? ['node', 'import', 'require'] : ['import', 'require'], + conditions, }).catch(() => { logger.debug('Could not resolve id', id, importer) return null diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index dfafe8d1cb..43b4a0769b 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -128,6 +128,19 @@ export async function buildClient (ctx: ViteBuildContext) { }, }, plugins: [ + { + name: 'nuxt:import-conditions', + enforce: 'post', + config (_config, env) { + if (env.mode !== 'test') { + return { + resolve: { + conditions: [ctx.nuxt.options.dev ? 'development' : 'production', 'web', 'browser', 'import', 'module', 'default'], + }, + } + } + }, + }, devStyleSSRPlugin({ srcDir: ctx.nuxt.options.srcDir, buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir), diff --git a/packages/vite/src/server.ts b/packages/vite/src/server.ts index 9ba55feaa0..6530654612 100644 --- a/packages/vite/src/server.ts +++ b/packages/vite/src/server.ts @@ -6,6 +6,7 @@ import { logger, resolvePath, tryResolveModule } from '@nuxt/kit' import { joinURL, withTrailingSlash, withoutLeadingSlash } from 'ufo' import type { ViteConfig } from '@nuxt/schema' import defu from 'defu' +import type { Nitro } from 'nitro/types' import type { ViteBuildContext } from './vite' import { createViteLogger } from './utils/logger' import { initViteNodeServer } from './vite-node' @@ -56,6 +57,7 @@ export async function buildServer (ctx: ViteBuildContext) { noDiscovery: true, }, resolve: { + conditions: ((ctx.nuxt as any)._nitro as Nitro)?.options.exportConditions, alias: { '#internal/nuxt/paths': resolve(ctx.nuxt.options.buildDir, 'paths.mjs'), '#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/server'), @@ -116,6 +118,8 @@ export async function buildServer (ctx: ViteBuildContext) { serverConfig.ssr!.external.push( // explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build 'unhead', '@unhead/ssr', 'unctx', 'h3', 'devalue', '@nuxt/devalue', 'radix3', 'rou3', 'unstorage', 'hookable', + // ensure we only have one version of vue if nitro is going to inline anyway + ...((ctx.nuxt as any)._nitro as Nitro).options.inlineDynamicImports ? ['vue', '@vue/server-renderer', '@unhead/vue'] : [], // dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build ...nitroDependencies, ) @@ -142,6 +146,20 @@ export async function buildServer (ctx: ViteBuildContext) { viteJsxPlugin(serverConfig.vueJsx), ) + if (!ctx.nuxt.options.dev) { + serverConfig.plugins!.push({ + name: 'nuxt:nitro:vue-feature-flags', + configResolved (config) { + for (const key in config.define) { + if (key.startsWith('__VUE')) { + // tree-shake vue feature flags for non-node targets + ((ctx.nuxt as any)._nitro as Nitro).options.replace[key] = config.define[key] + } + } + }, + }) + } + await ctx.nuxt.callHook('vite:configResolved', serverConfig, { isClient: false, isServer: true }) const onBuild = () => ctx.nuxt.callHook('vite:compiled') diff --git a/playground/package.json b/playground/package.json index 7e71518f92..7316c14927 100644 --- a/playground/package.json +++ b/playground/package.json @@ -7,11 +7,6 @@ "start": "nuxi preview" }, "dependencies": { - "@unhead/shared": "latest", - "@vue/devtools-api": "latest", - "@vue/shared": "latest", - "nuxt": "workspace:*", - "unhead": "latest", - "vue": "latest" + "nuxt": "workspace:*" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8788dd5ce..0179e6d2f2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -289,6 +289,9 @@ importers: '@unhead/dom': specifier: ^1.10.4 version: 1.10.4 + '@unhead/shared': + specifier: ^1.10.4 + version: 1.10.4 '@unhead/ssr': specifier: ^1.10.4 version: 1.10.4 @@ -427,6 +430,9 @@ importers: unenv: specifier: ^1.10.0 version: 1.10.0 + unhead: + specifier: ^1.10.4 + version: 1.10.4 unimport: specifier: ^3.11.1 version: 3.11.1(rollup@4.21.2)(webpack-sources@3.2.3) @@ -932,24 +938,9 @@ importers: playground: dependencies: - '@unhead/shared': - specifier: latest - version: 1.10.4 - '@vue/devtools-api': - specifier: latest - version: 6.6.3 - '@vue/shared': - specifier: latest - version: 3.5.1 nuxt: specifier: workspace:* version: link:../packages/nuxt - unhead: - specifier: latest - version: 1.10.4 - vue: - specifier: 3.5.1 - version: 3.5.1(typescript@5.5.4) test/fixtures/basic: dependencies: @@ -960,27 +951,12 @@ importers: specifier: workspace:* version: link:../../../packages/nuxt devDependencies: - '@unhead/dom': - specifier: latest - version: 1.10.4 - '@unhead/shared': - specifier: latest - version: 1.10.4 '@vue/devtools-api': specifier: latest version: 6.6.3 - '@vue/shared': - specifier: latest - version: 3.5.1 - iron-webcrypto: - specifier: latest - version: 1.2.1 ufo: specifier: 1.5.4 version: 1.5.4 - unhead: - specifier: latest - version: 1.10.4 unplugin: specifier: latest version: 1.13.1(webpack-sources@3.2.3) @@ -1015,18 +991,12 @@ importers: nuxt: specifier: workspace:* version: link:../../../packages/nuxt - vue: - specifier: 3.5.1 - version: 3.5.1(typescript@5.5.4) test/fixtures/minimal-types: dependencies: nuxt: specifier: workspace:* version: link:../../../packages/nuxt - vue: - specifier: 3.5.1 - version: 3.5.1(typescript@5.5.4) test/fixtures/remote-provider: {} @@ -1035,44 +1005,16 @@ importers: nuxt: specifier: workspace:* version: link:../../../packages/nuxt - devDependencies: - '@unhead/shared': - specifier: latest - version: 1.10.4 - '@vue/devtools-api': - specifier: latest - version: 6.6.3 - '@vue/shared': - specifier: latest - version: 3.5.1 - unhead: - specifier: latest - version: 1.10.4 test/fixtures/suspense: dependencies: nuxt: specifier: workspace:* version: link:../../../packages/nuxt - vue: - specifier: 3.5.1 - version: 3.5.1(typescript@5.5.4) devDependencies: - '@unhead/shared': - specifier: latest - version: 1.10.4 - '@vue/devtools-api': - specifier: latest - version: 6.6.3 - '@vue/shared': - specifier: latest - version: 3.5.1 typescript: specifier: 5.5.4 version: 5.5.4 - unhead: - specifier: latest - version: 1.10.4 packages: @@ -5303,10 +5245,6 @@ packages: resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} - minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -8310,8 +8248,8 @@ snapshots: '@nuxt/eslint-plugin@0.5.5(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': dependencies: - '@typescript-eslint/types': 8.3.0 - '@typescript-eslint/utils': 8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + '@typescript-eslint/types': 8.4.0 + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) eslint: 9.9.1(jiti@1.21.6) transitivePeerDependencies: - supports-color @@ -8739,7 +8677,7 @@ snapshots: '@stylistic/eslint-plugin@2.7.2(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': dependencies: '@types/eslint': 9.6.1 - '@typescript-eslint/utils': 8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) eslint: 9.9.1(jiti@1.21.6) eslint-visitor-keys: 4.0.0 espree: 10.1.0 @@ -8999,7 +8937,7 @@ snapshots: debug: 4.3.6 fast-glob: 3.3.2 is-glob: 4.0.3 - minimatch: 9.0.4 + minimatch: 9.0.5 semver: 7.6.3 ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: @@ -9525,7 +9463,7 @@ snapshots: '@vue/compiler-vue2': 2.7.16 '@vue/shared': 3.5.1 computeds: 0.0.1 - minimatch: 9.0.4 + minimatch: 9.0.5 muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: @@ -9538,7 +9476,7 @@ snapshots: '@vue/compiler-vue2': 2.7.16 '@vue/shared': 3.5.1 computeds: 0.0.1 - minimatch: 9.0.4 + minimatch: 9.0.5 muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: @@ -10705,15 +10643,15 @@ snapshots: eslint-plugin-import-x@4.1.1(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4): dependencies: - '@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) + '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4) debug: 4.3.6 doctrine: 3.0.0 eslint: 9.9.1(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 get-tsconfig: 4.7.6 is-glob: 4.0.3 - minimatch: 9.0.4 + minimatch: 9.0.5 semver: 7.6.3 stable-hash: 0.0.4 tslib: 2.7.0 @@ -11162,7 +11100,7 @@ snapshots: dependencies: foreground-child: 3.1.1 jackspeak: 3.1.2 - minimatch: 9.0.4 + minimatch: 9.0.5 minipass: 7.1.2 path-scurry: 1.11.1 @@ -11958,7 +11896,7 @@ snapshots: jsonc-parser: 3.2.1 jsonpointer: 5.0.1 markdownlint: 0.34.0 - minimatch: 9.0.4 + minimatch: 9.0.5 run-con: 1.3.2 smol-toml: 1.2.0 @@ -12350,10 +12288,6 @@ snapshots: dependencies: brace-expansion: 2.0.1 - minimatch@9.0.4: - dependencies: - brace-expansion: 2.0.1 - minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -13843,7 +13777,7 @@ snapshots: dependencies: '@istanbuljs/schema': 0.1.3 glob: 10.4.1 - minimatch: 9.0.4 + minimatch: 9.0.5 text-table@0.2.0: {} diff --git a/test/fixtures/basic/package.json b/test/fixtures/basic/package.json index fe04eb4e53..5eceaeb30d 100644 --- a/test/fixtures/basic/package.json +++ b/test/fixtures/basic/package.json @@ -9,13 +9,8 @@ "nuxt": "workspace:*" }, "devDependencies": { - "@unhead/dom": "latest", - "@unhead/shared": "latest", "@vue/devtools-api": "latest", - "@vue/shared": "latest", - "iron-webcrypto": "latest", "ufo": "latest", - "unhead": "latest", "unplugin": "latest", "vue": "latest" } diff --git a/test/fixtures/minimal-types/package.json b/test/fixtures/minimal-types/package.json index dd31eb9fb9..8cdd0337f1 100644 --- a/test/fixtures/minimal-types/package.json +++ b/test/fixtures/minimal-types/package.json @@ -6,7 +6,6 @@ "test:types": "nuxi prepare && npx vue-tsc --noEmit" }, "dependencies": { - "nuxt": "workspace:*", - "vue": "latest" + "nuxt": "workspace:*" } } diff --git a/test/fixtures/minimal/package.json b/test/fixtures/minimal/package.json index 83b314f397..b3c2d82157 100644 --- a/test/fixtures/minimal/package.json +++ b/test/fixtures/minimal/package.json @@ -5,7 +5,6 @@ "build": "nuxi build" }, "dependencies": { - "nuxt": "workspace:*", - "vue": "latest" + "nuxt": "workspace:*" } } diff --git a/test/fixtures/runtime-compiler/package.json b/test/fixtures/runtime-compiler/package.json index 0ee7c1d0ae..cf133dcd9b 100644 --- a/test/fixtures/runtime-compiler/package.json +++ b/test/fixtures/runtime-compiler/package.json @@ -6,11 +6,5 @@ }, "dependencies": { "nuxt": "workspace:*" - }, - "devDependencies": { - "@unhead/shared": "latest", - "@vue/devtools-api": "latest", - "@vue/shared": "latest", - "unhead": "latest" } } diff --git a/test/fixtures/suspense/package.json b/test/fixtures/suspense/package.json index 85cc733b09..44a373a436 100644 --- a/test/fixtures/suspense/package.json +++ b/test/fixtures/suspense/package.json @@ -5,14 +5,9 @@ "build": "nuxi build" }, "dependencies": { - "nuxt": "workspace:*", - "vue": "latest" + "nuxt": "workspace:*" }, "devDependencies": { - "@unhead/shared": "latest", - "@vue/devtools-api": "latest", - "@vue/shared": "latest", - "typescript": "latest", - "unhead": "latest" + "typescript": "latest" } }