Pipe `platform` and `bundleEntry` through WebSocket connection
Reviewed By: vjeux Differential Revision: D2793572 fb-gh-sync-id: 6ce2467b8d528d1a91c1b4fc51741f2502674022
This commit is contained in:
Родитель
dd8e1f91d8
Коммит
5f850fbede
|
@ -10,12 +10,17 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
const invariant = require('invariant');
|
||||
|
||||
/**
|
||||
* HMR Client that receives from the server HMR updates and propagates them
|
||||
* runtime to reflects those changes.
|
||||
*/
|
||||
const HMRClient = {
|
||||
enable() {
|
||||
enable(platform, bundleEntry) {
|
||||
invariant(platform, 'Missing required parameter `platform`');
|
||||
invariant(bundleEntry, 'Missing required paramenter `bundleEntry`');
|
||||
|
||||
// need to require WebSocket inside of `enable` function because the
|
||||
// this module is defined as a `polyfillGlobal`.
|
||||
// See `InitializeJavascriptAppEngine.js`
|
||||
|
@ -23,7 +28,10 @@ const HMRClient = {
|
|||
|
||||
// TODO(martinb): parametrize the url and receive entryFile to minimize
|
||||
// the number of updates we want to receive from the server.
|
||||
const activeWS = new WebSocket('ws://localhost:8081/hot');
|
||||
const activeWS = new WebSocket(
|
||||
'ws://localhost:8081/hot?platform=' + platform + '&bundleEntry=' +
|
||||
bundleEntry.replace('.bundle', '.js')
|
||||
);
|
||||
activeWS.onerror = (e) => {
|
||||
console.error('[Hot Module Replacement] Unexpected error', e);
|
||||
};
|
||||
|
|
|
@ -90,6 +90,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
|||
{
|
||||
RCTJavaScriptContext *_context;
|
||||
NSThread *_javaScriptThread;
|
||||
NSURL *_bundleURL;
|
||||
}
|
||||
|
||||
@synthesize valid = _valid;
|
||||
|
@ -145,22 +146,22 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL isHotLoadingEnabled()
|
||||
{
|
||||
NSString *enabledQS = [[RCTBundleURLProcessor sharedProcessor] getQueryStringValue:@"hot"];
|
||||
return (enabledQS != nil && [enabledQS isEqualToString:@"true"]) ? YES : NO;
|
||||
}
|
||||
|
||||
static void RCTInstallHotLoading(RCTBridge *bridge, RCTJSCExecutor *executor)
|
||||
{
|
||||
[bridge.devMenu addItem:[RCTDevMenuItem toggleItemWithKey:RCTHotLoadingEnabledDefaultsKey title:@"Enable Hot Loading" selectedTitle:@"Disable Hot Loading" handler:^(BOOL enabledOnCurrentBundle) {
|
||||
[executor executeBlockOnJavaScriptQueue:^{
|
||||
NSString *enabledQS = [[RCTBundleURLProcessor sharedProcessor] getQueryStringValue:@"hot"];
|
||||
BOOL enabledOnConfig = (enabledQS != nil && [enabledQS isEqualToString:@"true"]) ? YES : NO;
|
||||
|
||||
BOOL enabledOnConfig = isHotLoadingEnabled();
|
||||
// reload bundle when user change Hot Loading setting
|
||||
if (enabledOnConfig != enabledOnCurrentBundle) {
|
||||
[[RCTBundleURLProcessor sharedProcessor] setQueryStringValue:enabledOnCurrentBundle ? @"true" : @"false" forAttribute:@"hot"];
|
||||
[bridge reload];
|
||||
}
|
||||
|
||||
if (enabledOnCurrentBundle) {
|
||||
[bridge enqueueJSCall:@"HMRClient.enable" args:@[@YES]];
|
||||
}
|
||||
}];
|
||||
}]];
|
||||
}
|
||||
|
@ -534,6 +535,13 @@ static void RCTInstallHotLoading(RCTBridge *bridge, RCTJSCExecutor *executor)
|
|||
onComplete(error);
|
||||
}
|
||||
}), 0, @"js_call", (@{ @"url": sourceURL.absoluteString }))];
|
||||
|
||||
#if RCT_DEV
|
||||
if (isHotLoadingEnabled()) {
|
||||
// strip initial slash
|
||||
[_bridge enqueueJSCall:@"HMRClient.enable" args:@[@"ios", [sourceURL.path substringFromIndex: 1]]];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block
|
||||
|
|
|
@ -8,28 +8,30 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
const querystring = require('querystring');
|
||||
const url = require('url');
|
||||
|
||||
/**
|
||||
* Attaches a WebSocket based connection to the Packager to expose
|
||||
* Hot Module Replacement updates to the simulator.
|
||||
*/
|
||||
function attachHMRServer({httpServer, path, packagerServer}) {
|
||||
let activeWS;
|
||||
let client = null;
|
||||
|
||||
function disconnect() {
|
||||
activeWS = null;
|
||||
client = null;
|
||||
}
|
||||
|
||||
packagerServer.addFileChangeListener(filename => {
|
||||
if (!activeWS) {
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
packagerServer.buildBundleForHMR({
|
||||
entryFile: filename,
|
||||
// TODO(martinb): receive platform on query string when client connects
|
||||
platform: 'ios',
|
||||
platform: client.platform,
|
||||
})
|
||||
.then(bundle => activeWS.send(bundle));
|
||||
.then(bundle => client.ws.send(bundle));
|
||||
});
|
||||
|
||||
const WebSocketServer = require('ws').Server;
|
||||
|
@ -41,14 +43,19 @@ function attachHMRServer({httpServer, path, packagerServer}) {
|
|||
console.log('[Hot Module Replacement] Server listening on', path);
|
||||
wss.on('connection', ws => {
|
||||
console.log('[Hot Module Replacement] Client connected');
|
||||
activeWS = ws;
|
||||
const params = querystring.parse(url.parse(ws.upgradeReq.url).query);
|
||||
client = {
|
||||
ws,
|
||||
platform: params.platform,
|
||||
bundleEntry: params.bundleEntry,
|
||||
};
|
||||
|
||||
ws.on('error', e => {
|
||||
client.ws.on('error', e => {
|
||||
console.error('[Hot Module Replacement] Unexpected error', e);
|
||||
disconnect();
|
||||
});
|
||||
|
||||
ws.on('close', () => disconnect());
|
||||
client.ws.on('close', () => disconnect());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче