Hot Loading Indicators
Summary: public Introduce a header bar similar to the one shown when loading the bundle to indicate that the packager server is processing an HMR update. Hook into HMR events to show this bar when appropriate. Reviewed By: javache Differential Revision: D2873521 fb-gh-sync-id: a77cbb2368b75b045aa8c6ababce2f731baf514b
This commit is contained in:
parent
180ead05e9
commit
36efbc341d
|
@ -11,6 +11,7 @@
|
|||
'use strict';
|
||||
|
||||
const invariant = require('invariant');
|
||||
const processColor = require('processColor');
|
||||
|
||||
/**
|
||||
* HMR Client that receives from the server HMR updates and propagates them
|
||||
|
@ -49,39 +50,60 @@ Error: ${e.message}`
|
|||
);
|
||||
};
|
||||
activeWS.onmessage = ({data}) => {
|
||||
const DevLoadingView = require('NativeModules').DevLoadingView;
|
||||
data = JSON.parse(data);
|
||||
if (data.type === 'update') {
|
||||
const modules = data.body.modules;
|
||||
const sourceMappingURLs = data.body.sourceMappingURLs;
|
||||
const sourceURLs = data.body.sourceURLs;
|
||||
|
||||
const RCTRedBox = require('NativeModules').RedBox;
|
||||
RCTRedBox && RCTRedBox.dismiss && RCTRedBox.dismiss();
|
||||
switch(data.type) {
|
||||
case 'update-start': {
|
||||
DevLoadingView.showMessage(
|
||||
'Hot Loading...',
|
||||
processColor('#000000'),
|
||||
processColor('#aaaaaa'),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'update': {
|
||||
const modules = data.body.modules;
|
||||
const sourceMappingURLs = data.body.sourceMappingURLs;
|
||||
const sourceURLs = data.body.sourceURLs;
|
||||
|
||||
modules.forEach((code, i) => {
|
||||
code = code + '\n\n' + sourceMappingURLs[i];
|
||||
const RCTRedBox = require('NativeModules').RedBox;
|
||||
RCTRedBox && RCTRedBox.dismiss && RCTRedBox.dismiss();
|
||||
|
||||
require('SourceMapsCache').fetch({
|
||||
text: code,
|
||||
url: sourceURLs[i],
|
||||
sourceMappingURL: sourceMappingURLs[i],
|
||||
modules.forEach((code, i) => {
|
||||
code = code + '\n\n' + sourceMappingURLs[i];
|
||||
|
||||
require('SourceMapsCache').fetch({
|
||||
text: code,
|
||||
url: sourceURLs[i],
|
||||
sourceMappingURL: sourceMappingURLs[i],
|
||||
});
|
||||
|
||||
// on JSC we need to inject from native for sourcemaps to work
|
||||
// (Safari doesn't support `sourceMappingURL` nor any variant when
|
||||
// evaluating code) but on Chrome we can simply use eval
|
||||
const injectFunction = typeof __injectHMRUpdate === 'function'
|
||||
? __injectHMRUpdate
|
||||
: eval;
|
||||
|
||||
injectFunction(code, sourceURLs[i]);
|
||||
});
|
||||
|
||||
// on JSC we need to inject from native for sourcemaps to work
|
||||
// (Safari doesn't support `sourceMappingURL` nor any variant when
|
||||
// evaluating code) but on Chrome we can simply use eval
|
||||
const injectFunction = typeof __injectHMRUpdate === 'function'
|
||||
? __injectHMRUpdate
|
||||
: eval;
|
||||
|
||||
injectFunction(code, sourceURLs[i]);
|
||||
})
|
||||
return;
|
||||
DevLoadingView.hide();
|
||||
break;
|
||||
}
|
||||
case 'update-done': {
|
||||
DevLoadingView.hide();
|
||||
break;
|
||||
}
|
||||
case 'error': {
|
||||
DevLoadingView.hide();
|
||||
throw new Error(data.body.type + ' ' + data.body.description);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unexpected message: ${data}`);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add support for opening filename by clicking on the stacktrace
|
||||
const error = data.body;
|
||||
throw new Error(error.type + ' ' + error.description);
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -55,14 +55,13 @@ RCT_EXPORT_MODULE()
|
|||
[self showWithURL:bridge.bundleURL];
|
||||
}
|
||||
|
||||
- (void)showWithURL:(NSURL *)URL
|
||||
RCT_EXPORT_METHOD(showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(UIColor *)backgroundColor)
|
||||
{
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
_showDate = [NSDate date];
|
||||
if (!_window && !RCTRunningInTestEnvironment()) {
|
||||
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
|
||||
|
@ -77,34 +76,23 @@ RCT_EXPORT_MODULE()
|
|||
[_window makeKeyAndVisible];
|
||||
}
|
||||
|
||||
NSString *source;
|
||||
if (URL.fileURL) {
|
||||
_window.backgroundColor = [UIColor blackColor];
|
||||
_label.textColor = [UIColor grayColor];
|
||||
source = @"pre-bundled file";
|
||||
} else {
|
||||
_window.backgroundColor = [UIColor colorWithHue:1./3 saturation:1 brightness:.35 alpha:1];
|
||||
_label.textColor = [UIColor whiteColor];
|
||||
source = [NSString stringWithFormat:@"%@:%@", URL.host, URL.port];
|
||||
}
|
||||
|
||||
_label.text = [NSString stringWithFormat:@"Loading from %@...", source];
|
||||
_label.text = message;
|
||||
_label.textColor = color;
|
||||
_window.backgroundColor = backgroundColor;
|
||||
_window.hidden = NO;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)hide
|
||||
RCT_EXPORT_METHOD(hide)
|
||||
{
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
const NSTimeInterval MIN_PRESENTED_TIME = 0.6;
|
||||
NSTimeInterval presentedTime = [[NSDate date] timeIntervalSinceDate:_showDate];
|
||||
NSTimeInterval delay = MAX(0, MIN_PRESENTED_TIME - presentedTime);
|
||||
|
||||
CGRect windowFrame = _window.frame;
|
||||
[UIView animateWithDuration:0.25
|
||||
delay:delay
|
||||
|
@ -119,6 +107,26 @@ RCT_EXPORT_MODULE()
|
|||
});
|
||||
}
|
||||
|
||||
- (void)showWithURL:(NSURL *)URL
|
||||
{
|
||||
UIColor *color;
|
||||
UIColor *backgroundColor;
|
||||
NSString *source;
|
||||
if (URL.fileURL) {
|
||||
color = [UIColor grayColor];
|
||||
backgroundColor = [UIColor blackColor];
|
||||
source = @"pre-bundled file";
|
||||
} else {
|
||||
color = [UIColor whiteColor];
|
||||
backgroundColor = [UIColor colorWithHue:1./3 saturation:1 brightness:.35 alpha:1];
|
||||
source = [NSString stringWithFormat:@"%@:%@", URL.host, URL.port];
|
||||
}
|
||||
|
||||
[self showMessage:[NSString stringWithFormat:@"Loading from %@...", source]
|
||||
color:color
|
||||
backgroundColor:backgroundColor];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
|
|
|
@ -112,6 +112,7 @@ function attachHMRServer({httpServer, path, packagerServer}) {
|
|||
return;
|
||||
}
|
||||
|
||||
client.ws.send(JSON.stringify({type: 'update-start'}));
|
||||
stat.then(() => {
|
||||
return packagerServer.getShallowDependencies(filename)
|
||||
.then(deps => {
|
||||
|
@ -240,7 +241,9 @@ function attachHMRServer({httpServer, path, packagerServer}) {
|
|||
() => {
|
||||
// do nothing, file was removed
|
||||
},
|
||||
);
|
||||
).finally(() => {
|
||||
client.ws.send(JSON.stringify({type: 'update-done'}));
|
||||
});
|
||||
});
|
||||
|
||||
client.ws.on('error', e => {
|
||||
|
|
Loading…
Reference in New Issue