1
+ 'use strict' ;
2
+
3
+ Object . defineProperty ( exports , "__esModule" , {
4
+ value : true
5
+ } ) ;
6
+
7
+ var _createClass = function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ( ) ;
8
+
9
+ var _typeof = typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ? function ( obj ) { return typeof obj ; } : function ( obj ) { return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ; } ;
10
+
11
+ var _react = require ( 'react' ) ;
12
+
13
+ var _react2 = _interopRequireDefault ( _react ) ;
14
+
15
+ function _interopRequireDefault ( obj ) { return obj && obj . __esModule ? obj : { default : obj } ; }
16
+
17
+ function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
18
+
19
+ function _possibleConstructorReturn ( self , call ) { if ( ! self ) { throw new ReferenceError ( "this hasn't been initialised - super() hasn't been called" ) ; } return call && ( typeof call === "object" || typeof call === "function" ) ? call : self ; }
20
+
21
+ function _inherits ( subClass , superClass ) { if ( typeof superClass !== "function" && superClass !== null ) { throw new TypeError ( "Super expression must either be null or a function, not " + typeof superClass ) ; } subClass . prototype = Object . create ( superClass && superClass . prototype , { constructor : { value : subClass , enumerable : false , writable : true , configurable : true } } ) ; if ( superClass ) Object . setPrototypeOf ? Object . setPrototypeOf ( subClass , superClass ) : subClass . __proto__ = superClass ; }
22
+
23
+ var validSSRModes = [ 'render' , 'defer' , 'boundary' ] ;
24
+
25
+ function asyncComponent ( args ) {
26
+ var name = args . name ,
27
+ resolve = args . resolve ,
28
+ _args$autoResolveES = args . autoResolveES2015Default ,
29
+ autoResolveES2015Default = _args$autoResolveES === undefined ? true : _args$autoResolveES ,
30
+ _args$serverMode = args . serverMode ,
31
+ serverMode = _args$serverMode === undefined ? 'render' : _args$serverMode ,
32
+ LoadingComponent = args . LoadingComponent ,
33
+ ErrorComponent = args . ErrorComponent ;
34
+
35
+
36
+ if ( validSSRModes . indexOf ( serverMode ) === - 1 ) {
37
+ throw new Error ( 'Invalid serverMode provided to asyncComponent' ) ;
38
+ }
39
+
40
+ var env = typeof window === 'undefined' ? 'node' : 'browser' ;
41
+
42
+ var sharedState = {
43
+ // A unique id we will assign to our async component which is especially
44
+ // useful when rehydrating server side rendered async components.
45
+ id : null ,
46
+ // This will be use to hold the resolved module allowing sharing across
47
+ // instances.
48
+ // NOTE: When using React Hot Loader this reference will become null.
49
+ module : null ,
50
+ // If an error occurred during a resolution it will be stored here.
51
+ error : null ,
52
+ // Allows us to share the resolver promise across instances.
53
+ resolver : null
54
+ } ;
55
+
56
+ // Takes the given module and if it has a ".default" the ".default" will
57
+ // be returned. i.e. handy when you could be dealing with es6 imports.
58
+ var es6Resolve = function es6Resolve ( x ) {
59
+ return autoResolveES2015Default && x != null && ( typeof x === 'function' || ( typeof x === 'undefined' ? 'undefined' : _typeof ( x ) ) === 'object' ) && x . default ? x . default : x ;
60
+ } ;
61
+
62
+ var getResolver = function getResolver ( ) {
63
+ if ( sharedState . resolver == null ) {
64
+ try {
65
+ // Wrap whatever the user returns in Promise.resolve to ensure a Promise
66
+ // is always returned.
67
+ var resolver = resolve ( ) ;
68
+ sharedState . resolver = Promise . resolve ( resolver ) ;
69
+ } catch ( err ) {
70
+ sharedState . resolver = Promise . reject ( err ) ;
71
+ }
72
+ }
73
+ return sharedState . resolver ;
74
+ } ;
75
+
76
+ var AsyncComponent = function ( _React$Component ) {
77
+ _inherits ( AsyncComponent , _React$Component ) ;
78
+
79
+ function AsyncComponent ( props , context ) {
80
+ _classCallCheck ( this , AsyncComponent ) ;
81
+
82
+ // We have to set the id in the constructor because a RHL seems
83
+ // to recycle the module and therefore the id closure will be null.
84
+ // We can't put it in componentWillMount as RHL hot swaps the new code
85
+ // so the mount call will not happen (but the ctor does).
86
+ var _this = _possibleConstructorReturn ( this , ( AsyncComponent . __proto__ || Object . getPrototypeOf ( AsyncComponent ) ) . call ( this , props , context ) ) ;
87
+
88
+ if ( _this . context . asyncComponents && ! sharedState . id ) {
89
+ sharedState . id = _this . context . asyncComponents . getNextId ( ) ;
90
+ }
91
+ return _this ;
92
+ }
93
+
94
+ _createClass ( AsyncComponent , [ {
95
+ key : 'getChildContext' ,
96
+ value : function getChildContext ( ) {
97
+ if ( ! this . context . asyncComponents ) {
98
+ return undefined ;
99
+ }
100
+
101
+ return {
102
+ asyncComponentsAncestor : {
103
+ isBoundary : serverMode === 'boundary'
104
+ }
105
+ } ;
106
+ }
107
+ } , {
108
+ key : 'componentWillMount' ,
109
+ value : function componentWillMount ( ) {
110
+ this . setState ( { module : sharedState . module } ) ;
111
+ if ( sharedState . error ) {
112
+ this . registerErrorState ( sharedState . error ) ;
113
+ }
114
+ }
115
+ } , {
116
+ key : 'componentDidMount' ,
117
+ value : function componentDidMount ( ) {
118
+ if ( ! this . state . module ) {
119
+ this . resolveModule ( ) ;
120
+ }
121
+ }
122
+
123
+ // @see react-async-bootstrapper
124
+
125
+ } , {
126
+ key : 'asyncBootstrap' ,
127
+ value : function asyncBootstrap ( ) {
128
+ var _this2 = this ;
129
+
130
+ var _context = this . context ,
131
+ asyncComponents = _context . asyncComponents ,
132
+ asyncComponentsAncestor = _context . asyncComponentsAncestor ;
133
+ var shouldRehydrate = asyncComponents . shouldRehydrate ;
134
+
135
+
136
+ var doResolve = function doResolve ( ) {
137
+ return _this2 . resolveModule ( ) . then ( function ( module ) {
138
+ return module !== undefined ;
139
+ } ) ;
140
+ } ;
141
+
142
+ if ( typeof window !== 'undefined' ) {
143
+ // BROWSER BASED LOGIC
144
+ return shouldRehydrate ( sharedState . id ) ? doResolve ( ) : false ;
145
+ }
146
+
147
+ // SERVER BASED LOGIC
148
+ var isChildOfBoundary = asyncComponentsAncestor && asyncComponentsAncestor . isBoundary ;
149
+ return serverMode === 'defer' || isChildOfBoundary ? false : doResolve ( ) ;
150
+ }
151
+ } , {
152
+ key : 'resolveModule' ,
153
+ value : function resolveModule ( ) {
154
+ var _this3 = this ;
155
+
156
+ this . resolving = true ;
157
+
158
+ return getResolver ( ) . then ( function ( module ) {
159
+ if ( _this3 . unmounted ) {
160
+ return undefined ;
161
+ }
162
+ if ( _this3 . context . asyncComponents ) {
163
+ _this3 . context . asyncComponents . resolved ( sharedState . id ) ;
164
+ }
165
+ sharedState . module = module ;
166
+ if ( env === 'browser' ) {
167
+ _this3 . setState ( { module : module } ) ;
168
+ }
169
+ _this3 . resolving = false ;
170
+ return module ;
171
+ } ) . catch ( function ( error ) {
172
+ if ( _this3 . unmounted ) {
173
+ return undefined ;
174
+ }
175
+ if ( env === 'node' || ! ErrorComponent ) {
176
+ // We will at least log the error so that user isn't completely
177
+ // unaware of an error occurring.
178
+ // eslint-disable-next-line no-console
179
+ // console.warn('Failed to resolve asyncComponent')
180
+ // eslint-disable-next-line no-console
181
+ // console.warn(error)
182
+ }
183
+ sharedState . error = error ;
184
+ _this3 . registerErrorState ( error ) ;
185
+ _this3 . resolving = false ;
186
+ return undefined ;
187
+ } ) ;
188
+ }
189
+ } , {
190
+ key : 'componentWillUnmount' ,
191
+ value : function componentWillUnmount ( ) {
192
+ this . unmounted = true ;
193
+ }
194
+ } , {
195
+ key : 'registerErrorState' ,
196
+ value : function registerErrorState ( error ) {
197
+ var _this4 = this ;
198
+
199
+ if ( env === 'browser' ) {
200
+ setTimeout ( function ( ) {
201
+ if ( ! _this4 . unmounted ) {
202
+ _this4 . setState ( { error : error } ) ;
203
+ }
204
+ } , 16 ) ;
205
+ }
206
+ }
207
+ } , {
208
+ key : 'render' ,
209
+ value : function render ( ) {
210
+ var _state = this . state ,
211
+ module = _state . module ,
212
+ error = _state . error ;
213
+
214
+ // This is as workaround for React Hot Loader support. When using
215
+ // RHL the local component reference will be killed by any change
216
+ // to the component, this will be our signal to know that we need to
217
+ // re-resolve it.
218
+
219
+ if ( sharedState . module == null && ! this . resolving && typeof window !== 'undefined' ) {
220
+ this . resolveModule ( ) ;
221
+ }
222
+
223
+ if ( error ) {
224
+ return ErrorComponent ? _react2 . default . createElement ( ErrorComponent , { error : error } ) : null ;
225
+ }
226
+
227
+ var Component = es6Resolve ( module ) ;
228
+ // eslint-disable-next-line no-nested-ternary
229
+ return Component ? _react2 . default . createElement ( Component , this . props ) : LoadingComponent ? _react2 . default . createElement ( LoadingComponent , this . props ) : null ;
230
+ }
231
+ } ] ) ;
232
+
233
+ return AsyncComponent ;
234
+ } ( _react2 . default . Component ) ;
235
+
236
+ AsyncComponent . childContextTypes = {
237
+ asyncComponentsAncestor : _react2 . default . PropTypes . shape ( {
238
+ isBoundary : _react2 . default . PropTypes . bool
239
+ } )
240
+ } ;
241
+
242
+ AsyncComponent . contextTypes = {
243
+ asyncComponentsAncestor : _react2 . default . PropTypes . shape ( {
244
+ isBoundary : _react2 . default . PropTypes . bool
245
+ } ) ,
246
+ asyncComponents : _react2 . default . PropTypes . shape ( {
247
+ getNextId : _react2 . default . PropTypes . func . isRequired ,
248
+ resolved : _react2 . default . PropTypes . func . isRequired ,
249
+ shouldRehydrate : _react2 . default . PropTypes . func . isRequired
250
+ } )
251
+ } ;
252
+
253
+ AsyncComponent . displayName = name || 'AsyncComponent' ;
254
+
255
+ return AsyncComponent ;
256
+ }
257
+
258
+ exports . default = asyncComponent ;
0 commit comments