Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@rollup/plugin-node-resolve

Package Overview
Dependencies
Maintainers
4
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rollup/plugin-node-resolve - npm Package Compare versions

Comparing version 10.0.0 to 11.0.0

18

CHANGELOG.md
# @rollup/plugin-node-resolve ChangeLog
## v11.0.0
_2020-11-30_
### Breaking Changes
- refactor!: simplify builtins and remove `customResolveOptions` (#656)
- feat!: Mark built-ins as external (#627)
- feat!: support package entry points (#540)
### Bugfixes
- fix: refactor handling builtins, do not log warning if no local version (#637)
### Updates
- docs: fix import statements in examples in README.md (#646)
## v10.0.0

@@ -4,0 +22,0 @@

454

dist/cjs/index.js

@@ -11,7 +11,8 @@ 'use strict';

var util = require('util');
var resolve = require('resolve');
var pluginutils = require('@rollup/pluginutils');
var resolveModule = require('resolve');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var builtinList__default = /*#__PURE__*/_interopDefaultLegacy(builtinList);

@@ -21,3 +22,3 @@ var deepMerge__default = /*#__PURE__*/_interopDefaultLegacy(deepMerge);

var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var resolveModule__default = /*#__PURE__*/_interopDefaultLegacy(resolveModule);
var resolve__default = /*#__PURE__*/_interopDefaultLegacy(resolve);

@@ -83,4 +84,2 @@ const exists = util.promisify(fs__default['default'].exists);

const resolveId = util.promisify(resolveModule__default['default']);
// returns the imported package name for bare module imports

@@ -138,3 +137,3 @@ function getPackageName(id) {

// copy as we are about to munge the `main` field of `pkg`.
packageJson: Object.assign({}, pkg),
packageJson: { ...pkg },

@@ -237,33 +236,302 @@ // path to package.json file

// 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.
function resolveImportSpecifiers(importSpecifierList, resolveOptions) {
let promise = Promise.resolve();
const resolveImportPath = util.promisify(resolve__default['default']);
const readFile$1 = util.promisify(fs__default['default'].readFile);
for (let i = 0; i < importSpecifierList.length; i++) {
// eslint-disable-next-line no-loop-func
promise = promise.then(async (value) => {
// if we've already resolved to something, just return it.
if (value) {
return value;
const pathNotFoundError = (subPath, pkgPath) =>
new Error(`Package subpath '${subPath}' is not defined by "exports" in ${pkgPath}`);
function findExportKeyMatch(exportMap, subPath) {
for (const key of Object.keys(exportMap)) {
if (key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
if (subPath.startsWith(keyWithoutStar)) {
return key;
}
}
let result = await resolveId(importSpecifierList[i], resolveOptions);
if (!resolveOptions.preserveSymlinks) {
if (await exists(result)) {
result = await realpath(result);
}
if (key.endsWith('/') && subPath.startsWith(key)) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return key;
}
if (key === subPath) {
// literal match
return key;
}
}
return null;
}
function mapSubPath(pkgJsonPath, subPath, key, value) {
if (typeof value === 'string') {
if (typeof key === 'string' && key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
const subPathAfterKey = subPath.substring(keyWithoutStar.length);
return value.replace(/\*/g, subPathAfterKey);
}
if (value.endsWith('/')) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return `${value}${subPath.substring(key.length)}`;
}
// mapping is a string, for example { "./foo": "./dist/foo.js" }
return value;
}
if (Array.isArray(value)) {
// mapping is an array with fallbacks, for example { "./foo": ["foo:bar", "./dist/foo.js"] }
return value.find((v) => v.startsWith('./'));
}
throw pathNotFoundError(subPath, pkgJsonPath);
}
function findEntrypoint(pkgJsonPath, subPath, exportMap, conditions, key) {
if (typeof exportMap !== 'object') {
return mapSubPath(pkgJsonPath, subPath, key, exportMap);
}
// iterate conditions recursively, find the first that matches all conditions
for (const [condition, subExportMap] of Object.entries(exportMap)) {
if (conditions.includes(condition)) {
const mappedSubPath = findEntrypoint(pkgJsonPath, subPath, subExportMap, conditions, key);
if (mappedSubPath) {
return mappedSubPath;
}
return result;
}
}
throw pathNotFoundError(subPath, pkgJsonPath);
}
function findEntrypointTopLevel(pkgJsonPath, subPath, exportMap, conditions) {
if (typeof exportMap !== 'object') {
// the export map shorthand, for example { exports: "./index.js" }
if (subPath !== '.') {
// shorthand only supports a main entrypoint
throw pathNotFoundError(subPath, pkgJsonPath);
}
return mapSubPath(pkgJsonPath, subPath, null, exportMap);
}
// export map is an object, the top level can be either conditions or sub path mappings
const keys = Object.keys(exportMap);
const isConditions = keys.every((k) => !k.startsWith('.'));
const isMappings = keys.every((k) => k.startsWith('.'));
if (!isConditions && !isMappings) {
throw new Error(
`Invalid package config ${pkgJsonPath}, "exports" cannot contain some keys starting with '.'` +
' and some not. The exports object must either be an object of package subpath keys or an object of main entry' +
' condition name keys only.'
);
}
let key = null;
let exportMapForSubPath;
if (isConditions) {
// top level is conditions, for example { "import": ..., "require": ..., "module": ... }
if (subPath !== '.') {
// package with top level conditions means it only supports a main entrypoint
throw pathNotFoundError(subPath, pkgJsonPath);
}
exportMapForSubPath = exportMap;
} else {
// top level is sub path mappings, for example { ".": ..., "./foo": ..., "./bar": ... }
key = findExportKeyMatch(exportMap, subPath);
if (!key) {
throw pathNotFoundError(subPath, pkgJsonPath);
}
exportMapForSubPath = exportMap[key];
}
return findEntrypoint(pkgJsonPath, subPath, exportMapForSubPath, conditions, key);
}
async function resolveId({
importPath,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
}) {
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
});
// swallow MODULE_NOT_FOUND errors
promise = promise.catch((error) => {
({ 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(importPath);
if (pkgName) {
let pkgJsonPath;
let pkgJson;
try {
pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
pkgJson = JSON.parse(await readFile$1(pkgJsonPath, 'utf-8'));
} catch (_) {
// if there is no package.json we defer to regular resolve behavior
}
if (pkgJsonPath && pkgJson && pkgJson.exports) {
try {
const packageSubPath =
pkgName === importPath ? '.' : `.${importPath.substring(pkgName.length)}`;
const mappedSubPath = findEntrypointTopLevel(
pkgJsonPath,
packageSubPath,
pkgJson.exports,
exportConditions
);
const pkgDir = path__default['default'].dirname(pkgJsonPath);
location = path__default['default'].join(pkgDir, mappedSubPath);
} catch (error) {
warn(error);
return null;
}
}
}
if (!location) {
try {
location = await resolveImportPath(importPath, 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({
importSpecifierList,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
}) {
for (let i = 0; i < importSpecifierList.length; i++) {
// eslint-disable-next-line no-await-in-loop
const resolved = await resolveId({
importPath: importSpecifierList[i],
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
});
if (resolved) {
return resolved;
}
}
return null;
}
return promise;
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 };
}

@@ -275,3 +543,2 @@

const ES6_BROWSER_EMPTY = '\0node-resolve:empty.js';
const nullFn = () => null;
const deepFreeze = (object) => {

@@ -288,4 +555,7 @@ Object.freeze(object);

};
const baseConditions = ['default', 'module'];
const baseConditionsEsm = [...baseConditions, 'import'];
const baseConditionsCjs = [...baseConditions, 'require'];
const defaults = {
customResolveOptions: {},
dedupe: [],

@@ -295,3 +565,4 @@ // It's important that .mjs is listed before .js so that Rollup will interpret npm modules

extensions: ['.mjs', '.js', '.json', '.node'],
resolveOnly: []
resolveOnly: [],
moduleDirectories: ['node_modules']
};

@@ -301,5 +572,8 @@ const DEFAULTS = deepFreeze(deepMerge__default['default']({}, defaults));

function nodeResolve(opts = {}) {
const options = Object.assign({}, defaults, opts);
const { customResolveOptions, extensions, jail } = options;
const warnings = [];
const { warnings } = handleDeprecatedOptions(opts);
const options = { ...defaults, ...opts };
const { extensions, jail, moduleDirectories } = options;
const conditionsEsm = [...baseConditionsEsm, ...(options.exportConditions || [])];
const conditionsCjs = [...baseConditionsCjs, ...(options.exportConditions || [])];
const packageInfoCache = new Map();

@@ -315,7 +589,2 @@ const idToPackageInfo = new Map();

if (options.only) {
warnings.push('node-resolve: The `only` options is deprecated, please use `resolveOnly`');
options.resolveOnly = options.only;
}
if (typeof dedupe !== 'function') {

@@ -356,3 +625,3 @@ dedupe = (importee) =>

async resolveId(importee, importer) {
async resolveId(importee, importer, opts) {
if (importee === ES6_BROWSER_EMPTY) {

@@ -373,3 +642,3 @@ return importee;

const basedir = !importer || dedupe(importee) ? rootDir : path.dirname(importer);
const baseDir = !importer || dedupe(importee) ? rootDir : path.dirname(importer);

@@ -379,3 +648,3 @@ // https://github.com/defunctzombie/package-browser-field-spec

if (useBrowserOverrides && browser) {
const resolvedImportee = path.resolve(basedir, importee);
const resolvedImportee = path.resolve(baseDir, importee);
if (browser[importee] === false || browser[resolvedImportee] === false) {

@@ -403,3 +672,3 @@ return ES6_BROWSER_EMPTY;

// an import relative to the parent dir of the importer
id = path.resolve(basedir, importee);
id = path.resolve(baseDir, importee);
isRelativeImport = true;

@@ -419,36 +688,2 @@ }

let hasModuleSideEffects = nullFn;
let hasPackageEntry = true;
let packageBrowserField = false;
let packageInfo;
const filter = (pkg, pkgPath) => {
const info = getPackageInfo({
cache: packageInfoCache,
extensions,
pkg,
pkgPath,
mainFields,
preserveSymlinks,
useBrowserOverrides
});
({ packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = info);
return info.cachedPkg;
};
let resolveOptions = {
basedir,
packageFilter: filter,
readFile: readCachedFile,
isFile: isFileCached,
isDirectory: isDirCached,
extensions
};
if (preserveSymlinks !== undefined) {
resolveOptions.preserveSymlinks = preserveSymlinks;
}
const importSpecifierList = [];

@@ -468,3 +703,3 @@

if (importeeIsBuiltin && (!preferBuiltins || !isPreferBuiltinsSet)) {
if (importeeIsBuiltin) {
// The `resolve` library will not resolve packages with the same

@@ -489,5 +724,30 @@ // name as a node built-in module. If we're resolving something

importSpecifierList.push(importee);
resolveOptions = Object.assign(resolveOptions, customResolveOptions);
let resolved = await resolveImportSpecifiers(importSpecifierList, resolveOptions);
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({
importSpecifierList,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
});
const resolved =
importeeIsBuiltin && preferBuiltins
? {
packageInfo: undefined,
hasModuleSideEffects: () => null,
hasPackageEntry: true,
packageBrowserField: false
}
: resolvedWithoutBuiltins;
if (!resolved) {

@@ -497,43 +757,43 @@ return null;

const { packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = resolved;
let { location } = resolved;
if (packageBrowserField) {
if (Object.prototype.hasOwnProperty.call(packageBrowserField, resolved)) {
if (!packageBrowserField[resolved]) {
browserMapCache.set(resolved, packageBrowserField);
if (Object.prototype.hasOwnProperty.call(packageBrowserField, location)) {
if (!packageBrowserField[location]) {
browserMapCache.set(location, packageBrowserField);
return ES6_BROWSER_EMPTY;
}
resolved = packageBrowserField[resolved];
location = packageBrowserField[location];
}
browserMapCache.set(resolved, packageBrowserField);
browserMapCache.set(location, packageBrowserField);
}
if (hasPackageEntry && !preserveSymlinks) {
const fileExists = await exists(resolved);
const fileExists = await exists(location);
if (fileExists) {
resolved = await realpath(resolved);
location = await realpath(location);
}
}
idToPackageInfo.set(resolved, packageInfo);
idToPackageInfo.set(location, packageInfo);
if (hasPackageEntry) {
if (builtins.has(resolved) && preferBuiltins && isPreferBuiltinsSet) {
return null;
} else if (importeeIsBuiltin && preferBuiltins) {
if (!isPreferBuiltinsSet) {
if (importeeIsBuiltin && preferBuiltins) {
if (!isPreferBuiltinsSet && resolvedWithoutBuiltins && resolved !== importee) {
this.warn(
`preferring built-in module '${importee}' over local alternative at '${resolved}', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning`
`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(path.normalize(jail.trim(path.sep))) !== 0) {
return null;
} else if (jail && resolved.indexOf(path.normalize(jail.trim(path.sep))) !== 0) {
return null;
}
}
if (options.modulesOnly && (await exists(resolved))) {
const code = await readFile(resolved, 'utf-8');
if (options.modulesOnly && (await exists(location))) {
const code = await readFile(location, 'utf-8');
if (isModule__default['default'](code)) {
return {
id: `${resolved}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(resolved)
id: `${location}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(location)
};

@@ -544,4 +804,4 @@ }

const result = {
id: `${resolved}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(resolved)
id: `${location}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(location)
};

@@ -548,0 +808,0 @@ return result;

@@ -1,2 +0,2 @@

import { dirname, resolve, extname, normalize, sep } from 'path';
import path, { dirname, resolve, extname, normalize, sep } from 'path';
import builtinList from 'builtin-modules';

@@ -7,4 +7,4 @@ import deepMerge from 'deepmerge';

import { promisify } from 'util';
import resolve$1 from 'resolve';
import { createFilter } from '@rollup/pluginutils';
import resolveModule from 'resolve';

@@ -70,4 +70,2 @@ const exists = promisify(fs.exists);

const resolveId = promisify(resolveModule);
// returns the imported package name for bare module imports

@@ -125,3 +123,3 @@ function getPackageName(id) {

// copy as we are about to munge the `main` field of `pkg`.
packageJson: Object.assign({}, pkg),
packageJson: { ...pkg },

@@ -224,33 +222,302 @@ // path to package.json file

// 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.
function resolveImportSpecifiers(importSpecifierList, resolveOptions) {
let promise = Promise.resolve();
const resolveImportPath = promisify(resolve$1);
const readFile$1 = promisify(fs.readFile);
for (let i = 0; i < importSpecifierList.length; i++) {
// eslint-disable-next-line no-loop-func
promise = promise.then(async (value) => {
// if we've already resolved to something, just return it.
if (value) {
return value;
const pathNotFoundError = (subPath, pkgPath) =>
new Error(`Package subpath '${subPath}' is not defined by "exports" in ${pkgPath}`);
function findExportKeyMatch(exportMap, subPath) {
for (const key of Object.keys(exportMap)) {
if (key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
if (subPath.startsWith(keyWithoutStar)) {
return key;
}
}
let result = await resolveId(importSpecifierList[i], resolveOptions);
if (!resolveOptions.preserveSymlinks) {
if (await exists(result)) {
result = await realpath(result);
}
if (key.endsWith('/') && subPath.startsWith(key)) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return key;
}
if (key === subPath) {
// literal match
return key;
}
}
return null;
}
function mapSubPath(pkgJsonPath, subPath, key, value) {
if (typeof value === 'string') {
if (typeof key === 'string' && key.endsWith('*')) {
// star match: "./foo/*": "./foo/*.js"
const keyWithoutStar = key.substring(0, key.length - 1);
const subPathAfterKey = subPath.substring(keyWithoutStar.length);
return value.replace(/\*/g, subPathAfterKey);
}
if (value.endsWith('/')) {
// directory match (deprecated by node): "./foo/": "./foo/.js"
return `${value}${subPath.substring(key.length)}`;
}
// mapping is a string, for example { "./foo": "./dist/foo.js" }
return value;
}
if (Array.isArray(value)) {
// mapping is an array with fallbacks, for example { "./foo": ["foo:bar", "./dist/foo.js"] }
return value.find((v) => v.startsWith('./'));
}
throw pathNotFoundError(subPath, pkgJsonPath);
}
function findEntrypoint(pkgJsonPath, subPath, exportMap, conditions, key) {
if (typeof exportMap !== 'object') {
return mapSubPath(pkgJsonPath, subPath, key, exportMap);
}
// iterate conditions recursively, find the first that matches all conditions
for (const [condition, subExportMap] of Object.entries(exportMap)) {
if (conditions.includes(condition)) {
const mappedSubPath = findEntrypoint(pkgJsonPath, subPath, subExportMap, conditions, key);
if (mappedSubPath) {
return mappedSubPath;
}
return result;
}
}
throw pathNotFoundError(subPath, pkgJsonPath);
}
function findEntrypointTopLevel(pkgJsonPath, subPath, exportMap, conditions) {
if (typeof exportMap !== 'object') {
// the export map shorthand, for example { exports: "./index.js" }
if (subPath !== '.') {
// shorthand only supports a main entrypoint
throw pathNotFoundError(subPath, pkgJsonPath);
}
return mapSubPath(pkgJsonPath, subPath, null, exportMap);
}
// export map is an object, the top level can be either conditions or sub path mappings
const keys = Object.keys(exportMap);
const isConditions = keys.every((k) => !k.startsWith('.'));
const isMappings = keys.every((k) => k.startsWith('.'));
if (!isConditions && !isMappings) {
throw new Error(
`Invalid package config ${pkgJsonPath}, "exports" cannot contain some keys starting with '.'` +
' and some not. The exports object must either be an object of package subpath keys or an object of main entry' +
' condition name keys only.'
);
}
let key = null;
let exportMapForSubPath;
if (isConditions) {
// top level is conditions, for example { "import": ..., "require": ..., "module": ... }
if (subPath !== '.') {
// package with top level conditions means it only supports a main entrypoint
throw pathNotFoundError(subPath, pkgJsonPath);
}
exportMapForSubPath = exportMap;
} else {
// top level is sub path mappings, for example { ".": ..., "./foo": ..., "./bar": ... }
key = findExportKeyMatch(exportMap, subPath);
if (!key) {
throw pathNotFoundError(subPath, pkgJsonPath);
}
exportMapForSubPath = exportMap[key];
}
return findEntrypoint(pkgJsonPath, subPath, exportMapForSubPath, conditions, key);
}
async function resolveId({
importPath,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
}) {
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
});
// swallow MODULE_NOT_FOUND errors
promise = promise.catch((error) => {
({ 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(importPath);
if (pkgName) {
let pkgJsonPath;
let pkgJson;
try {
pkgJsonPath = await resolveImportPath(`${pkgName}/package.json`, resolveOptions);
pkgJson = JSON.parse(await readFile$1(pkgJsonPath, 'utf-8'));
} catch (_) {
// if there is no package.json we defer to regular resolve behavior
}
if (pkgJsonPath && pkgJson && pkgJson.exports) {
try {
const packageSubPath =
pkgName === importPath ? '.' : `.${importPath.substring(pkgName.length)}`;
const mappedSubPath = findEntrypointTopLevel(
pkgJsonPath,
packageSubPath,
pkgJson.exports,
exportConditions
);
const pkgDir = path.dirname(pkgJsonPath);
location = path.join(pkgDir, mappedSubPath);
} catch (error) {
warn(error);
return null;
}
}
}
if (!location) {
try {
location = await resolveImportPath(importPath, 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({
importSpecifierList,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
}) {
for (let i = 0; i < importSpecifierList.length; i++) {
// eslint-disable-next-line no-await-in-loop
const resolved = await resolveId({
importPath: importSpecifierList[i],
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
});
if (resolved) {
return resolved;
}
}
return null;
}
return promise;
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 };
}

@@ -262,3 +529,2 @@

const ES6_BROWSER_EMPTY = '\0node-resolve:empty.js';
const nullFn = () => null;
const deepFreeze = (object) => {

@@ -275,4 +541,7 @@ Object.freeze(object);

};
const baseConditions = ['default', 'module'];
const baseConditionsEsm = [...baseConditions, 'import'];
const baseConditionsCjs = [...baseConditions, 'require'];
const defaults = {
customResolveOptions: {},
dedupe: [],

@@ -282,3 +551,4 @@ // It's important that .mjs is listed before .js so that Rollup will interpret npm modules

extensions: ['.mjs', '.js', '.json', '.node'],
resolveOnly: []
resolveOnly: [],
moduleDirectories: ['node_modules']
};

@@ -288,5 +558,8 @@ const DEFAULTS = deepFreeze(deepMerge({}, defaults));

function nodeResolve(opts = {}) {
const options = Object.assign({}, defaults, opts);
const { customResolveOptions, extensions, jail } = options;
const warnings = [];
const { warnings } = handleDeprecatedOptions(opts);
const options = { ...defaults, ...opts };
const { extensions, jail, moduleDirectories } = options;
const conditionsEsm = [...baseConditionsEsm, ...(options.exportConditions || [])];
const conditionsCjs = [...baseConditionsCjs, ...(options.exportConditions || [])];
const packageInfoCache = new Map();

@@ -302,7 +575,2 @@ const idToPackageInfo = new Map();

if (options.only) {
warnings.push('node-resolve: The `only` options is deprecated, please use `resolveOnly`');
options.resolveOnly = options.only;
}
if (typeof dedupe !== 'function') {

@@ -343,3 +611,3 @@ dedupe = (importee) =>

async resolveId(importee, importer) {
async resolveId(importee, importer, opts) {
if (importee === ES6_BROWSER_EMPTY) {

@@ -360,3 +628,3 @@ return importee;

const basedir = !importer || dedupe(importee) ? rootDir : dirname(importer);
const baseDir = !importer || dedupe(importee) ? rootDir : dirname(importer);

@@ -366,3 +634,3 @@ // https://github.com/defunctzombie/package-browser-field-spec

if (useBrowserOverrides && browser) {
const resolvedImportee = resolve(basedir, importee);
const resolvedImportee = resolve(baseDir, importee);
if (browser[importee] === false || browser[resolvedImportee] === false) {

@@ -390,3 +658,3 @@ return ES6_BROWSER_EMPTY;

// an import relative to the parent dir of the importer
id = resolve(basedir, importee);
id = resolve(baseDir, importee);
isRelativeImport = true;

@@ -406,36 +674,2 @@ }

let hasModuleSideEffects = nullFn;
let hasPackageEntry = true;
let packageBrowserField = false;
let packageInfo;
const filter = (pkg, pkgPath) => {
const info = getPackageInfo({
cache: packageInfoCache,
extensions,
pkg,
pkgPath,
mainFields,
preserveSymlinks,
useBrowserOverrides
});
({ packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = info);
return info.cachedPkg;
};
let resolveOptions = {
basedir,
packageFilter: filter,
readFile: readCachedFile,
isFile: isFileCached,
isDirectory: isDirCached,
extensions
};
if (preserveSymlinks !== undefined) {
resolveOptions.preserveSymlinks = preserveSymlinks;
}
const importSpecifierList = [];

@@ -455,3 +689,3 @@

if (importeeIsBuiltin && (!preferBuiltins || !isPreferBuiltinsSet)) {
if (importeeIsBuiltin) {
// The `resolve` library will not resolve packages with the same

@@ -476,5 +710,30 @@ // name as a node built-in module. If we're resolving something

importSpecifierList.push(importee);
resolveOptions = Object.assign(resolveOptions, customResolveOptions);
let resolved = await resolveImportSpecifiers(importSpecifierList, resolveOptions);
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({
importSpecifierList,
exportConditions,
warn,
packageInfoCache,
extensions,
mainFields,
preserveSymlinks,
useBrowserOverrides,
baseDir,
moduleDirectories
});
const resolved =
importeeIsBuiltin && preferBuiltins
? {
packageInfo: undefined,
hasModuleSideEffects: () => null,
hasPackageEntry: true,
packageBrowserField: false
}
: resolvedWithoutBuiltins;
if (!resolved) {

@@ -484,43 +743,43 @@ return null;

const { packageInfo, hasModuleSideEffects, hasPackageEntry, packageBrowserField } = resolved;
let { location } = resolved;
if (packageBrowserField) {
if (Object.prototype.hasOwnProperty.call(packageBrowserField, resolved)) {
if (!packageBrowserField[resolved]) {
browserMapCache.set(resolved, packageBrowserField);
if (Object.prototype.hasOwnProperty.call(packageBrowserField, location)) {
if (!packageBrowserField[location]) {
browserMapCache.set(location, packageBrowserField);
return ES6_BROWSER_EMPTY;
}
resolved = packageBrowserField[resolved];
location = packageBrowserField[location];
}
browserMapCache.set(resolved, packageBrowserField);
browserMapCache.set(location, packageBrowserField);
}
if (hasPackageEntry && !preserveSymlinks) {
const fileExists = await exists(resolved);
const fileExists = await exists(location);
if (fileExists) {
resolved = await realpath(resolved);
location = await realpath(location);
}
}
idToPackageInfo.set(resolved, packageInfo);
idToPackageInfo.set(location, packageInfo);
if (hasPackageEntry) {
if (builtins.has(resolved) && preferBuiltins && isPreferBuiltinsSet) {
return null;
} else if (importeeIsBuiltin && preferBuiltins) {
if (!isPreferBuiltinsSet) {
if (importeeIsBuiltin && preferBuiltins) {
if (!isPreferBuiltinsSet && resolvedWithoutBuiltins && resolved !== importee) {
this.warn(
`preferring built-in module '${importee}' over local alternative at '${resolved}', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning`
`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;
} else if (jail && resolved.indexOf(normalize(jail.trim(sep))) !== 0) {
return null;
}
}
if (options.modulesOnly && (await exists(resolved))) {
const code = await readFile(resolved, 'utf-8');
if (options.modulesOnly && (await exists(location))) {
const code = await readFile(location, 'utf-8');
if (isModule(code)) {
return {
id: `${resolved}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(resolved)
id: `${location}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(location)
};

@@ -531,4 +790,4 @@ }

const result = {
id: `${resolved}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(resolved)
id: `${location}${importSuffix}`,
moduleSideEffects: hasModuleSideEffects(location)
};

@@ -535,0 +794,0 @@ return result;

{
"name": "@rollup/plugin-node-resolve",
"version": "10.0.0",
"version": "11.0.0",
"publishConfig": {

@@ -62,3 +62,3 @@ "access": "public"

"is-module": "^1.0.0",
"resolve": "^1.17.0"
"resolve": "^1.19.0"
},

@@ -69,3 +69,3 @@ "devDependencies": {

"@rollup/plugin-babel": "^5.1.0",
"@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-json": "^4.1.0",

@@ -72,0 +72,0 @@ "es5-ext": "^0.10.53",

@@ -47,2 +47,13 @@ [npm]: https://img.shields.io/npm/v/@rollup/plugin-node-resolve

### `exportConditions`
Type: `Array[...String]`<br>
Default: `[]`
Additional conditions of the package.json exports field to match when resolving modules. By default, this plugin looks for the `['default', 'module', 'import']` conditions when resolving imports.
When using `@rollup/plugin-commonjs` v16 or higher, this plugin will use the `['default', 'module', 'require']` conditions when resolving require statements.
Setting this option will add extra conditions on top of the default conditions. See https://nodejs.org/api/packages.html#packages_conditional_exports for more information.
### `browser`

@@ -55,15 +66,9 @@

### `customResolveOptions`
### `moduleDirectories`
Type: `Object`<br>
Default: `null`
Type: `Array[...String]`<br>
Default: `['node_modules']`
An `Object` that specifies additional options that should be passed through to [`resolve`](https://www.npmjs.com/package/resolve).
One or more directories in which to recursively look for modules.
```
customResolveOptions: {
moduleDirectory: 'js_modules'
}
```
### `dedupe`

@@ -106,3 +111,3 @@

Locks the module search within specified path (e.g. chroot). Modules defined outside this path will be marked as external.
Locks the module search within specified path (e.g. chroot). Modules defined outside this path will be ignored by this plugin.

@@ -117,10 +122,6 @@ ### `mainFields`

### `only`
DEPRECATED: use "resolveOnly" instead
### `preferBuiltins`
Type: `Boolean`<br>
Default: `true`
Default: `true` (with warnings if a builtin module is used over a local version. Set to `true` to disable warning.)

@@ -157,2 +158,6 @@ If `true`, the plugin will prefer built-in modules (e.g. `fs`, `path`). If `false`, the plugin will look for locally installed modules of the same name.

## Preserving symlinks
This plugin honours the rollup [`preserveSymlinks`](https://rollupjs.org/guide/en/#preservesymlinks) option.
## Using with @rollup/plugin-commonjs

@@ -164,3 +169,3 @@

// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

@@ -175,3 +180,3 @@

},
plugins: [resolve(), commonjs()]
plugins: [nodeResolve(), commonjs()]
};

@@ -182,12 +187,14 @@ ```

This plugin won't resolve any builtins (e.g. `fs`). If you need to resolve builtins you can install local modules and set `preferBuiltins` to `false`, or install a plugin like [rollup-plugin-node-polyfills](https://github.com/ionic-team/rollup-plugin-node-polyfills) which provides stubbed versions of these methods.
By default this plugin will prefer built-ins over local modules, marking them as external.
If you want to silence warnings about builtins, you can add the list of builtins to the `externals` option; like so:
See [`preferBuiltins`](#preferbuiltins).
To provide stubbed versions of Node built-ins, yse a plugin like [rollup-plugin-node-polyfills](https://github.com/ionic-team/rollup-plugin-node-polyfills) or use [`builtin-modules`](https://github.com/sindresorhus/builtin-modules) with `external`, and set `preferBuiltins` to `false`. e.g.
```js
import resolve from '@rollup/plugin-node-resolve';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import builtins from 'builtin-modules'
export default ({
input: ...,
plugins: [resolve()],
plugins: [nodeResolve()],
external: builtins,

@@ -198,2 +205,15 @@ output: ...

## Resolving require statements
According to [NodeJS module resolution](https://nodejs.org/api/packages.html#packages_package_entry_points) `require` statements should resolve using the `require` condition in the package exports field, while es modules should use the `import` condition.
The node resolve plugin uses `import` by default, you can opt into using the `require` semantics by passing an extra option to the resolve function:
```js
this.resolve(importee, importer, {
skipSelf: true,
custom: { 'node-resolve': { isRequire: true } }
});
```
## Meta

@@ -200,0 +220,0 @@

@@ -1,4 +0,1 @@

import { Plugin } from 'rollup';
import { AsyncOpts } from 'resolve';
export const DEFAULTS: {

@@ -13,2 +10,14 @@ customResolveOptions: {};

/**
* Additional conditions of the package.json exports field to match when resolving modules.
* By default, this plugin looks for the `'default', 'module', 'import']` conditions when resolving imports.
*
* When using `@rollup/plugin-commonjs` v16 or higher, this plugin will use the
* `['default', 'module', 'import']` conditions when resolving require statements.
*
* Setting this option will add extra conditions on top of the default conditions.
* See https://nodejs.org/api/packages.html#packages_conditional_exports for more information.
*/
exportConditions?: string[];
/**
* If `true`, instructs the plugin to use the `"browser"` property in `package.json`

@@ -24,5 +33,6 @@ * files to specify alternative files to load for bundling. This is useful when

/**
* An `Object` that specifies additional options that should be passed through to `node-resolve`.
* One or more directories in which to recursively look for modules.
* @default ['node_modules']
*/
customResolveOptions?: AsyncOpts;
moduleDirectories?: string[];

@@ -63,8 +73,2 @@ /**

/**
* @deprecated use "resolveOnly" instead
* @default null
*/
only?: ReadonlyArray<string | RegExp> | null;
/**
* If `true`, the plugin will prefer built-in modules (e.g. `fs`, `path`). If `false`,

@@ -71,0 +75,0 @@ * the plugin will look for locally installed modules of the same name.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc