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; } /**