Skip to content

Commit f871d25

Browse files
Jean Lauliacfacebook-github-bot
Jean Lauliac
authored andcommittedDec 14, 2017
metro-buck: check validity of segments
Reviewed By: davidaurelio Differential Revision: D6496312 fbshipit-source-id: 586dc8d9f64d13cfddaf6bfe768e8f7b3442561a
1 parent 59c3e33 commit f871d25

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed
 

‎Libraries/Utilities/asyncRequire.js

+43-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
'use strict';
1515

16+
const dynamicRequire: number => mixed = (require: $FlowFixMe);
17+
1618
/**
1719
* The bundler must register the dependency properly when generating a call to
1820
* `asyncRequire`, that allows us to call `require` dynamically with confidence
@@ -24,7 +26,7 @@ function asyncRequire(moduleID: number): Promise<mixed> {
2426
const {segmentId} = (require: $FlowFixMe).unpackModuleId(moduleID);
2527
return loadSegment(segmentId);
2628
})
27-
.then(() => require.call(null, (moduleID: $FlowFixMe)));
29+
.then(() => dynamicRequire(moduleID));
2830
}
2931

3032
let segmentLoaders = new Map();
@@ -45,6 +47,10 @@ function loadSegment(segmentId: number): Promise<void> {
4547
if (segmentId === 0) {
4648
return;
4749
}
50+
if (typeof global.__BUNDLE_DIGEST__ !== 'string') {
51+
throw IncorrectBundleSetupError();
52+
}
53+
const globalDigest = global.__BUNDLE_DIGEST__;
4854
let segmentLoader = segmentLoaders.get(segmentId);
4955
if (segmentLoader != null) {
5056
return segmentLoader;
@@ -61,6 +67,19 @@ function loadSegment(segmentId: number): Promise<void> {
6167
}
6268
resolve();
6369
});
70+
}).then(() => {
71+
const metaModuleId = (require: $FlowFixMe).packModuleId({
72+
segmentId,
73+
localId: 0,
74+
});
75+
const metaModule = dynamicRequire(metaModuleId);
76+
const digest: string =
77+
typeof metaModule === 'object' && metaModule != null
78+
? (metaModule.BUNDLE_DIGEST: $FlowFixMe)
79+
: 'undefined';
80+
if (digest !== globalDigest) {
81+
throw new IncompatibleSegmentError(globalDigest, digest);
82+
}
6483
});
6584
segmentLoaders.set(segmentId, segmentLoader);
6685
return segmentLoader;
@@ -76,4 +95,27 @@ class FetchSegmentNotAvailableError extends Error {
7695
}
7796
}
7897

98+
class IncorrectBundleSetupError extends Error {
99+
constructor() {
100+
super(
101+
'To be able to use split segments, the bundler must define a global ' +
102+
'constant `__BUNDLE_DIGEST__` that identifies the bundle uniquely.',
103+
);
104+
}
105+
}
106+
asyncRequire.IncorrectBundleSetupError = IncorrectBundleSetupError;
107+
108+
class IncompatibleSegmentError extends Error {
109+
constructor(globalDigest, segmentDigest) {
110+
super(
111+
'The split segment that is being loaded has been built from a ' +
112+
'different version of the code than the main segment. Or, the ' +
113+
'bundler is setting up the module #0 of the segment incorrectly. ' +
114+
`The global digest is \`${globalDigest}\` while the segment is ` +
115+
`\`${segmentDigest}\`.`,
116+
);
117+
}
118+
}
119+
asyncRequire.IncompatibleSegmentError = IncompatibleSegmentError;
120+
79121
module.exports = asyncRequire;

0 commit comments

Comments
 (0)
Please sign in to comment.