Nuxt/packages/kit/src/utils/cjs.ts

135 lines
3.2 KiB
TypeScript
Raw Normal View History

import { join, normalize } from 'pathe'
import jiti from 'jiti'
2020-07-02 13:02:35 +00:00
// TODO: use create-require for jest environment
const _require = jiti(process.cwd())
export interface ResolveModuleOptions {
2021-04-15 19:17:44 +00:00
paths?: string | string[]
}
export interface RequireModuleOptions extends ResolveModuleOptions {
2021-04-15 18:49:29 +00:00
// 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
2021-04-15 18:49:29 +00:00
/** Automatically de-default the result of requiring the module. */
interopDefault?: boolean
}
export function isNodeModules (id: string) {
// TODO: Follow symlinks
2020-07-02 13:02:35 +00:00
return /[/\\]node_modules[/\\]/.test(id)
}
2020-07-30 23:40:16 +00:00
export function clearRequireCache (id: string) {
if (isNodeModules(id)) {
2020-07-02 13:02:35 +00:00
return
}
const entry = getRequireCacheItem(id)
if (!entry) {
delete _require.cache[id]
2020-07-02 13:02:35 +00:00
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 _require.cache[id]
2020-07-02 13:02:35 +00:00
}
2020-07-30 23:40:16 +00:00
export function scanRequireTree (id: string, files = new Set<string>()) {
if (isNodeModules(id) || files.has(id)) {
2020-07-02 13:02:35 +00:00
return files
}
const entry = getRequireCacheItem(id)
if (!entry) {
files.add(id)
return files
}
files.add(entry.id)
for (const child of entry.children) {
scanRequireTree(child.id, files)
}
return files
}
2021-04-15 18:49:29 +00:00
/** Access the require cache by module id. */
2020-07-30 23:40:16 +00:00
export function getRequireCacheItem (id: string) {
2020-07-02 13:02:35 +00:00
try {
return _require.cache[id]
2020-07-02 13:02:35 +00:00
} catch (e) {
}
}
2021-04-15 18:49:29 +00:00
/** Resolve the `package.json` file for a given module. */
export function requireModulePkg (id: string, opts: RequireModuleOptions = {}) {
return requireModule(join(id, 'package.json'), opts)
}
2021-04-15 18:49:29 +00:00
/** Resolve the path of a module. */
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
return normalize(_require.resolve(id, {
2021-04-15 19:17:44 +00:00
paths: [].concat(
// @ts-ignore
global.__NUXT_PREPATHS__,
opts.paths,
process.cwd(),
// @ts-ignore
global.__NUXT_PATHS__
).filter(Boolean)
}))
}
2021-04-15 18:49:29 +00:00
/** Try to resolve the path of a module, but don't emit an error if it can't be found. */
export function tryResolveModule (path: string, opts: ResolveModuleOptions = {}) {
2020-07-02 13:02:35 +00:00
try {
return resolveModule(path, opts)
} catch (error) {
if (error.code !== 'MODULE_NOT_FOUND') {
throw error
}
2020-07-02 13:02:35 +00:00
}
}
2021-04-15 18:49:29 +00:00
/** Require a module and return it. */
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
let requiredModule = _require(resolvedPath)
// Interop default
if (opts.interopDefault !== false && requiredModule && requiredModule.default) {
requiredModule = requiredModule.default
}
return requiredModule
}
2021-04-15 18:49:29 +00:00
/** Try to require a module, but don't emit an error if the module can't be required. */
export function tryRequireModule (id: string, opts: RequireModuleOptions = {}) {
try {
return requireModule(id, opts)
} catch (e) {
}
2020-07-02 13:02:35 +00:00
}