Skip to content

Commit 8d6b60c

Browse files
adamjernstfacebook-github-bot
authored andcommitted
Dev-only warning about require cycles in require polyfill
Reviewed By: rafeca Differential Revision: D8928342 fbshipit-source-id: f4ebad5daefd8da6444ca9d6fa1458a338ac7b20
1 parent 90bf14a commit 8d6b60c

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

packages/metro/src/integration_tests/__tests__/__snapshots__/basic_bundle-test.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ exports[`basic_bundle bundles package with polyfills 1`] = `
118118
module.isInitialized = false;
119119
module.exports = undefined;
120120
throw e;
121-
}
121+
} finally {}
122122
}
123123
124124
function unknownModuleError(id) {
@@ -313,7 +313,7 @@ exports[`basic_bundle bundles package without polyfills 1`] = `
313313
module.isInitialized = false;
314314
module.exports = undefined;
315315
throw e;
316-
}
316+
} finally {}
317317
}
318318
319319
function unknownModuleError(id) {

packages/metro/src/lib/polyfills/require.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ if (__DEV__) {
6969
[key: string]: number,
7070
__proto__: null,
7171
} = Object.create(null);
72+
var initializingModuleIds: Array<number> = [];
7273
}
7374

7475
function define(
@@ -146,6 +147,23 @@ function metroRequire(moduleId: ModuleID | VerboseModuleNameForDev) {
146147

147148
//$FlowFixMe: at this point we know that moduleId is a number
148149
const moduleIdReallyIsNumber: number = moduleId;
150+
if (__DEV__) {
151+
const initializingIndex = initializingModuleIds.indexOf(
152+
moduleIdReallyIsNumber,
153+
);
154+
if (initializingIndex !== -1) {
155+
const cycle = initializingModuleIds
156+
.slice(initializingIndex)
157+
.map(id => modules[id].verboseName);
158+
// We want to show A -> B -> A:
159+
cycle.push(cycle[0]);
160+
console.warn(
161+
`Require cycle: ${cycle.join(' -> ')}\n\n` +
162+
'Require cycles are allowed, but can result in uninitialized values. ' +
163+
'Consider refactoring to remove the need for a cycle.',
164+
);
165+
}
166+
}
149167
const module = modules[moduleIdReallyIsNumber];
150168
return module && module.isInitialized
151169
? module.exports
@@ -222,6 +240,9 @@ function loadModuleImplementation(moduleId, module) {
222240
module.isInitialized = true;
223241
const exports = (module.exports = {});
224242
const {factory, dependencyMap} = module;
243+
if (__DEV__) {
244+
initializingModuleIds.push(moduleId);
245+
}
225246
try {
226247
if (PRINT_REQUIRE_PATHS) {
227248
console.log(`require file path ${module.path || 'unknown'}`); // eslint-disable-line no-console
@@ -259,6 +280,14 @@ function loadModuleImplementation(moduleId, module) {
259280
module.isInitialized = false;
260281
module.exports = undefined;
261282
throw e;
283+
} finally {
284+
if (__DEV__) {
285+
if (initializingModuleIds.pop() !== moduleId) {
286+
throw new Error(
287+
'initializingModuleIds is corrupt; something is terribly wrong',
288+
);
289+
}
290+
}
262291
}
263292
}
264293

0 commit comments

Comments
 (0)