You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1075 lines
30 KiB

import path, { dirname, resolve, extname, normalize, sep } from 'path';
import builtinList from 'builtin-modules';
import deepMerge from 'deepmerge';
import isModule from 'is-module';
import fs, { realpathSync } from 'fs';
import { promisify } from 'util';
import { pathToFileURL, fileURLToPath } from 'url';
import resolve$1 from 'resolve';
import { createFilter } from '@rollup/pluginutils';
const access = promisify(fs.access);
const readFile = promisify(fs.readFile);
const realpath = promisify(fs.realpath);
const stat = promisify(fs.stat);
async function exists(filePath) {
try {
await access(filePath);
return true;
} catch {
return false;
}
}
const onError = (error) => {
if (error.code === 'ENOENT') {
return false;
}
throw error;
};
const makeCache = (fn) => {
const cache = new Map();
const wrapped = async (param, done) => {
if (cache.has(param) === false) {
cache.set(
param,
fn(param).catch((err) => {
cache.delete(param);
throw err;
})
);
}
try {
const result = cache.get(param);
const value = await result;
return done(null, value);
} catch (error) {
return done(error);
}
};
wrapped.clear = () => cache.clear();
return wrapped;
};
const isDirCached = makeCache(async (file) => {
try {
const stats = await stat(file);
return stats.isDirectory();
} catch (error) {
return onError(error);
}
});
const isFileCached = makeCache(async (file) => {
try {
const stats = await stat(file);
return stats.isFile();
} catch (error) {
return onError(error);
}
});
const readCachedFile = makeCache(readFile);
// returns the imported package name for bare module imports
function getPackageName(id) {
if (id.startsWith('.') || id.startsWith('/')) {
return null;
}
const split = id.split('/');
// @my-scope/my-package/foo.js -> @my-scope/my-package
// @my-scope/my-package -> @my-scope/my-package
if (split[0][0] === '@') {
return `${split[0]}/${split[1]}`;
}
// my-package/foo.js -> my-package
// my-package -> my-package
return split[0];
}
function getMainFields(options) {
let mainFields;
if (options.mainFields) {
({ mainFields } = options);
} else {
mainFields = ['module', 'main'];
}
if (options.browser && mainFields.indexOf('browser') === -1) {
return ['browser'].concat(mainFields);
}
if (!mainFields.length) {
throw new Error('Please ensure at least one `mainFields` value is specified');
}
return mainFields;
}
function getPackageInfo(options) {
const {
cache,
extensions,
pkg,
mainFields,
preserveSymlinks,
useBrowserOverrides,
rootDir,
ignoreSideEffectsForRoot
} = options;
let { pkgPath } = options;
if (cache.has(pkgPath)) {
return cache.get(pkgPath);
}
// browserify/resolve doesn't realpath paths returned in its packageFilter callback
if (!preserveSymlinks) {
pkgPath = realpathSync(pkgPath);
}
const pkgRoot = dirname(pkgPath);
const packageInfo = {
// copy as we are about to munge the `main` field of `pkg`.
packageJson: { ...pkg },
// path to package.json file
packageJsonPath: pkgPath,
// directory containing the package.json
root: pkgRoot,
// which main field was used during resolution of this module (main, module, or browser)
resolvedMainField: 'main',
// whether the browser map was used to resolve the entry point to this module
browserMappedMain: false,
// the entry point of the module with respect to the selected main field and any
// relevant browser mappings.
resolvedEntryPoint: ''
};
let overriddenMain = false;
for (let i = 0; i < mainFields.length; i++) {
const field = mainFields[i];
if (typeof pkg[field] === 'string') {
pkg.main = pkg[field];
packageInfo.resolvedMainField = field;
overriddenMain = true;
break;
}
}
const internalPackageInfo = {
cachedPkg: pkg,
hasModuleSideEffects: () => null,
hasPackageEntry: overriddenMain !== false || mainFields.indexOf('main') !== -1,
packageBrowserField:
useBrowserOverrides &&
typeof pkg.browser === 'object' &&
Object.keys(pkg.browser).reduce((browser, key) => {
let resolved = pkg.browser[key];
if (resolved && resolved[0] === '.') {
resolved = resolve(pkgRoot, resolved);
}
/* eslint-disable no-param-reassign */
browser[key] = resolved;
if (key[0] === '.') {
const absoluteKey = resolve(pkgRoot, key);
browser[absoluteKey] = resolved;
if (!extname(key)) {
extensions.reduce((subBrowser, ext) => {
subBrowser[absoluteKey + ext] = subBrowser[key];
return subBrowser;
}, browser);
}
}
return browser;
}, {}),
packageInfo
};
const browserMap = internalPackageInfo.packageBrowserField;
if (
useBrowserOverrides &&
typeof pkg.browser === 'object' &&
// eslint-disable-next-line no-prototype-builtins
browserMap.hasOwnProperty(pkg.main)
) {
packageInfo.resolvedEntryPoint = browserMap[pkg.main];
packageInfo.browserMappedMain = true;
} else {
// index.node is technically a valid default entrypoint as well...
packageInfo.resolvedEntryPoint = resolve(pkgRoot, pkg.main || 'index.js');
packageInfo.browserMappedMain = false;
}
if (!ignoreSideEffectsForRoot || rootDir !== pkgRoot) {
const packageSideEffects = pkg.sideEffects;
if (typeof packageSideEffects === 'boolean') {
internalPackageInfo.hasModuleSideEffects = () => packageSideEffects;
} else if (Array.isArray(packageSideEffects)) {
internalPackageInfo.hasModuleSideEffects = createFilter(packageSideEffects, null, {
resolve: pkgRoot
});
}
}
cache.set(pkgPath, internalPackageInfo);
return internalPackageInfo;
}
function normalizeInput(input) {
if (Array.isArray(input)) {
return input;
} else if (typeof input === 'object') {
return Object.values(input);
}
// otherwise it's a string
return [input];
}
/* eslint-disable no-await-in-loop */
const fileExists = promisify(fs.exists);
function isModuleDir(current, moduleDirs) {
return moduleDirs.some((dir) => current.endsWith(dir));
}
async function findPackageJson(base, moduleDirs) {
const { root } = path.parse(base);
let current = base;
while (current !== root && !isModuleDir(current, moduleDirs)) {
const pkgJsonPath = path.join(current, 'package.json');
if (await fileExists(pkgJsonPath)) {
const pkgJsonString = fs.readFileSync(pkgJsonPath, 'utf-8');
return { pkgJson: JSON.parse(pkgJsonString), pkgPath: current, pkgJsonPath };
}
current = path.resolve(current, '..');
}
return null;
}
function isUrl(str) {
try {
return !!new URL(str);
} catch (_) {
return false;
}
}
function isConditions(exports) {
return typeof exports === 'object' && Object.keys(exports).every((k) => !k.startsWith('.'));
}
function isMappings(exports) {
return typeof exports === 'object' && !isConditions(exports);
}
function isMixedExports(exports) {
const keys = Object.keys(exports);
return keys.some((k) => k.startsWith('.')) && keys.some((k) => !k.startsWith('.'));
}
function createBaseErrorMsg(importSpecifier, importer) {
return `Could not resolve import "${importSpecifier}" in ${importer}`;
}
function createErrorMsg(context, reason, internal) {
const { importSpecifier, importer, pkgJsonPath } = context;
const base = createBaseErrorMsg(importSpecifier, importer);
const field = internal ? 'imports' : 'exports';
return `${base} using ${field} defined in ${pkgJsonPath}.${reason ? ` ${reason}` : ''}`;
}
class ResolveError extends Error {}
class InvalidConfigurationError extends ResolveError {
constructor(context, reason) {
super(createErrorMsg(context, `Invalid "exports" field. ${reason}`));
}
}
class InvalidModuleSpecifierError extends ResolveError {
constructor(context, internal) {
super(createErrorMsg(context, internal));
}
}
class InvalidPackageTargetError extends ResolveError {
constructor(context, reason) {
super(createErrorMsg(context, reason));
}
}
/* eslint-disable no-await-in-loop, no-undefined */
function includesInvalidSegments(pathSegments, moduleDirs) {
return pathSegments
.split('/')
.slice(1)
.some((t) => ['.', '..', ...moduleDirs].includes(t));
}
async function resolvePackageTarget(context, { target, subpath, pattern, internal }) {
if (typeof target === 'string') {
if (!pattern && subpath.length > 0 && !target.endsWith('/')) {
throw new InvalidModuleSpecifierError(context);
}
if (!target.startsWith('./')) {
if (internal && !['/', '../'].some((p) => target.startsWith(p)) && !isUrl(target)) {
// this is a bare package import, remap it and resolve it using regular node resolve
if (pattern) {
const result = await context.resolveId(
target.replace(/\*/g, subpath),
context.pkgURL.href
);
return result ? pathToFileURL(result.location) : null;
}
const result = await context.resolveId(`${target}${subpath}`, context.pkgURL.href);
return result ? pathToFileURL(result.location) : null;
}
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
}
if (includesInvalidSegments(target, context.moduleDirs)) {
throw new InvalidPackageTargetError(context, `Invalid mapping: "${target}".`);
}
const resolvedTarget = new URL(target, context.pkgURL);
if (!resolvedTarget.href.startsWith(context.pkgURL.href)) {
throw new InvalidPackageTargetError(
context,
`Resolved to ${resolvedTarget.href} which is outside package ${context.pkgURL.href}`
);
}
if (includesInvalidSegments(subpath, context.moduleDirs)) {
throw new InvalidModuleSpecifierError(context);
}
if (pattern) {
return resolvedTarget.href.replace(/\*/g, subpath);
}
return new URL(subpath, resolvedTarget).href;
}
if (Array.isArray(target)) {
let lastError;
for (const item of target) {
try {
const resolved = await resolvePackageTarget(context, {
target: item,
subpath,
pattern,
internal
});
// return if defined or null, but not undefined
if (resolved !== undefined) {
return resolved;
}
} catch (error) {
if (!(error instanceof InvalidPackageTargetError)) {
throw error;
} else {
lastError = error;
}
}
}
if (lastError) {
throw lastError;
}
return null;
}
if (target && typeof target === 'object') {
for (const [key, value] of Object.entries(target)) {
if (key === 'default' || context.conditions.includes(key)) {
const resolved = await resolvePackageTarget(context, {
target: value,
subpath,
pattern,
internal
});
// return if defined or null, but not undefined
if (resolved !== undefined) {
return resolved;
}
}
}
return undefined;
}
if (target === null) {
return null;
}
throw new InvalidPackageTargetError(context, `Invalid exports field.`);
}
/* eslint-disable no-await-in-loop */
async function resolvePackageImportsExports(context, { matchKey, matchObj, internal }) {
if (!matchKey.endsWith('*') && matchKey in matchObj) {
const target = matchObj[matchKey];
const resolved = await resolvePackageTarget(context, { target, subpath: '', internal });
return resolved;
}
const expansionKeys = Object.keys(matchObj)
.filter((k) => k.endsWith('/') || k.endsWith('*'))
.sort((a, b) => b.length - a.length);
for (const expansionKey of expansionKeys) {
const prefix = expansionKey.substring(0, expansionKey.length - 1);
if (expansionKey.endsWith('*') && matchKey.startsWith(prefix)) {
const target = matchObj[expansionKey];
const subpath = matchKey.substring(expansionKey.length - 1);
const resolved = await resolvePackageTarget(context, {
target,
subpath,
pattern: true,
internal
});
return resolved;
}
if (matchKey.startsWith(expansionKey)) {
const target = matchObj[expansionKey];
const subpath = matchKey.substring(expansionKey.length);
const resolved = await resolvePackageTarget(context, { target, subpath, internal });
return resolved;
}
}
throw new InvalidModuleSpecifierError(context, internal);
}
async function resolvePackageExports(context, subpath, exports) {
if (isMixedExports(exports)) {
throw new InvalidConfigurationError(
context,
'All keys must either start with ./, or without one.'
);
}
if (subpath === '.') {
let mainExport;
// If exports is a String or Array, or an Object containing no keys starting with ".", then
if (typeof exports === 'string' || Array.isArray(exports) || isConditions(exports)) {
mainExport = exports;
} else if (isMappings(exports)) {
mainExport = exports['.'];
}
if (mainExport) {
const resolved = await resolvePackageTarget(context, { target: mainExport, subpath: '' });
if (resolved) {
return resolved;
}
}
} else if (isMappings(exports)) {
const resolvedMatch = await resolvePackageImportsExports(context, {
matchKey: subpath,
matchObj: exports
});
if (resolvedMatch) {
return resolvedMatch;
}
}
throw new InvalidModuleSpecifierError(context);
}
async function resolvePackageImports({
importSpecifier,
importer,
moduleDirs,
conditions,
resolveId
}) {
const result = await findPackageJson(importer, moduleDirs);
if (!result) {
throw new Error(createBaseErrorMsg('. Could not find a parent package.json.'));
}
const { pkgPath, pkgJsonPath, pkgJson } = result;
const pkgURL = pathToFileURL(`${pkgPath}/`);
const context = {
importer,
importSpecifier,
moduleDirs,
pkgURL,
pkgJsonPath,
conditions,
resolveId
};
const { imports } = pkgJson;
if (!imports) {
throw new InvalidModuleSpecifierError(context, true);
}
if (importSpecifier === '#' || importSpecifier.startsWith('#/')) {
throw new InvalidModuleSpecifierError(context, 'Invalid import specifier.');
}
return resolvePackageImportsExports(context, {
matchKey: importSpecifier,
matchObj: imports,
internal: true
});
}
const resolveImportPath = promisify(resolve$1);
const readFile$1 = promisify(fs.readFile);
async function getPackageJson(importer, pkgName, resolveOptions, moduleDirectories) {
if (importer) {
const selfPackageJsonResult = await findPackageJson(importer, moduleDirectories);
if (selfPackageJsonResult && selfPackageJsonResult.pkgJson.name === pkgName) {
// the referenced package name is the current package
return selfPackageJsonResult;
}
}
try {
const pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
const pkgJson = JSON.parse(await readFile$1(pkgJsonPath, 'utf-8'));
return { pkgJsonPath, pkgJson };
} catch (_) {
return null;
}
}
async function resolveId({
importer,
importSpecifier,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories,
rootDir,
ignoreSideEffectsForRoot
}) {
let hasModuleSideEffects = () => null;
let hasPackageEntry = true;
let packageBrowserField = false;
let packageInfo;
const filter = (pkg, pkgPath) => {
const info = getPackageInfo({
cache: packageInfoCache,
extensions,
pkg,
pkgPath,
mainFields,
preserveSymlinks,
useBrowserOverrides,
rootDir,
ignoreSideEffectsForRoot
});
({ packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = info);
return info.cachedPkg;
};
const resolveOptions = {
basedir: baseDir,
readFile: readCachedFile,
isFile: isFileCached,
isDirectory: isDirCached,
extensions,
includeCoreModules: false,
moduleDirectory: moduleDirectories,
preserveSymlinks,
packageFilter: filter
};
let location;
const pkgName = getPackageName(importSpecifier);
if (importSpecifier.startsWith('#')) {
// this is a package internal import, resolve using package imports field
const resolveResult = await resolvePackageImports({
importSpecifier,
importer,
moduleDirs: moduleDirectories,
conditions: exportConditions,
resolveId(id, parent) {
return resolveId({
importSpecifier: id,
importer: parent,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
});
}
});
location = fileURLToPath(resolveResult);
} else if (pkgName) {
// it's a bare import, find the package.json and resolve using package exports if available
const result = await getPackageJson(importer, pkgName, resolveOptions, moduleDirectories);
if (result && result.pkgJson.exports) {
const { pkgJson, pkgJsonPath } = result;
try {
const subpath =
pkgName === importSpecifier ? '.' : `.${importSpecifier.substring(pkgName.length)}`;
const pkgDr = pkgJsonPath.replace('package.json', '');
const pkgURL = pathToFileURL(pkgDr);
const context = {
importer,
importSpecifier,
moduleDirs: moduleDirectories,
pkgURL,
pkgJsonPath,
conditions: exportConditions
};
const resolvedPackageExport = await resolvePackageExports(
context,
subpath,
pkgJson.exports
);
location = fileURLToPath(resolvedPackageExport);
} catch (error) {
if (error instanceof ResolveError) {
return error;
}
throw error;
}
}
}
if (!location) {
// package has no imports or exports, use classic node resolve
try {
location = await resolveImportPath(importSpecifier, resolveOptions);
} catch (error) {
if (error.code !== 'MODULE_NOT_FOUND') {
throw error;
}
return null;
}
}
if (!preserveSymlinks) {
if (await exists(location)) {
location = await realpath(location);
}
}
return {
location,
hasModuleSideEffects,
hasPackageEntry,
packageBrowserField,
packageInfo
};
}
// Resolve module specifiers in order. Promise resolves to the first module that resolves
// successfully, or the error that resulted from the last attempted module resolution.
async function resolveImportSpecifiers({
importer,
importSpecifierList,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories,
rootDir,
ignoreSideEffectsForRoot
}) {
let lastResolveError;
for (let i = 0; i < importSpecifierList.length; i++) {
// eslint-disable-next-line no-await-in-loop
const result = await resolveId({
importer,
importSpecifier: importSpecifierList[i],
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories,
rootDir,
ignoreSideEffectsForRoot
});
if (result instanceof ResolveError) {
lastResolveError = result;
} else if (result) {
return result;
}
}
if (lastResolveError) {
// only log the last failed resolve error
warn(lastResolveError);
}
return null;
}
function handleDeprecatedOptions(opts) {
const warnings = [];
if (opts.customResolveOptions) {
const { customResolveOptions } = opts;
if (customResolveOptions.moduleDirectory) {
// eslint-disable-next-line no-param-reassign
opts.moduleDirectories = Array.isArray(customResolveOptions.moduleDirectory)
? customResolveOptions.moduleDirectory
: [customResolveOptions.moduleDirectory];
warnings.push(
'node-resolve: The `customResolveOptions.moduleDirectory` option has been deprecated. Use `moduleDirectories`, which must be an array.'
);
}
if (customResolveOptions.preserveSymlinks) {
throw new Error(
'node-resolve: `customResolveOptions.preserveSymlinks` is no longer an option. We now always use the rollup `preserveSymlinks` option.'
);
}
[
'basedir',
'package',
'extensions',
'includeCoreModules',
'readFile',
'isFile',
'isDirectory',
'realpath',
'packageFilter',
'pathFilter',
'paths',
'packageIterator'
].forEach((resolveOption) => {
if (customResolveOptions[resolveOption]) {
throw new Error(
`node-resolve: \`customResolveOptions.${resolveOption}\` is no longer an option. If you need this, please open an issue.`
);
}
});
}
return { warnings };
}
/* eslint-disable no-param-reassign, no-shadow, no-undefined */
const builtins = new Set(builtinList);
const ES6_BROWSER_EMPTY = '\0node-resolve:empty.js';
const deepFreeze = (object) => {
Object.freeze(object);
for (const value of Object.values(object)) {
if (typeof value === 'object' && !Object.isFrozen(value)) {
deepFreeze(value);
}
}
return object;
};
const baseConditions = ['default', 'module'];
const baseConditionsEsm = [...baseConditions, 'import'];
const baseConditionsCjs = [...baseConditions, 'require'];
const defaults = {
dedupe: [],
// It's important that .mjs is listed before .js so that Rollup will interpret npm modules
// which deploy both ESM .mjs and CommonJS .js files as ESM.
extensions: ['.mjs', '.js', '.json', '.node'],
resolveOnly: [],
moduleDirectories: ['node_modules'],
ignoreSideEffectsForRoot: false
};
const DEFAULTS = deepFreeze(deepMerge({}, defaults));
function nodeResolve(opts = {}) {
const { warnings } = handleDeprecatedOptions(opts);
const options = { ...defaults, ...opts };
const { extensions, jail, moduleDirectories, ignoreSideEffectsForRoot } = options;
const conditionsEsm = [...baseConditionsEsm, ...(options.exportConditions || [])];
const conditionsCjs = [...baseConditionsCjs, ...(options.exportConditions || [])];
const packageInfoCache = new Map();
const idToPackageInfo = new Map();
const mainFields = getMainFields(options);
const useBrowserOverrides = mainFields.indexOf('browser') !== -1;
const isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false;
const preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true;
const rootDir = resolve(options.rootDir || process.cwd());
let { dedupe } = options;
let rollupOptions;
if (typeof dedupe !== 'function') {
dedupe = (importee) =>
options.dedupe.includes(importee) || options.dedupe.includes(getPackageName(importee));
}
const resolveOnly = options.resolveOnly.map((pattern) => {
if (pattern instanceof RegExp) {
return pattern;
}
const normalized = pattern.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
return new RegExp(`^${normalized}$`);
});
const browserMapCache = new Map();
let preserveSymlinks;
return {
name: 'node-resolve',
buildStart(options) {
rollupOptions = options;
for (const warning of warnings) {
this.warn(warning);
}
({ preserveSymlinks } = options);
},
generateBundle() {
readCachedFile.clear();
isFileCached.clear();
isDirCached.clear();
},
async resolveId(importee, importer, opts) {
if (importee === ES6_BROWSER_EMPTY) {
return importee;
}
// ignore IDs with null character, these belong to other plugins
if (/\0/.test(importee)) return null;
if (/\0/.test(importer)) {
importer = undefined;
}
// strip query params from import
const [importPath, params] = importee.split('?');
const importSuffix = `${params ? `?${params}` : ''}`;
importee = importPath;
const baseDir = !importer || dedupe(importee) ? rootDir : dirname(importer);
// https://github.com/defunctzombie/package-browser-field-spec
const browser = browserMapCache.get(importer);
if (useBrowserOverrides && browser) {
const resolvedImportee = resolve(baseDir, importee);
if (browser[importee] === false || browser[resolvedImportee] === false) {
return ES6_BROWSER_EMPTY;
}
const browserImportee =
browser[importee] ||
browser[resolvedImportee] ||
browser[`${resolvedImportee}.js`] ||
browser[`${resolvedImportee}.json`];
if (browserImportee) {
importee = browserImportee;
}
}
const parts = importee.split(/[/\\]/);
let id = parts.shift();
let isRelativeImport = false;
if (id[0] === '@' && parts.length > 0) {
// scoped packages
id += `/${parts.shift()}`;
} else if (id[0] === '.') {
// an import relative to the parent dir of the importer
id = resolve(baseDir, importee);
isRelativeImport = true;
}
if (
!isRelativeImport &&
resolveOnly.length &&
!resolveOnly.some((pattern) => pattern.test(id))
) {
if (normalizeInput(rollupOptions.input).includes(importee)) {
return null;
}
return false;
}
const importSpecifierList = [];
if (importer === undefined && !importee[0].match(/^\.?\.?\//)) {
// For module graph roots (i.e. when importer is undefined), we
// need to handle 'path fragments` like `foo/bar` that are commonly
// found in rollup config files. If importee doesn't look like a
// relative or absolute path, we make it relative and attempt to
// resolve it. If we don't find anything, we try resolving it as we
// got it.
importSpecifierList.push(`./${importee}`);
}
const importeeIsBuiltin = builtins.has(importee);
if (importeeIsBuiltin) {
// The `resolve` library will not resolve packages with the same
// name as a node built-in module. If we're resolving something
// that's a builtin, and we don't prefer to find built-ins, we
// first try to look up a local module with that name. If we don't
// find anything, we resolve the builtin which just returns back
// the built-in's name.
importSpecifierList.push(`${importee}/`);
}
// TypeScript files may import '.js' to refer to either '.ts' or '.tsx'
if (importer && importee.endsWith('.js')) {
for (const ext of ['.ts', '.tsx']) {
if (importer.endsWith(ext) && extensions.includes(ext)) {
importSpecifierList.push(importee.replace(/.js$/, ext));
}
}
}
importSpecifierList.push(importee);
const warn = (...args) => this.warn(...args);
const isRequire =
opts && opts.custom && opts.custom['node-resolve'] && opts.custom['node-resolve'].isRequire;
const exportConditions = isRequire ? conditionsCjs : conditionsEsm;
const resolvedWithoutBuiltins = await resolveImportSpecifiers({
importer,
importSpecifierList,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories,
rootDir,
ignoreSideEffectsForRoot
});
const resolved =
importeeIsBuiltin && preferBuiltins
? {
packageInfo: undefined,
hasModuleSideEffects: () => null,
hasPackageEntry: true,
packageBrowserField: false
}
: resolvedWithoutBuiltins;
if (!resolved) {
return null;
}
const { packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = resolved;
let { location } = resolved;
if (packageBrowserField) {
if (Object.prototype.hasOwnProperty.call(packageBrowserField, location)) {
if (!packageBrowserField[location]) {
browserMapCache.set(location, packageBrowserField);
return ES6_BROWSER_EMPTY;
}
location = packageBrowserField[location];
}
browserMapCache.set(location, packageBrowserField);
}
if (hasPackageEntry && !preserveSymlinks) {
const fileExists = await exists(location);
if (fileExists) {
location = await realpath(location);
}
}
idToPackageInfo.set(location, packageInfo);
if (hasPackageEntry) {
if (importeeIsBuiltin && preferBuiltins) {
if (!isPreferBuiltinsSet && resolvedWithoutBuiltins && resolved !== importee) {
this.warn(
`preferring built-in module '${importee}' over local alternative at '${resolvedWithoutBuiltins.location}', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning`
);
}
return false;
} else if (jail && location.indexOf(normalize(jail.trim(sep))) !== 0) {
return null;
}
}
if (options.modulesOnly && (await exists(location))) {
const code = await readFile(location, 'utf-8');
if (isModule(code)) {
return {
id: `${location}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(location)
};
}
return null;
}
const result = {
id: `${location}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(location)
};
return result;
},
load(importee) {
if (importee === ES6_BROWSER_EMPTY) {
return 'export default {};';
}
return null;
},
getPackageInfoForId(id) {
return idToPackageInfo.get(id);
}
};
}
export default nodeResolve;
export { DEFAULTS, nodeResolve };