fix(nuxt): improve accuracy of module resolution conditions (#28846)

This commit is contained in:
Daniel Roe 2024-09-05 22:36:15 +02:00
parent addc7853bf
commit 02c08b03aa
No known key found for this signature in database
GPG Key ID: 3714AB03996F442B
12 changed files with 64 additions and 116 deletions

View File

@ -66,6 +66,7 @@
"@nuxt/telemetry": "^2.5.4", "@nuxt/telemetry": "^2.5.4",
"@nuxt/vite-builder": "workspace:*", "@nuxt/vite-builder": "workspace:*",
"@unhead/dom": "^1.10.4", "@unhead/dom": "^1.10.4",
"@unhead/shared": "^1.10.4",
"@unhead/ssr": "^1.10.4", "@unhead/ssr": "^1.10.4",
"@unhead/vue": "^1.10.4", "@unhead/vue": "^1.10.4",
"@vue/shared": "^3.5.1", "@vue/shared": "^3.5.1",
@ -112,6 +113,7 @@
"uncrypto": "^0.1.3", "uncrypto": "^0.1.3",
"unctx": "^2.3.1", "unctx": "^2.3.1",
"unenv": "^1.10.0", "unenv": "^1.10.0",
"unhead": "^1.10.4",
"unimport": "^3.11.1", "unimport": "^3.11.1",
"unplugin": "^1.13.1", "unplugin": "^1.13.1",
"unplugin-vue-router": "^0.10.7", "unplugin-vue-router": "^0.10.7",

View File

@ -257,7 +257,8 @@ async function initNuxt (nuxt: Nuxt) {
addWebpackPlugin(() => ImpoundPlugin.webpack(config)) addWebpackPlugin(() => ImpoundPlugin.webpack(config))
// add resolver for modules used in virtual files // 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 // Add transform for `onPrehydrate` lifecycle hook
addBuildPlugin(prehydrateTransformPlugin(nuxt)) addBuildPlugin(prehydrateTransformPlugin(nuxt))

View File

@ -8,10 +8,14 @@ import { pkgDir } from '../../dirs'
export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin { export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin {
const exclude: string[] = ['virtual:', '\0virtual:', '/__skip_vite'] const exclude: string[] = ['virtual:', '\0virtual:', '/__skip_vite']
let conditions: string[]
return { return {
name: 'nuxt:resolve-bare-imports', name: 'nuxt:resolve-bare-imports',
enforce: 'post', 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))) { if (!importer || isAbsolute(id) || (!isAbsolute(importer) && !importer.startsWith('virtual:')) || exclude.some(e => id.startsWith(e))) {
return return
} }
@ -22,8 +26,7 @@ export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin {
return await this.resolve?.(normalisedId, dir, { skipSelf: true }) ?? await resolvePath(id, { return await this.resolve?.(normalisedId, dir, { skipSelf: true }) ?? await resolvePath(id, {
url: [dir, ...nuxt.options.modulesDir], url: [dir, ...nuxt.options.modulesDir],
// TODO: respect nitro runtime conditions conditions,
conditions: options.ssr ? ['node', 'import', 'require'] : ['import', 'require'],
}).catch(() => { }).catch(() => {
logger.debug('Could not resolve id', id, importer) logger.debug('Could not resolve id', id, importer)
return null return null

View File

@ -128,6 +128,19 @@ export async function buildClient (ctx: ViteBuildContext) {
}, },
}, },
plugins: [ 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({ devStyleSSRPlugin({
srcDir: ctx.nuxt.options.srcDir, srcDir: ctx.nuxt.options.srcDir,
buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir), buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir),

View File

@ -6,6 +6,7 @@ import { logger, resolvePath, tryResolveModule } from '@nuxt/kit'
import { joinURL, withTrailingSlash, withoutLeadingSlash } from 'ufo' import { joinURL, withTrailingSlash, withoutLeadingSlash } from 'ufo'
import type { ViteConfig } from '@nuxt/schema' import type { ViteConfig } from '@nuxt/schema'
import defu from 'defu' import defu from 'defu'
import type { Nitro } from 'nitro/types'
import type { ViteBuildContext } from './vite' import type { ViteBuildContext } from './vite'
import { createViteLogger } from './utils/logger' import { createViteLogger } from './utils/logger'
import { initViteNodeServer } from './vite-node' import { initViteNodeServer } from './vite-node'
@ -56,6 +57,7 @@ export async function buildServer (ctx: ViteBuildContext) {
noDiscovery: true, noDiscovery: true,
}, },
resolve: { resolve: {
conditions: ((ctx.nuxt as any)._nitro as Nitro)?.options.exportConditions,
alias: { alias: {
'#internal/nuxt/paths': resolve(ctx.nuxt.options.buildDir, 'paths.mjs'), '#internal/nuxt/paths': resolve(ctx.nuxt.options.buildDir, 'paths.mjs'),
'#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/server'), '#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/server'),
@ -116,6 +118,8 @@ export async function buildServer (ctx: ViteBuildContext) {
serverConfig.ssr!.external.push( serverConfig.ssr!.external.push(
// explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build // 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', '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 // dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build
...nitroDependencies, ...nitroDependencies,
) )
@ -142,6 +146,20 @@ export async function buildServer (ctx: ViteBuildContext) {
viteJsxPlugin(serverConfig.vueJsx), 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 }) await ctx.nuxt.callHook('vite:configResolved', serverConfig, { isClient: false, isServer: true })
const onBuild = () => ctx.nuxt.callHook('vite:compiled') const onBuild = () => ctx.nuxt.callHook('vite:compiled')

View File

@ -7,11 +7,6 @@
"start": "nuxi preview" "start": "nuxi preview"
}, },
"dependencies": { "dependencies": {
"@unhead/shared": "latest", "nuxt": "workspace:*"
"@vue/devtools-api": "latest",
"@vue/shared": "latest",
"nuxt": "workspace:*",
"unhead": "latest",
"vue": "latest"
} }
} }

View File

@ -289,6 +289,9 @@ importers:
'@unhead/dom': '@unhead/dom':
specifier: ^1.10.4 specifier: ^1.10.4
version: 1.10.4 version: 1.10.4
'@unhead/shared':
specifier: ^1.10.4
version: 1.10.4
'@unhead/ssr': '@unhead/ssr':
specifier: ^1.10.4 specifier: ^1.10.4
version: 1.10.4 version: 1.10.4
@ -427,6 +430,9 @@ importers:
unenv: unenv:
specifier: ^1.10.0 specifier: ^1.10.0
version: 1.10.0 version: 1.10.0
unhead:
specifier: ^1.10.4
version: 1.10.4
unimport: unimport:
specifier: ^3.11.1 specifier: ^3.11.1
version: 3.11.1(rollup@4.21.2)(webpack-sources@3.2.3) version: 3.11.1(rollup@4.21.2)(webpack-sources@3.2.3)
@ -932,24 +938,9 @@ importers:
playground: playground:
dependencies: 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: nuxt:
specifier: workspace:* specifier: workspace:*
version: link:../packages/nuxt 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: test/fixtures/basic:
dependencies: dependencies:
@ -960,27 +951,12 @@ importers:
specifier: workspace:* specifier: workspace:*
version: link:../../../packages/nuxt version: link:../../../packages/nuxt
devDependencies: devDependencies:
'@unhead/dom':
specifier: latest
version: 1.10.4
'@unhead/shared':
specifier: latest
version: 1.10.4
'@vue/devtools-api': '@vue/devtools-api':
specifier: latest specifier: latest
version: 6.6.3 version: 6.6.3
'@vue/shared':
specifier: latest
version: 3.5.1
iron-webcrypto:
specifier: latest
version: 1.2.1
ufo: ufo:
specifier: 1.5.4 specifier: 1.5.4
version: 1.5.4 version: 1.5.4
unhead:
specifier: latest
version: 1.10.4
unplugin: unplugin:
specifier: latest specifier: latest
version: 1.13.1(webpack-sources@3.2.3) version: 1.13.1(webpack-sources@3.2.3)
@ -1015,18 +991,12 @@ importers:
nuxt: nuxt:
specifier: workspace:* specifier: workspace:*
version: link:../../../packages/nuxt version: link:../../../packages/nuxt
vue:
specifier: 3.5.1
version: 3.5.1(typescript@5.5.4)
test/fixtures/minimal-types: test/fixtures/minimal-types:
dependencies: dependencies:
nuxt: nuxt:
specifier: workspace:* specifier: workspace:*
version: link:../../../packages/nuxt version: link:../../../packages/nuxt
vue:
specifier: 3.5.1
version: 3.5.1(typescript@5.5.4)
test/fixtures/remote-provider: {} test/fixtures/remote-provider: {}
@ -1035,44 +1005,16 @@ importers:
nuxt: nuxt:
specifier: workspace:* specifier: workspace:*
version: link:../../../packages/nuxt 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: test/fixtures/suspense:
dependencies: dependencies:
nuxt: nuxt:
specifier: workspace:* specifier: workspace:*
version: link:../../../packages/nuxt version: link:../../../packages/nuxt
vue:
specifier: 3.5.1
version: 3.5.1(typescript@5.5.4)
devDependencies: 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: typescript:
specifier: 5.5.4 specifier: 5.5.4
version: 5.5.4 version: 5.5.4
unhead:
specifier: latest
version: 1.10.4
packages: packages:
@ -5303,10 +5245,6 @@ packages:
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
engines: {node: '>=16 || 14 >=14.17'} 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: minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'} 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)': '@nuxt/eslint-plugin@0.5.5(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies: dependencies:
'@typescript-eslint/types': 8.3.0 '@typescript-eslint/types': 8.4.0
'@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: 9.9.1(jiti@1.21.6)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - 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)': '@stylistic/eslint-plugin@2.7.2(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)':
dependencies: dependencies:
'@types/eslint': 9.6.1 '@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: 9.9.1(jiti@1.21.6)
eslint-visitor-keys: 4.0.0 eslint-visitor-keys: 4.0.0
espree: 10.1.0 espree: 10.1.0
@ -8999,7 +8937,7 @@ snapshots:
debug: 4.3.6 debug: 4.3.6
fast-glob: 3.3.2 fast-glob: 3.3.2
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.4 minimatch: 9.0.5
semver: 7.6.3 semver: 7.6.3
ts-api-utils: 1.3.0(typescript@5.5.4) ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies: optionalDependencies:
@ -9525,7 +9463,7 @@ snapshots:
'@vue/compiler-vue2': 2.7.16 '@vue/compiler-vue2': 2.7.16
'@vue/shared': 3.5.1 '@vue/shared': 3.5.1
computeds: 0.0.1 computeds: 0.0.1
minimatch: 9.0.4 minimatch: 9.0.5
muggle-string: 0.4.1 muggle-string: 0.4.1
path-browserify: 1.0.1 path-browserify: 1.0.1
optionalDependencies: optionalDependencies:
@ -9538,7 +9476,7 @@ snapshots:
'@vue/compiler-vue2': 2.7.16 '@vue/compiler-vue2': 2.7.16
'@vue/shared': 3.5.1 '@vue/shared': 3.5.1
computeds: 0.0.1 computeds: 0.0.1
minimatch: 9.0.4 minimatch: 9.0.5
muggle-string: 0.4.1 muggle-string: 0.4.1
path-browserify: 1.0.1 path-browserify: 1.0.1
optionalDependencies: 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): eslint-plugin-import-x@4.1.1(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4):
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) '@typescript-eslint/typescript-estree': 8.4.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/utils': 8.4.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)
debug: 4.3.6 debug: 4.3.6
doctrine: 3.0.0 doctrine: 3.0.0
eslint: 9.9.1(jiti@1.21.6) eslint: 9.9.1(jiti@1.21.6)
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
get-tsconfig: 4.7.6 get-tsconfig: 4.7.6
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.4 minimatch: 9.0.5
semver: 7.6.3 semver: 7.6.3
stable-hash: 0.0.4 stable-hash: 0.0.4
tslib: 2.7.0 tslib: 2.7.0
@ -11162,7 +11100,7 @@ snapshots:
dependencies: dependencies:
foreground-child: 3.1.1 foreground-child: 3.1.1
jackspeak: 3.1.2 jackspeak: 3.1.2
minimatch: 9.0.4 minimatch: 9.0.5
minipass: 7.1.2 minipass: 7.1.2
path-scurry: 1.11.1 path-scurry: 1.11.1
@ -11958,7 +11896,7 @@ snapshots:
jsonc-parser: 3.2.1 jsonc-parser: 3.2.1
jsonpointer: 5.0.1 jsonpointer: 5.0.1
markdownlint: 0.34.0 markdownlint: 0.34.0
minimatch: 9.0.4 minimatch: 9.0.5
run-con: 1.3.2 run-con: 1.3.2
smol-toml: 1.2.0 smol-toml: 1.2.0
@ -12350,10 +12288,6 @@ snapshots:
dependencies: dependencies:
brace-expansion: 2.0.1 brace-expansion: 2.0.1
minimatch@9.0.4:
dependencies:
brace-expansion: 2.0.1
minimatch@9.0.5: minimatch@9.0.5:
dependencies: dependencies:
brace-expansion: 2.0.1 brace-expansion: 2.0.1
@ -13843,7 +13777,7 @@ snapshots:
dependencies: dependencies:
'@istanbuljs/schema': 0.1.3 '@istanbuljs/schema': 0.1.3
glob: 10.4.1 glob: 10.4.1
minimatch: 9.0.4 minimatch: 9.0.5
text-table@0.2.0: {} text-table@0.2.0: {}

View File

@ -9,13 +9,8 @@
"nuxt": "workspace:*" "nuxt": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@unhead/dom": "latest",
"@unhead/shared": "latest",
"@vue/devtools-api": "latest", "@vue/devtools-api": "latest",
"@vue/shared": "latest",
"iron-webcrypto": "latest",
"ufo": "latest", "ufo": "latest",
"unhead": "latest",
"unplugin": "latest", "unplugin": "latest",
"vue": "latest" "vue": "latest"
} }

View File

@ -6,7 +6,6 @@
"test:types": "nuxi prepare && npx vue-tsc --noEmit" "test:types": "nuxi prepare && npx vue-tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"nuxt": "workspace:*", "nuxt": "workspace:*"
"vue": "latest"
} }
} }

View File

@ -5,7 +5,6 @@
"build": "nuxi build" "build": "nuxi build"
}, },
"dependencies": { "dependencies": {
"nuxt": "workspace:*", "nuxt": "workspace:*"
"vue": "latest"
} }
} }

View File

@ -6,11 +6,5 @@
}, },
"dependencies": { "dependencies": {
"nuxt": "workspace:*" "nuxt": "workspace:*"
},
"devDependencies": {
"@unhead/shared": "latest",
"@vue/devtools-api": "latest",
"@vue/shared": "latest",
"unhead": "latest"
} }
} }

View File

@ -5,14 +5,9 @@
"build": "nuxi build" "build": "nuxi build"
}, },
"dependencies": { "dependencies": {
"nuxt": "workspace:*", "nuxt": "workspace:*"
"vue": "latest"
}, },
"devDependencies": { "devDependencies": {
"@unhead/shared": "latest", "typescript": "latest"
"@vue/devtools-api": "latest",
"@vue/shared": "latest",
"typescript": "latest",
"unhead": "latest"
} }
} }