Skip to content

Commit 2d06c44

Browse files
authored
feat(commonjs)!: Add ignore-dynamic-requires option (#819)
BREAKING CHANGES: When dynamicRequireTargets is specified, "require" will be default no longer be used as fallback
1 parent 8752c2f commit 2d06c44

File tree

33 files changed

+761
-466
lines changed

33 files changed

+761
-466
lines changed

packages/commonjs/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,25 @@ Due to the conversion of `require` to a static `import` - the call is hoisted to
134134
- `string[]`: Pass an array containing the IDs to left unconverted.
135135
- `((id: string) => boolean|'remove')`: Pass a function that control individual IDs.
136136

137+
### `ignoreDynamicRequires`
138+
139+
Type: `boolean`
140+
Default: false
141+
142+
Some `require` calls cannot be resolved statically to be translated to imports, e.g.
143+
144+
```js
145+
function wrappedRequire(target) {
146+
return require(target);
147+
}
148+
wrappedRequire('foo');
149+
wrappedRequire('bar');
150+
```
151+
152+
When this option is set to `false`, the generated code will either directly throw an error when such a call is encountered or, when `dynamicRequireTargets` is used, when such a call cannot be resolved with a configured dynamic require target.
153+
154+
Setting this option to `true` will instead leave the `require` call in the code or use it as a fallback for `dynamicRequireTargets`.
155+
137156
### `esmExternals`
138157

139158
Type: `boolean | string[] | ((id: string) => boolean)`

packages/commonjs/src/helpers.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,20 @@ export function getAugmentedNamespace(n) {
4848
}
4949
`;
5050

51+
const FAILED_REQUIRE_ERROR = `throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');`;
52+
5153
const HELPER_NON_DYNAMIC = `
5254
export function createCommonjsModule(fn) {
5355
var module = { exports: {} }
5456
return fn(module, module.exports), module.exports;
5557
}
5658
57-
export function commonjsRequire (target) {
58-
throw new Error('Could not dynamically require "' + target + '". Please configure the dynamicRequireTargets option of @rollup/plugin-commonjs appropriately for this require call to behave properly.');
59+
export function commonjsRequire (path) {
60+
${FAILED_REQUIRE_ERROR}
5961
}
6062
`;
6163

62-
const HELPERS_DYNAMIC = `
64+
const getDynamicHelpers = (ignoreDynamicRequires) => `
6365
export function createCommonjsModule(fn, basedir, module) {
6466
return module = {
6567
path: basedir,
@@ -231,13 +233,15 @@ export function commonjsRequire (path, originalModuleDir) {
231233
return cachedModule.exports;
232234
};
233235
}
234-
return require(path);
236+
${ignoreDynamicRequires ? 'return require(path);' : FAILED_REQUIRE_ERROR}
235237
}
236238
237239
commonjsRequire.cache = DYNAMIC_REQUIRE_CACHE;
238240
commonjsRequire.resolve = commonjsResolve;
239241
`;
240242

241-
export function getHelpersModule(isDynamicRequireModulesEnabled) {
242-
return `${HELPERS}${isDynamicRequireModulesEnabled ? HELPERS_DYNAMIC : HELPER_NON_DYNAMIC}`;
243+
export function getHelpersModule(isDynamicRequireModulesEnabled, ignoreDynamicRequires) {
244+
return `${HELPERS}${
245+
isDynamicRequireModulesEnabled ? getDynamicHelpers(ignoreDynamicRequires) : HELPER_NON_DYNAMIC
246+
}`;
243247
}

packages/commonjs/src/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default function commonjs(options = {}) {
4444
const filter = createFilter(options.include, options.exclude);
4545
const {
4646
ignoreGlobal,
47+
ignoreDynamicRequires,
4748
requireReturnsDefault: requireReturnsDefaultOption,
4849
esmExternals
4950
} = options;
@@ -97,6 +98,7 @@ export default function commonjs(options = {}) {
9798

9899
function transformAndCheckExports(code, id) {
99100
if (isDynamicRequireModulesEnabled && this.getModuleInfo(id).isEntry) {
101+
// eslint-disable-next-line no-param-reassign
100102
code =
101103
getDynamicPackagesEntryIntro(dynamicRequireModuleDirPaths, dynamicRequireModuleSet) + code;
102104
}
@@ -125,6 +127,7 @@ export default function commonjs(options = {}) {
125127
// avoid wrapping in createCommonjsModule, as this is a commonjsRegister call
126128
if (isModuleRegisterProxy(id)) {
127129
disableWrap = true;
130+
// eslint-disable-next-line no-param-reassign
128131
id = unwrapModuleRegisterProxy(id);
129132
}
130133

@@ -135,6 +138,7 @@ export default function commonjs(options = {}) {
135138
isEsModule,
136139
ignoreGlobal || isEsModule,
137140
ignoreRequire,
141+
ignoreDynamicRequires && !isDynamicRequireModulesEnabled,
138142
getIgnoreTryCatchRequireStatementMode,
139143
sourceMap,
140144
isDynamicRequireModulesEnabled,
@@ -161,7 +165,7 @@ export default function commonjs(options = {}) {
161165

162166
load(id) {
163167
if (id === HELPERS_ID) {
164-
return getHelpersModule(isDynamicRequireModulesEnabled);
168+
return getHelpersModule(isDynamicRequireModulesEnabled, ignoreDynamicRequires);
165169
}
166170

167171
if (id.startsWith(HELPERS_ID)) {
@@ -232,6 +236,7 @@ export default function commonjs(options = {}) {
232236
}
233237
},
234238

239+
// eslint-disable-next-line no-shadow
235240
moduleParsed({ id, meta: { commonjs } }) {
236241
if (commonjs) {
237242
const isCjs = commonjs.isCommonJS;

packages/commonjs/src/transform-commonjs.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export default function transformCommonjs(
4646
isEsModule,
4747
ignoreGlobal,
4848
ignoreRequire,
49+
ignoreDynamicRequires,
4950
getIgnoreTryCatchRequireStatementMode,
5051
sourceMap,
5152
isDynamicRequireModulesEnabled,
@@ -320,12 +321,14 @@ export default function transformCommonjs(
320321
)}`
321322
);
322323
}
323-
if (isShorthandProperty(parent)) {
324-
magicString.appendRight(node.end, `: ${HELPERS_NAME}.commonjsRequire`);
325-
} else {
326-
magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsRequire`, {
327-
storeName: true
328-
});
324+
if (!ignoreDynamicRequires) {
325+
if (isShorthandProperty(parent)) {
326+
magicString.appendRight(node.end, `: ${HELPERS_NAME}.commonjsRequire`);
327+
} else {
328+
magicString.overwrite(node.start, node.end, `${HELPERS_NAME}.commonjsRequire`, {
329+
storeName: true
330+
});
331+
}
329332
}
330333

331334
uses.commonjsHelpers = true;

packages/commonjs/test/fixtures/function/dynamic-require-absolute-paths/_config.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

packages/commonjs/test/fixtures/function/dynamic-require-absolute-paths/main.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/commonjs/test/fixtures/function/dynamic-require-absolute-paths/submodule.js

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
description: 'keeps a require call as fallback when configured',
3+
pluginOptions: {
4+
ignoreDynamicRequires: true
5+
}
6+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 'dep';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* eslint-disable import/no-dynamic-require, global-require */
2+
3+
function takeModule(withName) {
4+
return require(withName);
5+
}
6+
7+
// The bundled code will run from test/helpers/util.js
8+
t.is(takeModule('../fixtures/function/dynamic-require-fallback/dep.js'), 'dep');

0 commit comments

Comments
 (0)