mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 00:23:53 +00:00
refactor(kit,nuxt,vite,webpack)!: remove legacy require utils (#28008)
This commit is contained in:
parent
128edc76fc
commit
79193561b9
@ -509,6 +509,30 @@ These options have been set to their current values for some time and we do not
|
||||
|
||||
* `respectNoSSRHeader`is implementable in user-land with [server middleware](https://github.com/nuxt/nuxt/blob/c660b39447f0d5b8790c0826092638d321cd6821/packages/nuxt/src/core/runtime/nitro/no-ssr.ts#L8-L9)
|
||||
|
||||
#### Removal of Deprecated Internal CJS Utils
|
||||
|
||||
🚦 **Impact Level**: Minimal
|
||||
|
||||
##### What Changed
|
||||
|
||||
We have now removed the following utils exported from `@nuxt/kit`:
|
||||
|
||||
* `resolveModule`
|
||||
* `requireModule`
|
||||
* `importModule`
|
||||
* `tryImportModule`
|
||||
* `tryRequireModule`
|
||||
|
||||
They were previously marked as deprecated and relied on CJS resolutions.
|
||||
|
||||
##### Reasons for Change
|
||||
|
||||
We now use [jiti](https://github.com/unjs/jiti) to resolve modules and other imports internally. It supports native ESM resolution where possible and should be less buggy.
|
||||
|
||||
##### Migration Steps
|
||||
|
||||
You can use [jiti](https://github.com/unjs/jiti) or [mlly](https://github.com/unjs/mlly) to do the same job in your own projects if you were relying on these utilities.
|
||||
|
||||
## Nuxt 2 vs Nuxt 3+
|
||||
|
||||
In the table below, there is a quick comparison between 3 versions of Nuxt:
|
||||
|
7
packages/kit/index.d.ts
vendored
7
packages/kit/index.d.ts
vendored
@ -1,7 +0,0 @@
|
||||
/* eslint-disable no-var */
|
||||
declare global {
|
||||
var __NUXT_PREPATHS__: string[] | string | undefined
|
||||
var __NUXT_PATHS__: string[] | string | undefined
|
||||
}
|
||||
|
||||
export {}
|
@ -32,13 +32,4 @@ export { addTemplate, addTypeTemplate, normalizeTemplate, updateTemplates, write
|
||||
export { logger, useLogger } from './logger'
|
||||
|
||||
// Internal Utils
|
||||
// TODO
|
||||
export {
|
||||
resolveModule,
|
||||
requireModule,
|
||||
importModule,
|
||||
tryImportModule,
|
||||
tryRequireModule,
|
||||
} from './internal/cjs'
|
||||
export type { ResolveModuleOptions, RequireModuleOptions } from './internal/cjs'
|
||||
export { tryResolveModule } from './internal/esm'
|
||||
|
@ -1,121 +0,0 @@
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { normalize } from 'pathe'
|
||||
import { interopDefault } from 'mlly'
|
||||
import { createJiti } from 'jiti'
|
||||
|
||||
// TODO: use create-require for jest environment
|
||||
const jiti = createJiti(process.cwd(), { interopDefault: true })
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
export interface ResolveModuleOptions {
|
||||
paths?: string | string[]
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
export interface RequireModuleOptions extends ResolveModuleOptions {
|
||||
// TODO: use create-require for jest environment
|
||||
// native?: boolean
|
||||
/** Clear the require cache (force fresh require) but only if not within `node_modules` */
|
||||
clearCache?: boolean
|
||||
|
||||
/** Automatically de-default the result of requiring the module. */
|
||||
interopDefault?: boolean
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
function isNodeModules (id: string) {
|
||||
// TODO: Follow symlinks
|
||||
return /[/\\]node_modules[/\\]/.test(id)
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
function clearRequireCache (id: string) {
|
||||
if (isNodeModules(id)) {
|
||||
return
|
||||
}
|
||||
|
||||
const entry = getRequireCacheItem(id)
|
||||
|
||||
if (!entry) {
|
||||
delete jiti.cache[id]
|
||||
return
|
||||
}
|
||||
|
||||
if (entry.parent) {
|
||||
entry.parent.children = entry.parent.children.filter(e => e.id !== id)
|
||||
}
|
||||
|
||||
for (const child of entry.children) {
|
||||
clearRequireCache(child.id)
|
||||
}
|
||||
|
||||
delete jiti.cache[id]
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
function getRequireCacheItem (id: string) {
|
||||
try {
|
||||
return jiti.cache[id]
|
||||
} catch (e) {
|
||||
// ignore issues accessing require.cache
|
||||
}
|
||||
}
|
||||
|
||||
export function getNodeModulesPaths (paths?: string[] | string) {
|
||||
return ([] as Array<string | undefined>).concat(
|
||||
global.__NUXT_PREPATHS__,
|
||||
paths || [],
|
||||
process.cwd(),
|
||||
global.__NUXT_PATHS__,
|
||||
).filter(Boolean) as string[]
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
||||
return normalize(jiti.resolve(id, {
|
||||
paths: getNodeModulesPaths(opts.paths),
|
||||
}))
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
export function requireModule (id: string, opts: RequireModuleOptions = {}) {
|
||||
// Resolve id
|
||||
const resolvedPath = resolveModule(id, opts)
|
||||
|
||||
// Clear require cache if necessary
|
||||
if (opts.clearCache && !isNodeModules(id)) {
|
||||
clearRequireCache(resolvedPath)
|
||||
}
|
||||
|
||||
// Try to require
|
||||
const requiredModule = jiti(resolvedPath)
|
||||
|
||||
return requiredModule
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
export function importModule (id: string, opts: RequireModuleOptions = {}) {
|
||||
const resolvedPath = resolveModule(id, opts)
|
||||
if (opts.interopDefault !== false) {
|
||||
return import(pathToFileURL(resolvedPath).href).then(interopDefault)
|
||||
}
|
||||
return import(pathToFileURL(resolvedPath).href)
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
export function tryImportModule (id: string, opts: RequireModuleOptions = {}) {
|
||||
try {
|
||||
return importModule(id, opts).catch(() => undefined)
|
||||
} catch {
|
||||
// intentionally empty as this is a `try-` function
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Do not use CJS utils */
|
||||
export function tryRequireModule (id: string, opts: RequireModuleOptions = {}) {
|
||||
try {
|
||||
return requireModule(id, opts)
|
||||
} catch {
|
||||
// intentionally empty as this is a `try-` function
|
||||
}
|
||||
}
|
@ -2,10 +2,9 @@ import { existsSync, promises as fsp, lstatSync } from 'node:fs'
|
||||
import type { ModuleMeta, Nuxt, NuxtConfig, NuxtModule } from '@nuxt/schema'
|
||||
import { dirname, isAbsolute, join, resolve } from 'pathe'
|
||||
import { defu } from 'defu'
|
||||
import { createJiti } from 'jiti'
|
||||
import { useNuxt } from '../context'
|
||||
import { requireModule } from '../internal/cjs'
|
||||
import { importModule } from '../internal/esm'
|
||||
import { resolveAlias, resolvePath } from '../resolve'
|
||||
import { resolveAlias } from '../resolve'
|
||||
import { logger } from '../logger'
|
||||
|
||||
const NODE_MODULES_RE = /[/\\]node_modules[/\\]/
|
||||
@ -72,15 +71,20 @@ export const normalizeModuleTranspilePath = (p: string) => {
|
||||
|
||||
export async function loadNuxtModuleInstance (nuxtModule: string | NuxtModule, nuxt: Nuxt = useNuxt()) {
|
||||
let buildTimeModuleMeta: ModuleMeta = {}
|
||||
|
||||
const jiti = createJiti(nuxt.options.rootDir, {
|
||||
interopDefault: true,
|
||||
alias: nuxt.options.alias,
|
||||
})
|
||||
|
||||
// Import if input is string
|
||||
if (typeof nuxtModule === 'string') {
|
||||
const paths = [join(nuxtModule, 'nuxt'), join(nuxtModule, 'module'), nuxtModule]
|
||||
let error: unknown
|
||||
for (const path of paths) {
|
||||
try {
|
||||
const src = await resolvePath(path, { fallbackToOriginal: true })
|
||||
// Prefer ESM resolution if possible
|
||||
nuxtModule = await importModule(src, nuxt.options.modulesDir).catch(() => null) ?? requireModule(src, { paths: nuxt.options.modulesDir })
|
||||
const src = jiti.esmResolve(path)
|
||||
nuxtModule = await jiti.import(src) as NuxtModule
|
||||
|
||||
// nuxt-module-builder generates a module.json with metadata including the version
|
||||
const moduleMetadataPath = join(dirname(src), 'module.json')
|
||||
@ -94,7 +98,7 @@ export async function loadNuxtModuleInstance (nuxtModule: string | NuxtModule, n
|
||||
}
|
||||
}
|
||||
if (typeof nuxtModule !== 'function' && error) {
|
||||
logger.error(`Error while requiring module \`${nuxtModule}\`: ${error}`)
|
||||
logger.error(`Error while importing module \`${nuxtModule}\`: ${error}`)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import { readPackageJSON } from 'pkg-types'
|
||||
import { tryResolveModule } from './internal/esm'
|
||||
import { getDirectory } from './module/install'
|
||||
import { tryUseNuxt, useNuxt } from './context'
|
||||
import { getNodeModulesPaths } from './internal/cjs'
|
||||
import { resolveNuxtModule } from './resolve'
|
||||
|
||||
/**
|
||||
@ -266,7 +265,7 @@ export async function _generateTypes (nuxt: Nuxt) {
|
||||
await Promise.all([...nuxt.options.modules, ...nuxt.options._modules].map(async (id) => {
|
||||
if (typeof id !== 'string') { return }
|
||||
|
||||
const pkg = await readPackageJSON(id, { url: getNodeModulesPaths(nuxt.options.modulesDir) }).catch(() => null)
|
||||
const pkg = await readPackageJSON(id, { url: nuxt.options.modulesDir }).catch(() => null)
|
||||
references.push(({ types: pkg?.name || id }))
|
||||
}))
|
||||
|
||||
|
2
packages/nuxt/index.d.ts
vendored
2
packages/nuxt/index.d.ts
vendored
@ -2,8 +2,6 @@
|
||||
declare global {
|
||||
var __NUXT_VERSION__: string
|
||||
var __NUXT_ASYNC_CONTEXT__: boolean
|
||||
var __NUXT_PREPATHS__: string[] | string | undefined
|
||||
var __NUXT_PATHS__: string[] | string | undefined
|
||||
|
||||
interface Navigator {
|
||||
connection?: {
|
||||
|
@ -6,7 +6,7 @@ import { createRouter as createRadixRouter, exportMatcher, toRouteMatcher } from
|
||||
import { joinURL, withTrailingSlash } from 'ufo'
|
||||
import { build, copyPublicAssets, createDevServer, createNitro, prepare, prerender, writeTypes } from 'nitro'
|
||||
import type { Nitro, NitroConfig, NitroOptions } from 'nitro/types'
|
||||
import { findPath, logger, resolveAlias, resolveIgnorePatterns, resolveNuxtModule, resolvePath } from '@nuxt/kit'
|
||||
import { findPath, logger, resolveAlias, resolveIgnorePatterns, resolveNuxtModule } from '@nuxt/kit'
|
||||
import escapeRE from 'escape-string-regexp'
|
||||
import { defu } from 'defu'
|
||||
import { dynamicEventHandler } from 'h3'
|
||||
@ -408,7 +408,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
|
||||
})
|
||||
|
||||
const cacheDir = resolve(nuxt.options.buildDir, 'cache/nitro/prerender')
|
||||
const cacheDriverPath = await resolvePath(join(distDir, 'core/runtime/nitro/cache-driver'))
|
||||
const cacheDriverPath = join(distDir, 'core/runtime/nitro/cache-driver.js')
|
||||
await fsp.rm(cacheDir, { recursive: true, force: true }).catch(() => {})
|
||||
nitro.options._config.storage = defu(nitro.options._config.storage, {
|
||||
'internal:nuxt:prerender': {
|
||||
|
@ -1,10 +1,18 @@
|
||||
// @ts-check
|
||||
|
||||
import { defineDriver } from 'unstorage'
|
||||
import fsDriver from 'unstorage/drivers/fs-lite'
|
||||
import lruCache from 'unstorage/drivers/lru-cache'
|
||||
|
||||
const normalizeFsKey = (item: string) => item.replaceAll(':', '_')
|
||||
/**
|
||||
* @param {string} item
|
||||
*/
|
||||
const normalizeFsKey = item => item.replaceAll(':', '_')
|
||||
|
||||
export default defineDriver((opts: { base: string }) => {
|
||||
/**
|
||||
* @param {{ base: string }} opts
|
||||
*/
|
||||
export default defineDriver((opts) => {
|
||||
const fs = fsDriver({ base: opts.base })
|
||||
const lru = lruCache({ max: 1000 })
|
||||
|
@ -47,6 +47,7 @@
|
||||
"externality": "^1.0.2",
|
||||
"get-port-please": "^3.1.2",
|
||||
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
|
||||
"jiti": "^2.0.0-beta.3",
|
||||
"knitwork": "^1.1.0",
|
||||
"magic-string": "^0.30.10",
|
||||
"mlly": "^1.7.1",
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
import { requireModule, tryResolveModule } from '@nuxt/kit'
|
||||
import type { Nuxt, NuxtOptions } from '@nuxt/schema'
|
||||
import type { InlineConfig as ViteConfig } from 'vite'
|
||||
import { interopDefault } from 'mlly'
|
||||
import type { Plugin } from 'postcss'
|
||||
import { createJiti } from 'jiti'
|
||||
|
||||
function sortPlugins ({ plugins, order }: NuxtOptions['postcss']): string[] {
|
||||
const names = Object.keys(plugins)
|
||||
@ -18,27 +16,23 @@ export async function resolveCSSOptions (nuxt: Nuxt): Promise<ViteConfig['css']>
|
||||
}
|
||||
|
||||
css.postcss.plugins = []
|
||||
|
||||
const postcssOptions = nuxt.options.postcss
|
||||
|
||||
const cwd = fileURLToPath(new URL('.', import.meta.url))
|
||||
const jiti = createJiti(nuxt.options.rootDir, {
|
||||
interopDefault: true,
|
||||
alias: nuxt.options.alias,
|
||||
})
|
||||
|
||||
for (const pluginName of sortPlugins(postcssOptions)) {
|
||||
const pluginOptions = postcssOptions.plugins[pluginName]
|
||||
if (!pluginOptions) { continue }
|
||||
|
||||
const path = await tryResolveModule(pluginName, nuxt.options.modulesDir)
|
||||
|
||||
let pluginFn: (opts: Record<string, any>) => Plugin
|
||||
// TODO: use jiti v2
|
||||
if (path) {
|
||||
pluginFn = await import(pathToFileURL(path).href).then(interopDefault)
|
||||
} else {
|
||||
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`)
|
||||
// fall back to cjs
|
||||
pluginFn = requireModule(pluginName, { paths: [cwd] })
|
||||
}
|
||||
const path = jiti.esmResolve(pluginName)
|
||||
const pluginFn = (await jiti.import(path)) as (opts: Record<string, any>) => Plugin
|
||||
if (typeof pluginFn === 'function') {
|
||||
css.postcss.plugins.push(pluginFn(pluginOptions))
|
||||
} else {
|
||||
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\`. Please report this as a bug.`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
"globby": "^14.0.2",
|
||||
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
|
||||
"hash-sum": "^2.0.0",
|
||||
"jiti": "^2.0.0-beta.3",
|
||||
"knitwork": "^1.1.0",
|
||||
"lodash-es": "4.17.21",
|
||||
"magic-string": "^0.30.10",
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
import createResolver from 'postcss-import-resolver'
|
||||
import { interopDefault } from 'mlly'
|
||||
import { requireModule, tryResolveModule } from '@nuxt/kit'
|
||||
import type { Nuxt, NuxtOptions } from '@nuxt/schema'
|
||||
import { defu } from 'defu'
|
||||
import { createJiti } from 'jiti'
|
||||
import type { Plugin } from 'postcss'
|
||||
|
||||
const isPureObject = (obj: unknown): obj is Object => obj !== null && !Array.isArray(obj) && typeof obj === 'object'
|
||||
@ -38,28 +36,25 @@ export async function getPostcssConfig (nuxt: Nuxt) {
|
||||
sourceMap: nuxt.options.webpack.cssSourceMap,
|
||||
})
|
||||
|
||||
const jiti = createJiti(nuxt.options.rootDir, {
|
||||
interopDefault: true,
|
||||
alias: nuxt.options.alias,
|
||||
})
|
||||
|
||||
// Keep the order of default plugins
|
||||
if (!Array.isArray(postcssOptions.plugins) && isPureObject(postcssOptions.plugins)) {
|
||||
// Map postcss plugins into instances on object mode once
|
||||
const cwd = fileURLToPath(new URL('.', import.meta.url))
|
||||
const plugins: Plugin[] = []
|
||||
for (const pluginName of sortPlugins(postcssOptions)) {
|
||||
const pluginOptions = postcssOptions.plugins[pluginName]
|
||||
if (!pluginOptions) { continue }
|
||||
|
||||
const path = await tryResolveModule(pluginName, nuxt.options.modulesDir)
|
||||
|
||||
let pluginFn: (opts: Record<string, any>) => Plugin
|
||||
// TODO: use jiti v2
|
||||
if (path) {
|
||||
pluginFn = await import(pathToFileURL(path).href).then(interopDefault)
|
||||
} else {
|
||||
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`)
|
||||
// fall back to cjs
|
||||
pluginFn = requireModule(pluginName, { paths: [cwd] })
|
||||
}
|
||||
const path = jiti.esmResolve(pluginName)
|
||||
const pluginFn = (await jiti.import(path)) as (opts: Record<string, any>) => Plugin
|
||||
if (typeof pluginFn === 'function') {
|
||||
plugins.push(pluginFn(pluginOptions))
|
||||
} else {
|
||||
console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\`. Please report this as a bug.`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -670,6 +670,9 @@ importers:
|
||||
h3:
|
||||
specifier: npm:h3-nightly@2.0.0-1718872656.6765a6e
|
||||
version: h3-nightly@2.0.0-1718872656.6765a6e
|
||||
jiti:
|
||||
specifier: 2.0.0-beta.3
|
||||
version: 2.0.0-beta.3
|
||||
knitwork:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
@ -791,6 +794,9 @@ importers:
|
||||
hash-sum:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
jiti:
|
||||
specifier: 2.0.0-beta.3
|
||||
version: 2.0.0-beta.3
|
||||
knitwork:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
|
Loading…
Reference in New Issue
Block a user