diff --git a/packages/commonjs/README.md b/packages/commonjs/README.md
index 31b1f1e6d..98f646e6f 100644
--- a/packages/commonjs/README.md
+++ b/packages/commonjs/README.md
@@ -345,6 +345,14 @@ For these situations, you can change Rollup's behaviour either globally or per m
To change this for individual modules, you can supply a function for `requireReturnsDefault` instead. This function will then be called once for each required ES module or external dependency with the corresponding id and allows you to return different values for different modules.
+### nodeModulesLookupDepth
+
+Type: `number`
+Default: `15`
+
+Max depth for `node_modules` lookup algorithm in the virtual `require` realm.
+This is here for safety, in case of a dynamic require to something that does not exist.
+
## Using with @rollup/plugin-node-resolve
Since most CommonJS packages you are importing are probably dependencies in `node_modules`, you may need to use [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve):
diff --git a/packages/commonjs/src/helpers.js b/packages/commonjs/src/helpers.js
index fa13894d0..19f2b203f 100644
--- a/packages/commonjs/src/helpers.js
+++ b/packages/commonjs/src/helpers.js
@@ -58,7 +58,7 @@ export function commonjsRequire (path) {
}
`;
-const getDynamicHelpers = (ignoreDynamicRequires) => `
+const getDynamicHelpers = (ignoreDynamicRequires, nodeModulesLookupDepth) => `
export function createModule(modulePath) {
return {
path: modulePath,
@@ -172,7 +172,8 @@ export function commonjsResolveImpl (path, originalModuleDir, testCache) {
if (path[0] === '/') {
originalModuleDir = '/';
}
- while (true) {
+ let depth = 0;
+ while (depth++ < ${nodeModulesLookupDepth}) {
if (!shouldTryNodeModules) {
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;
} else if (originalModuleDir) {
@@ -181,10 +182,6 @@ export function commonjsResolveImpl (path, originalModuleDir, testCache) {
relPath = normalize(join('node_modules', path));
}
- if (relPath.endsWith('/..')) {
- break; // Travelled too far up, avoid infinite loop
- }
-
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];
if (DYNAMIC_REQUIRE_CACHE[resolvedPath]) {
@@ -257,8 +254,14 @@ commonjsRequire.cache = DYNAMIC_REQUIRE_CACHE;
commonjsRequire.resolve = commonjsResolve;
`;
-export function getHelpersModule(isDynamicRequireModulesEnabled, ignoreDynamicRequires) {
+export function getHelpersModule(
+ isDynamicRequireModulesEnabled,
+ ignoreDynamicRequires,
+ nodeModulesLookupDepth
+) {
return `${HELPERS}${
- isDynamicRequireModulesEnabled ? getDynamicHelpers(ignoreDynamicRequires) : HELPER_NON_DYNAMIC
+ isDynamicRequireModulesEnabled
+ ? getDynamicHelpers(ignoreDynamicRequires, nodeModulesLookupDepth)
+ : HELPER_NON_DYNAMIC
}`;
}
diff --git a/packages/commonjs/src/index.js b/packages/commonjs/src/index.js
index 09925de34..76fe406fb 100644
--- a/packages/commonjs/src/index.js
+++ b/packages/commonjs/src/index.js
@@ -46,6 +46,7 @@ export default function commonjs(options = {}) {
const {
ignoreGlobal,
ignoreDynamicRequires,
+ nodeModulesLookupDepth,
requireReturnsDefault: requireReturnsDefaultOption,
esmExternals
} = options;
@@ -168,7 +169,11 @@ export default function commonjs(options = {}) {
load(id) {
if (id === HELPERS_ID) {
- return getHelpersModule(isDynamicRequireModulesEnabled, ignoreDynamicRequires);
+ return getHelpersModule(
+ isDynamicRequireModulesEnabled,
+ ignoreDynamicRequires,
+ typeof nodeModulesLookupDepth === 'number' ? nodeModulesLookupDepth : 15
+ );
}
if (id.startsWith(HELPERS_ID)) {
diff --git a/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/_config.js b/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/_config.js
new file mode 100755
index 000000000..5d2c2f23a
--- /dev/null
+++ b/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/_config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ description: 'resolves both windows and posix paths',
+ pluginOptions: {
+ dynamicRequireTargets: [
+ 'fixtures/function/dynamic-require-alias-hack/stub.js'
+ ],
+ ignoreDynamicRequires: true
+ }
+};
diff --git a/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/main.js b/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/main.js
new file mode 100755
index 000000000..8fe3e299b
--- /dev/null
+++ b/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/main.js
@@ -0,0 +1,9 @@
+/* eslint-disable global-require */
+// noinspection UnnecessaryLocalVariableJS
+
+// A hack used in many old libraries, saying "workaround to exclude package from browserify list."
+// Will bypass rollup-commonjs finding out that this is a require that should not go through the plugin, and will do an infinite search.
+let _require = require;
+let buffer = _require('buffer');
+
+t.is(buffer, require('buffer'));
diff --git a/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/stub.js b/packages/commonjs/test/fixtures/function/dynamic-require-alias-hack/stub.js
new file mode 100755
index 000000000..e69de29bb
diff --git a/packages/commonjs/test/snapshots/function.js.md b/packages/commonjs/test/snapshots/function.js.md
index eb98d9b21..6ae07eb2b 100644
--- a/packages/commonjs/test/snapshots/function.js.md
+++ b/packages/commonjs/test/snapshots/function.js.md
@@ -436,7 +436,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -444,10 +445,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -657,7 +654,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -665,10 +663,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -874,7 +868,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -882,10 +877,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -1113,7 +1104,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -1121,10 +1113,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -1361,7 +1349,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -1369,10 +1358,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -1598,7 +1583,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -1606,10 +1592,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -1802,7 +1784,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -1810,10 +1793,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -2038,7 +2017,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -2046,10 +2026,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -2236,7 +2212,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -2244,10 +2221,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -2469,7 +2442,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -2477,10 +2451,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -2691,7 +2661,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -2699,10 +2670,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -2939,7 +2906,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -2947,10 +2915,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -3189,7 +3153,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -3197,10 +3162,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -3402,7 +3363,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -3410,10 +3372,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -3626,7 +3584,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -3634,10 +3593,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -3876,7 +3831,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -3884,10 +3840,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -4102,7 +4054,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -4110,10 +4063,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -4335,7 +4284,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -4343,10 +4293,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -4543,7 +4489,8 @@ Generated by [AVA](https://avajs.dev).
if (path[0] === '/') {␊
originalModuleDir = '/';␊
}␊
- while (true) {␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
if (!shouldTryNodeModules) {␊
relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
} else if (originalModuleDir) {␊
@@ -4551,10 +4498,6 @@ Generated by [AVA](https://avajs.dev).
} else {␊
relPath = normalize(join('node_modules', path));␊
}␊
- ␊
- if (relPath.endsWith('/..')) {␊
- break; // Travelled too far up, avoid infinite loop␊
- }␊
␊
for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
@@ -7871,3 +7814,213 @@ Generated by [AVA](https://avajs.dev).
module.exports = main;␊
`,
}
+
+## dynamic-require-alias-hack
+
+> Snapshot 1
+
+ {
+ 'main.js': `'use strict';␊
+ ␊
+ var require$$0 = require('buffer');␊
+ ␊
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }␊
+ ␊
+ var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);␊
+ ␊
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};␊
+ ␊
+ function commonjsRegister (path, loader) {␊
+ DYNAMIC_REQUIRE_LOADERS[path] = loader;␊
+ }␊
+ ␊
+ const DYNAMIC_REQUIRE_LOADERS = Object.create(null);␊
+ const DYNAMIC_REQUIRE_CACHE = Object.create(null);␊
+ const DYNAMIC_REQUIRE_SHORTS = Object.create(null);␊
+ const DEFAULT_PARENT_MODULE = {␊
+ id: '<' + 'rollup>', exports: {}, parent: undefined, filename: null, loaded: false, children: [], paths: []␊
+ };␊
+ const CHECKED_EXTENSIONS = ['', '.js', '.json'];␊
+ ␊
+ function normalize (path) {␊
+ path = path.replace(/\\\\/g, '/');␊
+ const parts = path.split('/');␊
+ const slashed = parts[0] === '';␊
+ for (let i = 1; i < parts.length; i++) {␊
+ if (parts[i] === '.' || parts[i] === '') {␊
+ parts.splice(i--, 1);␊
+ }␊
+ }␊
+ for (let i = 1; i < parts.length; i++) {␊
+ if (parts[i] !== '..') continue;␊
+ if (i > 0 && parts[i - 1] !== '..' && parts[i - 1] !== '.') {␊
+ parts.splice(--i, 2);␊
+ i--;␊
+ }␊
+ }␊
+ path = parts.join('/');␊
+ if (slashed && path[0] !== '/')␊
+ path = '/' + path;␊
+ else if (path.length === 0)␊
+ path = '.';␊
+ return path;␊
+ }␊
+ ␊
+ function join () {␊
+ if (arguments.length === 0)␊
+ return '.';␊
+ let joined;␊
+ for (let i = 0; i < arguments.length; ++i) {␊
+ let arg = arguments[i];␊
+ if (arg.length > 0) {␊
+ if (joined === undefined)␊
+ joined = arg;␊
+ else␊
+ joined += '/' + arg;␊
+ }␊
+ }␊
+ if (joined === undefined)␊
+ return '.';␊
+ ␊
+ return joined;␊
+ }␊
+ ␊
+ function isPossibleNodeModulesPath (modulePath) {␊
+ let c0 = modulePath[0];␊
+ if (c0 === '/' || c0 === '\\\\') return false;␊
+ let c1 = modulePath[1], c2 = modulePath[2];␊
+ if ((c0 === '.' && (!c1 || c1 === '/' || c1 === '\\\\')) ||␊
+ (c0 === '.' && c1 === '.' && (!c2 || c2 === '/' || c2 === '\\\\'))) return false;␊
+ if (c1 === ':' && (c2 === '/' || c2 === '\\\\'))␊
+ return false;␊
+ return true;␊
+ }␊
+ ␊
+ function dirname (path) {␊
+ if (path.length === 0)␊
+ return '.';␊
+ ␊
+ let i = path.length - 1;␊
+ while (i > 0) {␊
+ const c = path.charCodeAt(i);␊
+ if ((c === 47 || c === 92) && i !== path.length - 1)␊
+ break;␊
+ i--;␊
+ }␊
+ ␊
+ if (i > 0)␊
+ return path.substr(0, i);␊
+ ␊
+ if (path.chartCodeAt(0) === 47 || path.chartCodeAt(0) === 92)␊
+ return path.charAt(0);␊
+ ␊
+ return '.';␊
+ }␊
+ ␊
+ function commonjsResolveImpl (path, originalModuleDir, testCache) {␊
+ const shouldTryNodeModules = isPossibleNodeModulesPath(path);␊
+ path = normalize(path);␊
+ let relPath;␊
+ if (path[0] === '/') {␊
+ originalModuleDir = '/';␊
+ }␊
+ let depth = 0;␊
+ while (depth++ < 15) {␊
+ if (!shouldTryNodeModules) {␊
+ relPath = originalModuleDir ? normalize(originalModuleDir + '/' + path) : path;␊
+ } else if (originalModuleDir) {␊
+ relPath = normalize(originalModuleDir + '/node_modules/' + path);␊
+ } else {␊
+ relPath = normalize(join('node_modules', path));␊
+ }␊
+ ␊
+ for (let extensionIndex = 0; extensionIndex < CHECKED_EXTENSIONS.length; extensionIndex++) {␊
+ const resolvedPath = relPath + CHECKED_EXTENSIONS[extensionIndex];␊
+ if (DYNAMIC_REQUIRE_CACHE[resolvedPath]) {␊
+ return resolvedPath;␊
+ }␊
+ if (DYNAMIC_REQUIRE_SHORTS[resolvedPath]) {␊
+ return resolvedPath;␊
+ }␊
+ if (DYNAMIC_REQUIRE_LOADERS[resolvedPath]) {␊
+ return resolvedPath;␊
+ }␊
+ }␊
+ if (!shouldTryNodeModules) break;␊
+ const nextDir = normalize(originalModuleDir + '/..');␊
+ if (nextDir === originalModuleDir) break;␊
+ originalModuleDir = nextDir;␊
+ }␊
+ return null;␊
+ }␊
+ ␊
+ function commonjsResolve (path, originalModuleDir) {␊
+ const resolvedPath = commonjsResolveImpl(path, originalModuleDir);␊
+ if (resolvedPath !== null) {␊
+ return resolvedPath;␊
+ }␊
+ return require.resolve(path);␊
+ }␊
+ ␊
+ function commonjsRequire (path, originalModuleDir) {␊
+ let resolvedPath = commonjsResolveImpl(path, originalModuleDir);␊
+ if (resolvedPath !== null) {␊
+ let cachedModule = DYNAMIC_REQUIRE_CACHE[resolvedPath];␊
+ if (cachedModule) return cachedModule.exports;␊
+ let shortTo = DYNAMIC_REQUIRE_SHORTS[resolvedPath];␊
+ if (shortTo) {␊
+ cachedModule = DYNAMIC_REQUIRE_CACHE[shortTo];␊
+ if (cachedModule)␊
+ return cachedModule.exports;␊
+ resolvedPath = commonjsResolveImpl(shortTo, null);␊
+ }␊
+ const loader = DYNAMIC_REQUIRE_LOADERS[resolvedPath];␊
+ if (loader) {␊
+ DYNAMIC_REQUIRE_CACHE[resolvedPath] = cachedModule = {␊
+ id: resolvedPath,␊
+ filename: resolvedPath,␊
+ path: dirname(resolvedPath),␊
+ exports: {},␊
+ parent: DEFAULT_PARENT_MODULE,␊
+ loaded: false,␊
+ children: [],␊
+ paths: [],␊
+ require: function (path, base) {␊
+ return commonjsRequire(path, (base === undefined || base === null) ? cachedModule.path : base);␊
+ }␊
+ };␊
+ try {␊
+ loader.call(commonjsGlobal, cachedModule, cachedModule.exports);␊
+ } catch (error) {␊
+ delete DYNAMIC_REQUIRE_CACHE[resolvedPath];␊
+ throw error;␊
+ }␊
+ cachedModule.loaded = true;␊
+ return cachedModule.exports;␊
+ } }␊
+ return require(path);␊
+ }␊
+ ␊
+ commonjsRequire.cache = DYNAMIC_REQUIRE_CACHE;␊
+ commonjsRequire.resolve = commonjsResolve;␊
+ ␊
+ var main = {};␊
+ ␊
+ const commonjsRegister$1 = commonjsRegister;␊
+ commonjsRegister$1("/$$rollup_base$$/fixtures/function/dynamic-require-alias-hack/stub.js", function (module, exports) {␊
+ ␊
+ });␊
+ ␊
+ /* eslint-disable global-require */␊
+ // noinspection UnnecessaryLocalVariableJS␊
+ ␊
+ // A hack used in many old libraries, saying "workaround to exclude package from browserify list."␊
+ // Will bypass rollup-commonjs finding out that this is a require that should not go through the plugin, and will do an infinite search.␊
+ let _require = commonjsRequire;␊
+ let buffer = _require('buffer');␊
+ ␊
+ t.is(buffer, require$$0__default['default']);␊
+ ␊
+ module.exports = main;␊
+ `,
+ }
diff --git a/packages/commonjs/test/snapshots/function.js.snap b/packages/commonjs/test/snapshots/function.js.snap
index 64dda0340..73e94fa4d 100644
Binary files a/packages/commonjs/test/snapshots/function.js.snap and b/packages/commonjs/test/snapshots/function.js.snap differ
diff --git a/packages/commonjs/types/index.d.ts b/packages/commonjs/types/index.d.ts
index 2b0b06797..d861962f2 100644
--- a/packages/commonjs/types/index.d.ts
+++ b/packages/commonjs/types/index.d.ts
@@ -175,6 +175,12 @@ interface RollupCommonJSOptions {
* replacing strings like `"/Users/John/Desktop/foo-project/"` -> `"/"`.
*/
dynamicRequireTargets?: string | ReadonlyArray;
+
+ /**
+ * Max depth for `node_modules` lookup algorithm in the virtual `require` realm.
+ * This is here for safety, in case of a dynamic require to something that does not exist.
+ */
+ nodeModulesLookupDepth?: number;
}
/**