mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-14 01:53:55 +00:00
feat(kit): handle virtual files in resolvePath
and findPath
(#26465)
This commit is contained in:
parent
d5e2080cd1
commit
3e610df4dd
31
packages/kit/src/resolve.test.ts
Normal file
31
packages/kit/src/resolve.test.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
import { resolve } from 'pathe'
|
||||||
|
import { loadNuxt } from './loader/nuxt'
|
||||||
|
import { findPath, resolvePath } from './resolve'
|
||||||
|
import { defineNuxtModule } from './module/define'
|
||||||
|
import { addTemplate } from './template'
|
||||||
|
|
||||||
|
const nuxt = await loadNuxt({
|
||||||
|
overrides: {
|
||||||
|
modules: [
|
||||||
|
defineNuxtModule(() => {
|
||||||
|
addTemplate({
|
||||||
|
filename: 'my-template.mjs',
|
||||||
|
getContents: () => 'export const myUtil = () => \'hello\'',
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('resolvePath', () => {
|
||||||
|
it('should resolve paths correctly', async () => {
|
||||||
|
expect(await resolvePath('.nuxt/app.config')).toBe(resolve(nuxt.options.buildDir, 'app.config'))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('findPath', () => {
|
||||||
|
it('should find paths correctly', async () => {
|
||||||
|
expect(await findPath(resolve(nuxt.options.buildDir, 'my-template'), { virtual: true })).toBe(resolve(nuxt.options.buildDir, 'my-template.mjs'))
|
||||||
|
})
|
||||||
|
})
|
@ -17,6 +17,12 @@ export interface ResolvePathOptions {
|
|||||||
|
|
||||||
/** The file extensions to try. Default is Nuxt configured extensions. */
|
/** The file extensions to try. Default is Nuxt configured extensions. */
|
||||||
extensions?: string[]
|
extensions?: string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to resolve files that exist in the Nuxt VFS (for example, as a Nuxt template).
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
virtual?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,9 +36,14 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}):
|
|||||||
path = normalize(path)
|
path = normalize(path)
|
||||||
|
|
||||||
// Fast return if the path exists
|
// Fast return if the path exists
|
||||||
if (isAbsolute(path) && existsSync(path) && !(await isDirectory(path))) {
|
if (isAbsolute(path)) {
|
||||||
|
if (opts?.virtual && existsInVFS(path)) {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
if (existsSync(path) && !(await isDirectory(path))) {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Use current nuxt options
|
// Use current nuxt options
|
||||||
const nuxt = tryUseNuxt()
|
const nuxt = tryUseNuxt()
|
||||||
@ -49,6 +60,10 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}):
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if resolvedPath is a file
|
// Check if resolvedPath is a file
|
||||||
|
if (opts?.virtual && existsInVFS(path, nuxt)) {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
let _isDir = false
|
let _isDir = false
|
||||||
if (existsSync(path)) {
|
if (existsSync(path)) {
|
||||||
_isDir = await isDirectory(path)
|
_isDir = await isDirectory(path)
|
||||||
@ -61,11 +76,17 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}):
|
|||||||
for (const ext of extensions) {
|
for (const ext of extensions) {
|
||||||
// path.[ext]
|
// path.[ext]
|
||||||
const pathWithExt = path + ext
|
const pathWithExt = path + ext
|
||||||
|
if (opts?.virtual && existsInVFS(pathWithExt, nuxt)) {
|
||||||
|
return pathWithExt
|
||||||
|
}
|
||||||
if (existsSync(pathWithExt)) {
|
if (existsSync(pathWithExt)) {
|
||||||
return pathWithExt
|
return pathWithExt
|
||||||
}
|
}
|
||||||
// path/index.[ext]
|
// path/index.[ext]
|
||||||
const pathWithIndex = join(path, 'index' + ext)
|
const pathWithIndex = join(path, 'index' + ext)
|
||||||
|
if (opts?.virtual && existsInVFS(pathWithIndex, nuxt)) {
|
||||||
|
return pathWithIndex
|
||||||
|
}
|
||||||
if (_isDir && existsSync(pathWithIndex)) {
|
if (_isDir && existsSync(pathWithIndex)) {
|
||||||
return pathWithIndex
|
return pathWithIndex
|
||||||
}
|
}
|
||||||
@ -85,8 +106,17 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}):
|
|||||||
* Try to resolve first existing file in paths
|
* Try to resolve first existing file in paths
|
||||||
*/
|
*/
|
||||||
export async function findPath (paths: string | string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise<string | null> {
|
export async function findPath (paths: string | string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise<string | null> {
|
||||||
|
const nuxt = opts?.virtual ? tryUseNuxt() : undefined
|
||||||
|
|
||||||
for (const path of toArray(paths)) {
|
for (const path of toArray(paths)) {
|
||||||
const rPath = await resolvePath(path, opts)
|
const rPath = await resolvePath(path, opts)
|
||||||
|
|
||||||
|
// Check VFS
|
||||||
|
if (opts?.virtual && existsInVFS(rPath, nuxt)) {
|
||||||
|
return rPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check file system
|
||||||
if (await existsSensitive(rPath)) {
|
if (await existsSensitive(rPath)) {
|
||||||
const _isDir = await isDirectory(rPath)
|
const _isDir = await isDirectory(rPath)
|
||||||
if (!pathType || (pathType === 'file' && !_isDir) || (pathType === 'dir' && _isDir)) {
|
if (!pathType || (pathType === 'file' && !_isDir) || (pathType === 'dir' && _isDir)) {
|
||||||
@ -160,6 +190,17 @@ async function isDirectory (path: string) {
|
|||||||
return (await fsp.lstat(path)).isDirectory()
|
return (await fsp.lstat(path)).isDirectory()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function existsInVFS (path: string, nuxt = tryUseNuxt()) {
|
||||||
|
if (!nuxt) { return false }
|
||||||
|
|
||||||
|
if (path in nuxt.vfs) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const templates = nuxt.apps.default?.templates ?? nuxt.options.build.templates
|
||||||
|
return templates.some(template => template.dst === path)
|
||||||
|
}
|
||||||
|
|
||||||
export async function resolveFiles (path: string, pattern: string | string[], opts: { followSymbolicLinks?: boolean } = {}) {
|
export async function resolveFiles (path: string, pattern: string | string[], opts: { followSymbolicLinks?: boolean } = {}) {
|
||||||
const files = await globby(pattern, { cwd: path, followSymbolicLinks: opts.followSymbolicLinks ?? true })
|
const files = await globby(pattern, { cwd: path, followSymbolicLinks: opts.followSymbolicLinks ?? true })
|
||||||
return files.map(p => resolve(path, p)).filter(p => !isIgnored(p)).sort()
|
return files.map(p => resolve(path, p)).filter(p => !isIgnored(p)).sort()
|
||||||
|
Loading…
Reference in New Issue
Block a user