mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
feat(nuxt): resolve unresolved paths within node_modules
(#22478)
This commit is contained in:
parent
ffd0223583
commit
b5c9a81d68
@ -25,6 +25,10 @@ export async function installModule (moduleToInstall: string | NuxtModule, inlin
|
||||
|
||||
if (typeof moduleToInstall === 'string') {
|
||||
nuxt.options.build.transpile.push(normalizeModuleTranspilePath(moduleToInstall))
|
||||
const directory = getDirectory(moduleToInstall)
|
||||
if (directory !== moduleToInstall) {
|
||||
nuxt.options.modulesDir.push(getDirectory(moduleToInstall))
|
||||
}
|
||||
}
|
||||
|
||||
nuxt.options._installedModules = nuxt.options._installedModules || []
|
||||
@ -37,15 +41,19 @@ export async function installModule (moduleToInstall: string | NuxtModule, inlin
|
||||
|
||||
// --- Internal ---
|
||||
|
||||
export const normalizeModuleTranspilePath = (p: string) => {
|
||||
function getDirectory (p: string) {
|
||||
try {
|
||||
// we need to target directories instead of module file paths themselves
|
||||
// /home/user/project/node_modules/module/index.js -> /home/user/project/node_modules/module
|
||||
p = isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p
|
||||
return isAbsolute(p) && lstatSync(p).isFile() ? dirname(p) : p
|
||||
} catch (e) {
|
||||
// maybe the path is absolute but does not exist, allow this to bubble up
|
||||
}
|
||||
return p.split('node_modules/').pop() as string
|
||||
return p
|
||||
}
|
||||
|
||||
export const normalizeModuleTranspilePath = (p: string) => {
|
||||
return getDirectory(p).split('node_modules/').pop() as string
|
||||
}
|
||||
|
||||
export async function loadNuxtModuleInstance (nuxtModule: string | NuxtModule, nuxt: Nuxt = useNuxt()) {
|
||||
|
@ -90,7 +90,7 @@ async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
||||
)
|
||||
}
|
||||
if (!app.mainComponent) {
|
||||
app.mainComponent = (await tryResolveModule('@nuxt/ui-templates/templates/welcome.vue', nuxt.options.modulesDir))!
|
||||
app.mainComponent = (await tryResolveModule('@nuxt/ui-templates/templates/welcome.vue', nuxt.options.modulesDir)) ?? '@nuxt/ui-templates/templates/welcome.vue'
|
||||
}
|
||||
|
||||
// Resolve root component
|
||||
|
@ -25,6 +25,7 @@ import { addModuleTranspiles } from './modules'
|
||||
import { initNitro } from './nitro'
|
||||
import schemaModule from './schema'
|
||||
import { RemovePluginMetadataPlugin } from './plugins/plugin-metadata'
|
||||
import { resolveDeepImportsPlugin } from './plugins/resolve-deep-imports'
|
||||
|
||||
export function createNuxt (options: NuxtOptions): Nuxt {
|
||||
const hooks = createHooks<NuxtHooks>()
|
||||
@ -86,6 +87,9 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
addVitePlugin(() => ImportProtectionPlugin.vite(config))
|
||||
addWebpackPlugin(() => ImportProtectionPlugin.webpack(config))
|
||||
|
||||
// add resolver for modules used in virtual files
|
||||
addVitePlugin(() => resolveDeepImportsPlugin(nuxt))
|
||||
|
||||
if (nuxt.options.experimental.localLayerAliases) {
|
||||
// Add layer aliasing support for ~, ~~, @ and @@ aliases
|
||||
addVitePlugin(() => LayerAliasingPlugin.vite({
|
||||
|
30
packages/nuxt/src/core/plugins/resolve-deep-imports.ts
Normal file
30
packages/nuxt/src/core/plugins/resolve-deep-imports.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { parseNodeModulePath, resolvePath } from 'mlly'
|
||||
import { isAbsolute, normalize } from 'pathe'
|
||||
import type { Plugin } from 'vite'
|
||||
import { resolveAlias } from '@nuxt/kit'
|
||||
import type { Nuxt } from '@nuxt/schema'
|
||||
|
||||
import { pkgDir } from '../../dirs'
|
||||
|
||||
export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin {
|
||||
return {
|
||||
name: 'nuxt:resolve-bare-imports',
|
||||
enforce: 'post',
|
||||
async resolveId (id, importer, options) {
|
||||
if (!importer || isAbsolute(id) || !isAbsolute(importer) || id.startsWith('virtual:') || id.startsWith('/__skip_vite')) {
|
||||
return
|
||||
}
|
||||
id = normalize(id)
|
||||
id = resolveAlias(id, nuxt.options.alias)
|
||||
const { dir } = parseNodeModulePath(importer)
|
||||
return await this.resolve?.(id, dir || pkgDir, { skipSelf: true }) ?? await resolvePath(id, {
|
||||
url: [dir || pkgDir, ...nuxt.options.modulesDir],
|
||||
// TODO: respect nitro runtime conditions
|
||||
conditions: options.ssr ? ['node', 'import', 'require'] : ['import', 'require']
|
||||
}).catch(() => {
|
||||
console.log('[nuxt] Could not resolve id', id, importer)
|
||||
return null
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
@ -58,7 +58,13 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
}
|
||||
},
|
||||
ssr: {
|
||||
external: ['#internal/nitro', '#internal/nitro/utils', ...nitroDependencies],
|
||||
external: [
|
||||
'#internal/nitro', '#internal/nitro/utils',
|
||||
// explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build
|
||||
'unhead', '@unhead/ssr', '@unhead/vue', 'unctx', 'h3', 'devalue', '@nuxt/devalue', 'radix3', 'unstorage',
|
||||
// dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build
|
||||
...nitroDependencies
|
||||
],
|
||||
noExternal: [
|
||||
...transpile({ isServer: true, isDev: ctx.nuxt.options.dev }),
|
||||
'/__vue-jsx',
|
||||
|
@ -132,7 +132,10 @@ function createViteNodeApp (ctx: ViteBuildContext, invalidates: Set<string> = ne
|
||||
node.shouldExternalize = async (id: string) => {
|
||||
const result = await isExternal(id)
|
||||
if (result?.external) {
|
||||
return resolveModule(result.id, { url: ctx.nuxt.options.modulesDir })
|
||||
return resolveModule(result.id, {
|
||||
url: ctx.nuxt.options.modulesDir,
|
||||
conditions: ['node', 'import', 'require']
|
||||
}).catch(() => false)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user