mirror of https://github.com/nuxt/nuxt.git
refactor(kit,nuxi): resolve module paths using node algorithm (#19537)
This commit is contained in:
parent
f7a5cf07b5
commit
6d79b71588
|
@ -24,5 +24,13 @@ export * from './logger'
|
||||||
|
|
||||||
// Internal Utils
|
// Internal Utils
|
||||||
// TODO
|
// TODO
|
||||||
export * from './internal/cjs'
|
export {
|
||||||
|
resolveModule,
|
||||||
|
requireModule,
|
||||||
|
importModule,
|
||||||
|
tryImportModule,
|
||||||
|
tryRequireModule
|
||||||
|
} from './internal/cjs'
|
||||||
|
export type { ResolveModuleOptions, RequireModuleOptions } from './internal/cjs'
|
||||||
|
export { tryResolveModule } from './internal/esm'
|
||||||
export * from './internal/template'
|
export * from './internal/template'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { pathToFileURL } from 'node:url'
|
import { pathToFileURL } from 'node:url'
|
||||||
import { join, normalize } from 'pathe'
|
import { normalize } from 'pathe'
|
||||||
import { interopDefault } from 'mlly'
|
import { interopDefault } from 'mlly'
|
||||||
import jiti from 'jiti'
|
import jiti from 'jiti'
|
||||||
|
|
||||||
|
@ -82,11 +82,6 @@ export function getRequireCacheItem (id: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve the `package.json` file for a given module. */
|
|
||||||
export function requireModulePkg (id: string, opts: RequireModuleOptions = {}) {
|
|
||||||
return requireModule(join(id, 'package.json'), opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated Do not use CJS utils */
|
/** @deprecated Do not use CJS utils */
|
||||||
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
||||||
return normalize(_require.resolve(id, {
|
return normalize(_require.resolve(id, {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { pathToFileURL } from 'node:url'
|
||||||
|
import { interopDefault, resolvePath } from 'mlly'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a module from a given root path using an algorithm patterned on
|
||||||
|
* the upcoming `import.meta.resolve`. It returns a file URL
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function tryResolveModule (id: string, url = import.meta.url) {
|
||||||
|
try {
|
||||||
|
return await resolvePath(id, { url })
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function importModule (id: string, url = import.meta.url) {
|
||||||
|
const resolvedPath = await resolvePath(id, { url })
|
||||||
|
return import(pathToFileURL(resolvedPath).href).then(interopDefault)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tryImportModule (id: string, url = import.meta.url) {
|
||||||
|
try {
|
||||||
|
return importModule(id, url).catch(() => undefined)
|
||||||
|
} catch { }
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
|
import { pathToFileURL } from 'node:url'
|
||||||
import { readPackageJSON, resolvePackageJSON } from 'pkg-types'
|
import { readPackageJSON, resolvePackageJSON } from 'pkg-types'
|
||||||
import type { Nuxt } from '@nuxt/schema'
|
import type { Nuxt } from '@nuxt/schema'
|
||||||
import type { RequireModuleOptions } from '../internal/cjs'
|
import { importModule, tryImportModule } from '../internal/esm'
|
||||||
import { importModule, tryImportModule } from '../internal/cjs'
|
|
||||||
import type { LoadNuxtConfigOptions } from './config'
|
import type { LoadNuxtConfigOptions } from './config'
|
||||||
|
|
||||||
export interface LoadNuxtOptions extends LoadNuxtConfigOptions {
|
export interface LoadNuxtOptions extends LoadNuxtConfigOptions {
|
||||||
|
@ -23,8 +23,6 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||||
opts.cwd = opts.cwd || opts.rootDir
|
opts.cwd = opts.cwd || opts.rootDir
|
||||||
opts.overrides = opts.overrides || opts.config || {}
|
opts.overrides = opts.overrides || opts.config || {}
|
||||||
|
|
||||||
const resolveOpts: RequireModuleOptions = { paths: opts.cwd }
|
|
||||||
|
|
||||||
// Apply dev as config override
|
// Apply dev as config override
|
||||||
opts.overrides.dev = !!opts.dev
|
opts.overrides.dev = !!opts.dev
|
||||||
|
|
||||||
|
@ -37,15 +35,17 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||||
const pkg = await readPackageJSON(nearestNuxtPkg)
|
const pkg = await readPackageJSON(nearestNuxtPkg)
|
||||||
const majorVersion = parseInt((pkg.version || '').split('.')[0])
|
const majorVersion = parseInt((pkg.version || '').split('.')[0])
|
||||||
|
|
||||||
|
const rootDir = pathToFileURL(opts.cwd || process.cwd()).href
|
||||||
|
|
||||||
// Nuxt 3
|
// Nuxt 3
|
||||||
if (majorVersion === 3) {
|
if (majorVersion === 3) {
|
||||||
const { loadNuxt } = await importModule((pkg as any)._name || pkg.name, resolveOpts)
|
const { loadNuxt } = await importModule((pkg as any)._name || pkg.name, rootDir)
|
||||||
const nuxt = await loadNuxt(opts)
|
const nuxt = await loadNuxt(opts)
|
||||||
return nuxt
|
return nuxt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nuxt 2
|
// Nuxt 2
|
||||||
const { loadNuxt } = await tryImportModule('nuxt-edge', resolveOpts) || await importModule('nuxt', resolveOpts)
|
const { loadNuxt } = await tryImportModule('nuxt-edge', rootDir) || await importModule('nuxt', rootDir)
|
||||||
const nuxt = await loadNuxt({
|
const nuxt = await loadNuxt({
|
||||||
rootDir: opts.cwd,
|
rootDir: opts.cwd,
|
||||||
for: opts.dev ? 'dev' : 'build',
|
for: opts.dev ? 'dev' : 'build',
|
||||||
|
@ -58,15 +58,15 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function buildNuxt (nuxt: Nuxt): Promise<any> {
|
export async function buildNuxt (nuxt: Nuxt): Promise<any> {
|
||||||
const resolveOpts: RequireModuleOptions = { paths: nuxt.options.rootDir }
|
const rootDir = pathToFileURL(nuxt.options.rootDir).href
|
||||||
|
|
||||||
// Nuxt 3
|
// Nuxt 3
|
||||||
if (nuxt.options._majorVersion === 3) {
|
if (nuxt.options._majorVersion === 3) {
|
||||||
const { build } = await tryImportModule('nuxt3', resolveOpts) || await importModule('nuxt', resolveOpts)
|
const { build } = await tryImportModule('nuxt3', rootDir) || await importModule('nuxt', rootDir)
|
||||||
return build(nuxt)
|
return build(nuxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nuxt 2
|
// Nuxt 2
|
||||||
const { build } = await tryImportModule('nuxt-edge', resolveOpts) || await importModule('nuxt', resolveOpts)
|
const { build } = await tryImportModule('nuxt-edge', rootDir) || await importModule('nuxt', rootDir)
|
||||||
return build(nuxt)
|
return build(nuxt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import type { Nuxt, NuxtModule } from '@nuxt/schema'
|
import type { Nuxt, NuxtModule } from '@nuxt/schema'
|
||||||
import { useNuxt } from '../context'
|
import { useNuxt } from '../context'
|
||||||
import { resolveModule, requireModule, importModule } from '../internal/cjs'
|
import { resolveModule, requireModule } from '../internal/cjs'
|
||||||
|
import { importModule } from '../internal/esm'
|
||||||
import { resolveAlias } from '../resolve'
|
import { resolveAlias } from '../resolve'
|
||||||
|
|
||||||
/** Installs a module on a Nuxt instance. */
|
/** Installs a module on a Nuxt instance. */
|
||||||
|
@ -38,7 +39,7 @@ async function normalizeModule (nuxtModule: string | NuxtModule, inlineOptions?:
|
||||||
const isESM = _src.endsWith('.mjs')
|
const isESM = _src.endsWith('.mjs')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
nuxtModule = isESM ? await importModule(_src) : requireModule(_src)
|
nuxtModule = isESM ? await importModule(_src, nuxt.options.rootDir) : requireModule(_src)
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
console.error(`Error while requiring module \`${nuxtModule}\`: ${error}`)
|
console.error(`Error while requiring module \`${nuxtModule}\`: ${error}`)
|
||||||
throw error
|
throw error
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { execa } from 'execa'
|
import { execa } from 'execa'
|
||||||
import consola from 'consola'
|
import consola from 'consola'
|
||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { tryResolveModule } from '../utils/cjs'
|
import { tryResolveModule } from '../utils/esm'
|
||||||
import { defineNuxtCommand } from './index'
|
import { defineNuxtCommand } from './index'
|
||||||
|
|
||||||
const MODULE_BUILDER_PKG = '@nuxt/module-builder'
|
const MODULE_BUILDER_PKG = '@nuxt/module-builder'
|
||||||
|
@ -15,7 +15,7 @@ export default defineNuxtCommand({
|
||||||
async invoke (args) {
|
async invoke (args) {
|
||||||
// Find local installed version
|
// Find local installed version
|
||||||
const rootDir = resolve(args._[0] || '.')
|
const rootDir = resolve(args._[0] || '.')
|
||||||
const hasLocal = tryResolveModule(`${MODULE_BUILDER_PKG}/package.json`, rootDir)
|
const hasLocal = await tryResolveModule(`${MODULE_BUILDER_PKG}/package.json`, rootDir)
|
||||||
|
|
||||||
const execArgs = Object.entries({
|
const execArgs = Object.entries({
|
||||||
'--stub': args.stub
|
'--stub': args.stub
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { setupDotenv } from 'c12'
|
||||||
import { showBanner, showVersions } from '../utils/banner'
|
import { showBanner, showVersions } from '../utils/banner'
|
||||||
import { writeTypes } from '../utils/prepare'
|
import { writeTypes } from '../utils/prepare'
|
||||||
import { loadKit } from '../utils/kit'
|
import { loadKit } from '../utils/kit'
|
||||||
import { importModule } from '../utils/cjs'
|
import { importModule } from '../utils/esm'
|
||||||
import { overrideEnv } from '../utils/env'
|
import { overrideEnv } from '../utils/env'
|
||||||
import { writeNuxtManifest, loadNuxtManifest, cleanupNuxtDirs } from '../utils/nuxt'
|
import { writeNuxtManifest, loadNuxtManifest, cleanupNuxtDirs } from '../utils/nuxt'
|
||||||
import { defineNuxtCommand } from './index'
|
import { defineNuxtCommand } from './index'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { execa } from 'execa'
|
import { execa } from 'execa'
|
||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { tryResolveModule } from '../utils/cjs'
|
import { tryResolveModule } from '../utils/esm'
|
||||||
|
|
||||||
import { loadKit } from '../utils/kit'
|
import { loadKit } from '../utils/kit'
|
||||||
import { writeTypes } from '../utils/prepare'
|
import { writeTypes } from '../utils/prepare'
|
||||||
|
@ -31,7 +31,7 @@ export default defineNuxtCommand({
|
||||||
await nuxt.close()
|
await nuxt.close()
|
||||||
|
|
||||||
// Prefer local install if possible
|
// Prefer local install if possible
|
||||||
const hasLocalInstall = tryResolveModule('typescript', rootDir) && tryResolveModule('vue-tsc/package.json', rootDir)
|
const hasLocalInstall = await tryResolveModule('typescript', rootDir) && await tryResolveModule('vue-tsc/package.json', rootDir)
|
||||||
if (hasLocalInstall) {
|
if (hasLocalInstall) {
|
||||||
await execa('vue-tsc', ['--noEmit'], { preferLocal: true, stdio: 'inherit', cwd: rootDir })
|
await execa('vue-tsc', ['--noEmit'], { preferLocal: true, stdio: 'inherit', cwd: rootDir })
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { createRequire } from 'node:module'
|
import { createRequire } from 'node:module'
|
||||||
import { pathToFileURL } from 'node:url'
|
|
||||||
import { normalize, dirname } from 'pathe'
|
import { normalize, dirname } from 'pathe'
|
||||||
|
|
||||||
export function getModulePaths (paths?: string | string[]): string[] {
|
export function getModulePaths (paths?: string | string[]): string[] {
|
||||||
|
@ -21,12 +20,6 @@ export function resolveModule (id: string, paths?: string | string[]) {
|
||||||
return normalize(_require.resolve(id, { paths: getModulePaths(paths) }))
|
return normalize(_require.resolve(id, { paths: getModulePaths(paths) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tryResolveModule (id: string, paths?: string | string[]) {
|
|
||||||
try {
|
|
||||||
return resolveModule(id, paths)
|
|
||||||
} catch { return null }
|
|
||||||
}
|
|
||||||
|
|
||||||
export function requireModule (id: string, paths?: string | string[]) {
|
export function requireModule (id: string, paths?: string | string[]) {
|
||||||
return _require(resolveModule(id, paths))
|
return _require(resolveModule(id, paths))
|
||||||
}
|
}
|
||||||
|
@ -35,11 +28,6 @@ export function tryRequireModule (id: string, paths?: string | string[]) {
|
||||||
try { return requireModule(id, paths) } catch { return null }
|
try { return requireModule(id, paths) } catch { return null }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importModule (id: string, paths?: string | string[]) {
|
|
||||||
const resolvedPath = resolveModule(id, paths)
|
|
||||||
return import(pathToFileURL(resolvedPath).href)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getNearestPackage (id: string, paths?: string | string[]) {
|
export function getNearestPackage (id: string, paths?: string | string[]) {
|
||||||
while (dirname(id) !== id) {
|
while (dirname(id) !== id) {
|
||||||
try { return requireModule(id + '/package.json', paths) } catch { }
|
try { return requireModule(id + '/package.json', paths) } catch { }
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { pathToFileURL } from 'node:url'
|
||||||
|
import { interopDefault, resolvePath } from 'mlly'
|
||||||
|
|
||||||
|
export async function tryResolveModule (id: string, url = import.meta.url) {
|
||||||
|
try {
|
||||||
|
return await resolvePath(id, { url })
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function importModule (id: string, url = import.meta.url) {
|
||||||
|
const resolvedPath = await resolvePath(id, { url })
|
||||||
|
return import(pathToFileURL(resolvedPath).href).then(interopDefault)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tryImportModule (id: string, url = import.meta.url) {
|
||||||
|
try {
|
||||||
|
return importModule(id, url).catch(() => undefined)
|
||||||
|
} catch { }
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { importModule } from './cjs'
|
import { importModule } from './esm'
|
||||||
|
|
||||||
export const loadKit = async (rootDir: string): Promise<typeof import('@nuxt/kit')> => {
|
export const loadKit = async (rootDir: string): Promise<typeof import('@nuxt/kit')> => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -67,7 +67,7 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!app.mainComponent) {
|
if (!app.mainComponent) {
|
||||||
app.mainComponent = tryResolveModule('@nuxt/ui-templates/templates/welcome.vue')
|
app.mainComponent = (await tryResolveModule('@nuxt/ui-templates/templates/welcome.vue'))!
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve root component
|
// Resolve root component
|
||||||
|
|
|
@ -165,7 +165,7 @@ async function initNuxt (nuxt: Nuxt) {
|
||||||
addComponent({
|
addComponent({
|
||||||
name: 'NuxtWelcome',
|
name: 'NuxtWelcome',
|
||||||
priority: 10, // built-in that we do not expect the user to override
|
priority: 10, // built-in that we do not expect the user to override
|
||||||
filePath: tryResolveModule('@nuxt/ui-templates/templates/welcome.vue')!
|
filePath: (await tryResolveModule('@nuxt/ui-templates/templates/welcome.vue'))!
|
||||||
})
|
})
|
||||||
|
|
||||||
addComponent({
|
addComponent({
|
||||||
|
|
|
@ -8,7 +8,7 @@ export default defineNuxtModule({
|
||||||
meta: {
|
meta: {
|
||||||
name: 'head'
|
name: 'head'
|
||||||
},
|
},
|
||||||
setup (options, nuxt) {
|
async setup (options, nuxt) {
|
||||||
const runtimeDir = resolve(distDir, 'head/runtime')
|
const runtimeDir = resolve(distDir, 'head/runtime')
|
||||||
|
|
||||||
// Transpile @unhead/vue
|
// Transpile @unhead/vue
|
||||||
|
@ -53,7 +53,7 @@ export default defineNuxtModule({
|
||||||
// Opt-out feature allowing dependencies using @vueuse/head to work
|
// Opt-out feature allowing dependencies using @vueuse/head to work
|
||||||
if (nuxt.options.experimental.polyfillVueUseHead) {
|
if (nuxt.options.experimental.polyfillVueUseHead) {
|
||||||
// backwards compatibility
|
// backwards compatibility
|
||||||
nuxt.options.alias['@vueuse/head'] = tryResolveModule('@unhead/vue') || '@unhead/vue'
|
nuxt.options.alias['@vueuse/head'] = await tryResolveModule('@unhead/vue') || '@unhead/vue'
|
||||||
addPlugin({ src: resolve(runtimeDir, 'plugins/vueuse-head-polyfill') })
|
addPlugin({ src: resolve(runtimeDir, 'plugins/vueuse-head-polyfill') })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue