drapanjanas / re-natal

Bootstrap ClojureScript React Native apps
MIT License
1.22k stars 100 forks source link

Faster prod bundles with babelrc for RN 0.45 #127

Open pesterhazy opened 7 years ago

pesterhazy commented 7 years ago

For production builds, this .babelrc seems to speed up the bundling step significantly:

{"presets": ["react-native"], "ignore": ["index.ios.js", "index.android.js"]}

Actually without this modification, the bundler OOMs on our index.ios.js.

Note that this only works with RN 0.45, as apparently this has a bugfix for using a local babel profile.

Also see https://github.com/facebook/react-native/issues/12590#issuecomment-318705819

pesterhazy commented 7 years ago

Just a heads-up, this didn't actually end up working too well in practice. When adding the --dev false flag, the packager still runs out of memory.

I've started an experiment of working around this issue here: https://github.com/pesterhazy/re-natal-husk

raspasov commented 7 years ago

Ok, I ran into this - it took me 1/2 day to try all sorts of hacks (incl. the ones above) and none of them worked (I've been using RN in producing with :advanced for over a year). My production index.ios.js file is about ~1.6MB, just FYI for your use case.

What worked: this line https://github.com/facebook/metro-bundler/blob/c37f730c57b1f932c5d65505f3cd45ad087c416e/packages/metro-bundler/src/JSTransformer/index.js#L55

Change it to execArgv: ["--max_old_space_size=6000"],

This allows all the workers to use up to 6000MB of memory vs. the default ~1400MB that I think node/V8 comes configured with. It seems that with metro-bundler the transforming of the code happens inside of a bunch of worker processes instead of the one node.js process that used to get launched pre metro-bundler. It took a bunch of tries and staring at Activity Monitor and "ps aux | grep node" in the Terminal for a while to figure that out.

I tried looking for a "good way" to pass this config --max_old_space_size=6000 to the workers but I couldn't find it. If anyone can point to any sort of official documentation about metro-bundler I would buy them lunch :).

PS This hack is for metro-bundler 11.0, with the latest metro-bundler 17.0 the hacked file has been changed so I'll get to that whenever I upgrade next.

Worked for me with RN 0.48.1

pesterhazy commented 7 years ago

Rangel, have you raised an issue in the metro-bundler repo? We need to raise the visibility for these issues

On Sep 14, 2017 20:55, "Rangel Spasov" notifications@github.com wrote:

Ok, I ran into this - it took me 1/2 day to try all sorts of hacks (incl. the ones above) and none of them worked (I've been using RN in producing with :advanced for over a year). My production index.ios.js file is about ~1.6MB, just FYI for your use case.

What worked: this line https://github.com/facebook/metro-bundler/blob/ c37f730c57b1f932c5d65505f3cd45ad087c416e/packages/metro- bundler/src/JSTransformer/index.js#L55

Change it to execArgv: ["--max_old_space_size=6000"],

This allows all the workers to use up to 6000MB of memory vs. the default ~1400MB that I think node/V8 comes configured with. It seems that with metro-bundler the transforming of the code happens inside of a bunch of worker processes instead of the one node.js process that used to get launched pre metro-bundler. It took a bunch of tries and staring at Activity Monitor and "ps aux | grep node" in the Terminal for a while to figure that out.

I tried looking for a "good way" to pass this config but I couldn't seem to find it. If anyone can point to any sort of official documentation about metro-bundler I would buy them lunch :).

PS This hack is for metro-bundler 11.0, with the latest metro-bundler 17.0 the hacked file has been changed so I'll get to that whenever I upgrade next.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/drapanjanas/re-natal/issues/127#issuecomment-329639764, or mute the thread https://github.com/notifications/unsubscribe-auth/AAGfWCGAoDdkA2bHJNFSWD47SFbgUgEyks5sibzWgaJpZM4Om17I .

raspasov commented 6 years ago

@pesterhazy I have not — I will file it.

raspasov commented 6 years ago

Ok, finally some good news in metro-bundler/bable fun land:

Steps to avoid metro-bundler/Babel taking forever to chew throw your great and awesome Google Closure output file:

  1. Manually upgrade to "metro-bundler": "^0.18.0" in your package.json (not sure if this is necessary, but I did).

npm install metro-bundler@0.18.0 --save

  1. RENAME your output file to something DIFFERENT and UNIQUE from index.ios.js WHY? Because if you don't, .babelrc CANNOT properly ignore your file in most cases. My .babelrc that worked for ignoring my output:

{"presets": ["react-native"], "ignore": ["cljs.ios.js"]}

Basically change your project.clj to output to cljs.ios.js instead of index.ios.js .

If you leave your Google Closure to the likely default name 'index.ios.js' then bundler will ignore ALL files, including ones inside React Native libraries called index.ios.js! And they need that Babel "help" to work, poor things. Babel = awesome.

That way, metro-bundler actually completes a production build in around 1 minute! I've never seen it compile that fast! Simply amazing. 12 hours of productive "work" well spent, really hope this helps anyone.

rboyd commented 6 years ago

@raspasov thank you good sir! you saved my night.