mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
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
|
||||
// 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'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { join, normalize } from 'pathe'
|
||||
import { normalize } from 'pathe'
|
||||
import { interopDefault } from 'mlly'
|
||||
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 */
|
||||
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
||||
return normalize(_require.resolve(id, {
|
||||
|
25
packages/kit/src/internal/esm.ts
Normal file
25
packages/kit/src/internal/esm.ts
Normal file
@ -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 type { Nuxt } from '@nuxt/schema'
|
||||
import type { RequireModuleOptions } from '../internal/cjs'
|
||||
import { importModule, tryImportModule } from '../internal/cjs'
|
||||
import { importModule, tryImportModule } from '../internal/esm'
|
||||
import type { LoadNuxtConfigOptions } from './config'
|
||||
|
||||
export interface LoadNuxtOptions extends LoadNuxtConfigOptions {
|
||||
@ -23,8 +23,6 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||
opts.cwd = opts.cwd || opts.rootDir
|
||||
opts.overrides = opts.overrides || opts.config || {}
|
||||
|
||||
const resolveOpts: RequireModuleOptions = { paths: opts.cwd }
|
||||
|
||||
// Apply dev as config override
|
||||
opts.overrides.dev = !!opts.dev
|
||||
|
||||
@ -37,15 +35,17 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||
const pkg = await readPackageJSON(nearestNuxtPkg)
|
||||
const majorVersion = parseInt((pkg.version || '').split('.')[0])
|
||||
|
||||
const rootDir = pathToFileURL(opts.cwd || process.cwd()).href
|
||||
|
||||
// Nuxt 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)
|
||||
return nuxt
|
||||
}
|
||||
|
||||
// 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({
|
||||
rootDir: opts.cwd,
|
||||
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> {
|
||||
const resolveOpts: RequireModuleOptions = { paths: nuxt.options.rootDir }
|
||||
const rootDir = pathToFileURL(nuxt.options.rootDir).href
|
||||
|
||||
// Nuxt 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Nuxt, NuxtModule } from '@nuxt/schema'
|
||||
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'
|
||||
|
||||
/** Installs a module on a Nuxt instance. */
|
||||
@ -38,7 +39,7 @@ async function normalizeModule (nuxtModule: string | NuxtModule, inlineOptions?:
|
||||
const isESM = _src.endsWith('.mjs')
|
||||
|
||||
try {
|
||||
nuxtModule = isESM ? await importModule(_src) : requireModule(_src)
|
||||
nuxtModule = isESM ? await importModule(_src, nuxt.options.rootDir) : requireModule(_src)
|
||||
} catch (error: unknown) {
|
||||
console.error(`Error while requiring module \`${nuxtModule}\`: ${error}`)
|
||||
throw error
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { execa } from 'execa'
|
||||
import consola from 'consola'
|
||||
import { resolve } from 'pathe'
|
||||
import { tryResolveModule } from '../utils/cjs'
|
||||
import { tryResolveModule } from '../utils/esm'
|
||||
import { defineNuxtCommand } from './index'
|
||||
|
||||
const MODULE_BUILDER_PKG = '@nuxt/module-builder'
|
||||
@ -15,7 +15,7 @@ export default defineNuxtCommand({
|
||||
async invoke (args) {
|
||||
// Find local installed version
|
||||
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({
|
||||
'--stub': args.stub
|
||||
|
@ -10,7 +10,7 @@ import { setupDotenv } from 'c12'
|
||||
import { showBanner, showVersions } from '../utils/banner'
|
||||
import { writeTypes } from '../utils/prepare'
|
||||
import { loadKit } from '../utils/kit'
|
||||
import { importModule } from '../utils/cjs'
|
||||
import { importModule } from '../utils/esm'
|
||||
import { overrideEnv } from '../utils/env'
|
||||
import { writeNuxtManifest, loadNuxtManifest, cleanupNuxtDirs } from '../utils/nuxt'
|
||||
import { defineNuxtCommand } from './index'
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { execa } from 'execa'
|
||||
import { resolve } from 'pathe'
|
||||
import { tryResolveModule } from '../utils/cjs'
|
||||
import { tryResolveModule } from '../utils/esm'
|
||||
|
||||
import { loadKit } from '../utils/kit'
|
||||
import { writeTypes } from '../utils/prepare'
|
||||
@ -31,7 +31,7 @@ export default defineNuxtCommand({
|
||||
await nuxt.close()
|
||||
|
||||
// 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) {
|
||||
await execa('vue-tsc', ['--noEmit'], { preferLocal: true, stdio: 'inherit', cwd: rootDir })
|
||||
} else {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { createRequire } from 'node:module'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { normalize, dirname } from 'pathe'
|
||||
|
||||
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) }))
|
||||
}
|
||||
|
||||
export function tryResolveModule (id: string, paths?: string | string[]) {
|
||||
try {
|
||||
return resolveModule(id, paths)
|
||||
} catch { return null }
|
||||
}
|
||||
|
||||
export function requireModule (id: string, paths?: string | string[]) {
|
||||
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 }
|
||||
}
|
||||
|
||||
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[]) {
|
||||
while (dirname(id) !== id) {
|
||||
try { return requireModule(id + '/package.json', paths) } catch { }
|
||||
|
19
packages/nuxi/src/utils/esm.ts
Normal file
19
packages/nuxi/src/utils/esm.ts
Normal file
@ -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')> => {
|
||||
try {
|
||||
|
@ -67,7 +67,7 @@ export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
||||
)
|
||||
}
|
||||
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
|
||||
|
@ -165,7 +165,7 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
addComponent({
|
||||
name: 'NuxtWelcome',
|
||||
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({
|
||||
|
@ -8,7 +8,7 @@ export default defineNuxtModule({
|
||||
meta: {
|
||||
name: 'head'
|
||||
},
|
||||
setup (options, nuxt) {
|
||||
async setup (options, nuxt) {
|
||||
const runtimeDir = resolve(distDir, 'head/runtime')
|
||||
|
||||
// Transpile @unhead/vue
|
||||
@ -53,7 +53,7 @@ export default defineNuxtModule({
|
||||
// Opt-out feature allowing dependencies using @vueuse/head to work
|
||||
if (nuxt.options.experimental.polyfillVueUseHead) {
|
||||
// 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') })
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user