Context
As a ClojureScript developer, I use the google closure compiler to optimize my JavaScript. In my current project these optimizations takes 9,655,832 bytes of javascript and compiles it down to a single file of 1,518,693 bytes. I can use this file as is for the browser, but react native has additional steps that take a long time.
Problem
React Native has its own transformation step and it’s really slow for my already optimized javascript files. Running exp publish
in my project takes 45 minutes in total. 23 minutes to build the bundle for iOS and 17 minutes for Android. To even allow the transformation to run for this long I have to increase the timeout in the metro-bundler that’s set to 5 minutes.
Question
Is there a way to use expo tooling to create a bundle for iOS or Android that doesn’t take tens of minutes?
Would it possible to use expo or the exp
command to skip the transformation step for ClojureScript compiled javascript files?
Having this built in to our tools would solve a huge pain point for ClojureScript (and possibly other languages that compile down to JavaScript).
State of the art
There are 2 approaches that I’ve seen and tried to get around this issue.
1. Skip the transformation
Austin Birch was able to skip the transformation step by patching the metro-bundler source code and using his own transformer. This article is now out of date, as the code has changed. Knowing very little about JavaScript, I updated his metro-bundler patch, but I couldn’t get the transformer to work without the bundler exiting with a non-descriptive error message: "map is not defined"
. I gave up here.
It’d be neat if exp
could call the react-native/metro-bundler code in a similar way to avoid transformations on the javascript generated by ClojureScript.
2. Perform transformations on a fake file
peterhazy has a different approach where he doesn’t pass the large compiled javascript file from google closure, he passes a small file which requires all the modules. After this small file gets bundled, he injects the large compiled javascript file into the actual bundle.
I tried this approach and I was able to generate a bundle, but I wasn’t able to use this approach with the existing exp publish command, since it calls the metro-bundler itself. For this to work, exp would have to call the bundler with a fake file itself. There’s a 4 line bash script named build-husk
at the root of the project if anyone wants to check it out.