13
13
14
14
'use strict' ;
15
15
16
+ const dynamicRequire : number => mixed = ( require : $FlowFixMe ) ;
17
+
16
18
/**
17
19
* The bundler must register the dependency properly when generating a call to
18
20
* `asyncRequire`, that allows us to call `require` dynamically with confidence
@@ -24,7 +26,7 @@ function asyncRequire(moduleID: number): Promise<mixed> {
24
26
const { segmentId} = ( require : $FlowFixMe ) . unpackModuleId ( moduleID ) ;
25
27
return loadSegment ( segmentId ) ;
26
28
} )
27
- . then ( ( ) => require . call ( null , ( moduleID : $FlowFixMe ) ) ) ;
29
+ . then ( ( ) => dynamicRequire ( moduleID ) ) ;
28
30
}
29
31
30
32
let segmentLoaders = new Map ( ) ;
@@ -45,6 +47,10 @@ function loadSegment(segmentId: number): Promise<void> {
45
47
if ( segmentId === 0 ) {
46
48
return ;
47
49
}
50
+ if ( typeof global . __BUNDLE_DIGEST__ !== 'string' ) {
51
+ throw IncorrectBundleSetupError ( ) ;
52
+ }
53
+ const globalDigest = global . __BUNDLE_DIGEST__ ;
48
54
let segmentLoader = segmentLoaders . get ( segmentId ) ;
49
55
if ( segmentLoader != null ) {
50
56
return segmentLoader ;
@@ -61,6 +67,19 @@ function loadSegment(segmentId: number): Promise<void> {
61
67
}
62
68
resolve ( ) ;
63
69
} ) ;
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
+ }
64
83
} ) ;
65
84
segmentLoaders . set ( segmentId , segmentLoader ) ;
66
85
return segmentLoader ;
@@ -76,4 +95,27 @@ class FetchSegmentNotAvailableError extends Error {
76
95
}
77
96
}
78
97
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
+
79
121
module . exports = asyncRequire ;
0 commit comments