First of all, this is not my brilliant effort to get react-native working on Windows, it is the collation of work by others, particularly @mqli and @Bernd Wessels. I've just summarised what worked for me.
If you would prefer to read what I've plagerised, head over to mqli's great gist
- The below is tested with
react-native-cli 0.1.5
,react-native 0.12.0
on Windows 10, node 4.1.1, and Android (physical Nexus 6 and AVD with API v22) - I hope this will all be redundant in a few weeks. Please comment on stuff that is now fixed and I will update this to keep it relevant.
- Sprinkle a bit of YMMV around
Keep this github issue handy, it’s the bucket for all Windows/Linux related tricks to get RN working.
Let's get started...
The official instructions for getting started and android setup should be followed first. You can skip the parts about installing watchman and flow. Downloading all the android stuff can take up to an hour, so don't get too exceted too soon.
Before getting into any react-specific things, make sure you can get one of the demo apps from android studio up and running. Then you know any issues you hit are actually react-native issues.
Not really Windows-specific, but if you downloaded and installed node 4.1.1
you're probably going to have npm3. Sad trombone.
You’re going to have troubles described here so you will need to npm install -g 'npm@<3'
. Run npm -v
to ensure you've downgraded to 2-something
.
From here on in, references to node_modules
refer to the contents of that initialised project.
In node_modules\react-native\packager\react-packager\src\DependencyResolver\index.js
add deps = deps.replace(/\\\\/g,'\\');
at the top of defineModuleCode
(line 166) as per the mqli gist
Then in node_modules\react-native\local-cli\run-packager.js
change the contents to
'use strict';
var path = require('path');
var child_process = require('child_process');
module.exports = function(newWindow) {
if (newWindow) {
child_process.spawnSync('open', [
path.resolve(__dirname, '..', 'packager', 'launchPackager.command')
]);
} else {
child_process.spawn('node', [
path.resolve(__dirname, '..', 'packager', 'packager.js'),
'--projectRoots',
process.cwd(),
], {stdio: 'inherit'});
}
};
as per the above-mentioned gist.
Pro-tip, if you use WebStorm, you can copy some code from the internet, then select the equivalent text in the file in webstorm, right click and pick Compare with clipboard. You'll get a diff of the two snippets.
Change the start command in package.json
scripts
to read "start": "node node_modules/react-native/packager/packager.js"
. Again there was a direct reference here to sh
. Tsk tsk.
The official guide says to run react-native run-android
. This will package the apk
and send it to a device or emulator. I get the impression this is also supposed to start the dev server that bundles the JS. But it don't. So after running react-native run-android
you will need to run npm start
(which runs the start script you fixed in the previous step).
If you're keen to get debugging working (as it is it tries to use an applescript
to start Chrome), check out this PR by Spencer Elliott. Read the comments though, it changes package.js
which is going to be moved, so as with the above you're making changes that will disappear with the next update.
For a quick and dirty fix, change the getDevToolsLauncher
function to the following (in 0.13.0-rc
the code is now in node_modules\react-native\packager\getDevToolsMiddleware.js
, earlier versions it's in node_modules\react-native\packager\packager.js
- the below is a code sample from 0.12.0
)
function getDevToolsLauncher(options) {
var debugRunning = false; // New code
return function(req, res, next) {
if (req.url === '/debugger-ui') {
var debuggerPath = path.join(__dirname, 'debugger.html');
res.writeHead(200, {'Content-Type': 'text/html'});
fs.createReadStream(debuggerPath).pipe(res);
} else if (req.url === '/launch-chrome-devtools') {
var debuggerURL = 'http://localhost:' + options.port + '/debugger-ui';
var script = 'launchChromeDevTools.applescript';
console.log('Launching Dev Tools...');
debugRunning || require('child_process').exec('start chrome "' + debuggerURL + '"'); // New code
debugRunning = true; // New code
//execFile(path.join(__dirname, script), [debuggerURL], function(err, stdout, stderr) {
// if (err) {
// console.log('Failed to run ' + script, err);
// }
// console.log(stdout);
// console.warn(stderr);
//});
res.end('OK');
} else {
next();
}
};
}
Note the start chrome
part, this might be different for you. Whatever you can type into cmd.exe
you can use here.
If you want to run this on a real device follow the instructions found here. Specifically, run adb reverse tcp:8081 tcp:8081
.
So you've done all this and still getting errors? Yeah, I feel ya. I also had issues with virtualisation. It doesn't seem to be possible to have Hyper-V installed and also run virtualization for Android emulators (prove me wrong, please). And there was another issue with the API version of the emulator, all I can say is play with these, since they don't seem to be Windows-specific, and there are plenty of solved issues in the repo to search.
After a few weeks of using React Native I've found these scripts handy for building and deploying. Maybe you'll find them usefull too
"scripts": {
"install-dev": "react-native run-android",
"start": "node node_modules/react-native/packager/packager.js",
"get-js": "curl \"http://localhost:8081/index.android.bundle?platform=android&dev=false&minify=true\" -o \"android/app/src/main/assets/index.android.bundle\"",
"assemble": "cd android && gradlew assembleRelease && cd ..",
"install": "cd android && gradlew installRelease && cd .."
},
I feel the same, I tested with Genymotion and studio android emulator
The error is now.
Unable to download js bundle. Did you forget to start the development server or connect your device