Description
The goal of this issue is to run RN's JS within Node instead of Chrome to reduce the number of moving parts and asynchrony.
How things currently work
Currently when turning on Chrome debugging, RN on the device opens a WebSocket connection to the packager server, which opens a small page in Chrome that opens another WebSocket connection to the packager:
[RN] <-- ws --> [packager] <-- ws --> [Chrome]
RN then sends the bundle URL to the packager, which forwards it to Chrome. Chrome then creates a Web Worker in which the bundle JS is executed. So there's quite a bit of asynchrony here:
[RN] <-- ws --> [packager] <-- ws --> [Chrome] <-- postMessage --> [Worker]
How we can simplify this
Node 6.3 supports V8's debugger out of the box. Node gives you a link that we can open in Chrome, and it shows a full-screen debugger that is focused solely on JS and not the other browser features. So, we no longer need to run the JS in Chrome for it to be debuggable with familiar tools. This is the new plan:
[RN] <-- ws --> [packager] <-- child_process --> [node --inspect]
Already you can see there's one less asynchronous communication step, and we replace the second WebSocket connection with child_process.fork
, which is easier to set up and keep alive.
Things to figure out
- Loading the script: With Chrome we could use
importScripts()
in the Web Worker to load the JS bundle. With Node that doesn't exist, so we'll need to manually download the script to a temporary location on disk and then run it. This isn't hard; just something that needs to be done. - Source maps: We need to make sure that source maps continue to work. I believe they should, as Blink Inspector is responsible for downloading them.
- Using as plain of a JS environment as possible: We don't want Node's APIs available to RN code if possible. I think we can achieve this with
vm.runInContext
from within the Node child process.
Launch plan
We should keep the Chrome debugger alive for at least a month (two RN releases) or perhaps until Node 6 hits LTS (October 1). My sense is the event that actually matters is when Facebook is able to use Node 6 internally -- once that happens FB probably won't want to maintain the Chrome debugger and will want to focus on just the Node debugger instead.