mirror of
https://github.com/status-im/react-native.git
synced 2025-01-09 17:15:54 +00:00
f2438b440d
Summary: public To make sourcemaps work on Hot Loading work, we'll need to be able to serve them for each module that is dynamically replaced. To do so we introduced a new parameter to the bundler, namely `entryModuleOnly` to decide whether or not to process the full dependency tree or just the module associated to the entry file. Also we need to add `//sourceMappingURL` to the HMR updates so that in case of an error the runtime retrieves the sourcemaps for the file on which an error occurred from the server. Finally, we need to refactor a bit how we load the HMR updates into JSC. Unfortunately, if the code is eval'ed when an error is thrown, the line and column number are missing. This is a bug/missing feature in JSC. To walkaround the issue we need to eval the code on native. This adds a bit of complexity to HMR as for both platforms we'll have to have a thin module to inject code but I don't see any other alternative. when debugging this is not needed as Chrome supports sourceMappingURLs on eval'ed code Reviewed By: javache Differential Revision: D2841788 fb-gh-sync-id: ad9370d26894527a151cea722463e694c670227e
90 lines
2.8 KiB
JavaScript
90 lines
2.8 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule HMRClient
|
|
*/
|
|
'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(platform, bundleEntry) {
|
|
invariant(platform, 'Missing required parameter `platform`');
|
|
invariant(bundleEntry, 'Missing required paramenter `bundleEntry`');
|
|
|
|
// TODO(martinb) receive host and port as parameters
|
|
const host = 'localhost';
|
|
const port = '8081';
|
|
|
|
// need to require WebSocket inside of `enable` function because
|
|
// this module is defined as a `polyfillGlobal`.
|
|
// See `InitializeJavascriptAppEngine.js`
|
|
const WebSocket = require('WebSocket');
|
|
|
|
const activeWS = new WebSocket(
|
|
`ws://${host}:${port}/hot?platform=${platform}&` +
|
|
`bundleEntry=${bundleEntry.replace('.bundle', '.js')}`
|
|
);
|
|
activeWS.onerror = (e) => {
|
|
throw new Error(
|
|
`Hot loading isn't working because it cannot connect to the development server.
|
|
|
|
Ensure the following:
|
|
- Node server is running and available on the same network
|
|
- run 'npm start' from react-native root
|
|
- Node server URL is correctly set in AppDelegate
|
|
|
|
URL: ${host}:${port}
|
|
|
|
Error: ${e.message}`
|
|
);
|
|
};
|
|
activeWS.onmessage = ({data}) => {
|
|
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();
|
|
|
|
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]);
|
|
})
|
|
return;
|
|
}
|
|
|
|
// TODO: add support for opening filename by clicking on the stacktrace
|
|
const error = data.body;
|
|
throw new Error(error.type + ' ' + error.description);
|
|
};
|
|
},
|
|
};
|
|
|
|
module.exports = HMRClient;
|