mirror of
https://github.com/nuxt/nuxt.git
synced 2025-03-19 16:01:24 +00:00
feat(kit,nuxt): resolve template imports from originating module (#31175)
This commit is contained in:
parent
156ab7c93c
commit
0b6c698e55
@ -1,5 +1,6 @@
|
||||
import { existsSync, promises as fsp } from 'node:fs'
|
||||
import { basename, isAbsolute, join, parse, relative, resolve } from 'pathe'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { basename, isAbsolute, join, normalize, parse, relative, resolve } from 'pathe'
|
||||
import { hash } from 'ohash'
|
||||
import type { Nuxt, NuxtServerTemplate, NuxtTemplate, NuxtTypeTemplate, ResolvedNuxtTemplate, TSReference } from '@nuxt/schema'
|
||||
import { withTrailingSlash } from 'ufo'
|
||||
@ -8,8 +9,9 @@ import type { TSConfig } from 'pkg-types'
|
||||
import { gte } from 'semver'
|
||||
import { readPackageJSON } from 'pkg-types'
|
||||
import { resolveModulePath } from 'exsolve'
|
||||
import { captureStackTrace } from 'errx'
|
||||
|
||||
import { filterInPlace } from './utils'
|
||||
import { distDirURL, filterInPlace } from './utils'
|
||||
import { directoryToURL } from './internal/esm'
|
||||
import { getDirectory } from './module/install'
|
||||
import { tryUseNuxt, useNuxt } from './context'
|
||||
@ -27,6 +29,19 @@ export function addTemplate<T> (_template: NuxtTemplate<T> | string) {
|
||||
// Remove any existing template with the same destination path
|
||||
filterInPlace(nuxt.options.build.templates, p => normalizeTemplate(p).dst !== template.dst)
|
||||
|
||||
try {
|
||||
const distDir = distDirURL.toString()
|
||||
const { source } = captureStackTrace().find(e => e.source && !e.source.startsWith(distDir)) ?? {}
|
||||
if (source) {
|
||||
const path = normalize(fileURLToPath(source))
|
||||
if (existsSync(path)) {
|
||||
template._path = path
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore errors as this is an additive feature
|
||||
}
|
||||
|
||||
// Add to templates array
|
||||
nuxt.options.build.templates.push(template)
|
||||
|
||||
|
@ -19,3 +19,5 @@ export function filterInPlace<T> (array: T[], predicate: (item: T, index: number
|
||||
}
|
||||
|
||||
export const MODE_RE = /\.(server|client)(\.\w+)*$/
|
||||
|
||||
export const distDirURL = new URL('.', import.meta.url)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { parseNodeModulePath } from 'mlly'
|
||||
import { resolveModulePath } from 'exsolve'
|
||||
import { isAbsolute, normalize } from 'pathe'
|
||||
import { isAbsolute, normalize, resolve } from 'pathe'
|
||||
import type { Plugin } from 'vite'
|
||||
import { directoryToURL, resolveAlias } from '@nuxt/kit'
|
||||
import type { Nuxt } from '@nuxt/schema'
|
||||
@ -8,6 +8,8 @@ import type { Nuxt } from '@nuxt/schema'
|
||||
import { pkgDir } from '../../dirs'
|
||||
import { logger } from '../../utils'
|
||||
|
||||
const VIRTUAL_RE = /^\0?virtual:(?:nuxt:)?/
|
||||
|
||||
export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin {
|
||||
const exclude: string[] = ['virtual:', '\0virtual:', '/__skip_vite', '@vitest/']
|
||||
let conditions: string[]
|
||||
@ -29,12 +31,24 @@ export function resolveDeepImportsPlugin (nuxt: Nuxt): Plugin {
|
||||
conditions = [...resolvedConditions]
|
||||
},
|
||||
async resolveId (id, importer) {
|
||||
if (!importer || isAbsolute(id) || (!isAbsolute(importer) && !importer.startsWith('virtual:') && !importer.startsWith('\0virtual:')) || exclude.some(e => id.startsWith(e))) {
|
||||
if (!importer || isAbsolute(id) || (!isAbsolute(importer) && !VIRTUAL_RE.test(importer)) || exclude.some(e => id.startsWith(e))) {
|
||||
return
|
||||
}
|
||||
|
||||
const normalisedId = resolveAlias(normalize(id), nuxt.options.alias)
|
||||
const normalisedImporter = importer.replace(/^\0?virtual:(?:nuxt:)?/, '')
|
||||
const isNuxtTemplate = importer.startsWith('virtual:nuxt')
|
||||
const normalisedImporter = (isNuxtTemplate ? decodeURIComponent(importer) : importer).replace(VIRTUAL_RE, '')
|
||||
|
||||
if (nuxt.options.experimental.templateImportResolution !== false && isNuxtTemplate) {
|
||||
const template = nuxt.options.build.templates.find(t => resolve(nuxt.options.buildDir, t.filename!) === normalisedImporter)
|
||||
if (template?._path) {
|
||||
const res = await this.resolve?.(normalisedId, template._path, { skipSelf: true })
|
||||
if (res !== undefined && res !== null) {
|
||||
return res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const dir = parseNodeModulePath(normalisedImporter).dir || pkgDir
|
||||
|
||||
const res = await this.resolve?.(normalisedId, dir, { skipSelf: true })
|
||||
|
@ -646,5 +646,10 @@ export default defineResolvers({
|
||||
return typeof val === 'boolean' ? val : true
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable resolving imports into Nuxt templates from the path of the module that added the template.
|
||||
*/
|
||||
templateImportResolution: true,
|
||||
},
|
||||
})
|
||||
|
@ -43,6 +43,11 @@ export interface NuxtTemplate<Options = TemplateDefaultOptions> {
|
||||
getContents?: (data: { nuxt: Nuxt, app: NuxtApp, options: Options }) => string | Promise<string>
|
||||
/** Write to filesystem */
|
||||
write?: boolean
|
||||
/**
|
||||
* The source path of the template (to try resolving dependencies from).
|
||||
* @internal
|
||||
*/
|
||||
_path?: string
|
||||
}
|
||||
|
||||
export interface NuxtServerTemplate {
|
||||
|
Loading…
Reference in New Issue
Block a user