Taking the best of two worlds
I like Apache Cordova a lot. For the first time I am able to write a serious production-worthy app and run it on Android and IPhone. There are lots of quirks and pitfalls, of course, but the “write once, run everywhere” thing is in this case reasonably verified.
I love React for sentimental reasons:
- I think of it every morning
- I dream of it every night
But putting them both at work together is painful: each one comes with an own CLI to build apps, with different directory structure and specific build processes.
You will never be able to
create-react-app myApp and then just
cordova add platform android inside it: pesky yarn will start complaining that someone else wrote in his darling package-json.lock, webpack will take a subtle pleasure in wiping away files from
www/ and pretend they were copied in
build/. You will have to
yarn run eject and, at that moment, you’ll hear Hell’s bells start ringing…
Cordova and React wish they were two big black boxes. Opening those boxes and putting their content aside in a seamless, natural way is hard. There are many recipes to be found googling, I’ve tried a lot of them. None worked to my full expectations: they are either too simple, too old, or they lean too much on one of the two frameworks and make it very cumbersome to use the other.
I have now built some experience in solving this problem. I’ve seen the problem tackled the naive way, which produced some hodge-podge of codebases with very ad-hoc build processes. I am writing here the way I’ll do the thing next time, taking into account and building on the previous experiences.
The basic story is:
- have a not-completely-trivial Cordova app
- make it React-ready with Gulp/Yarn and raw Webpack
- rebuild it page by page with styled-components
Possibly, later I will write about making Cordova-ready an existing React app.
Starting point: a pure Cordova app
This code is hopelessly obsolete. It is a bunch of plain ES5 classes and IEFE’s that rely on the loading order inside the HTML page. It features Handlebars templates embedded in the HTML as
<script type="text/template"> tags. If we want to start moving the codebase in the direction of React it’s necessary to wrap the code into ES6 modules and change the templates into literal strings. We could use naked Babel, as I did in these examples, but a direct jump to Webpack promises already more flexibility down the line.
I hear you say: “
create-react-app is basically Webpack: just get on and use it!”. Yes, but…
The main hurdle dividing Cordova and create-react-app is that Cordova expects to find in `www/` the code to be used for preparing each platform’s build, while create-react-app compiles and writes into `build/`. For this reason only, every usage of create-react-app requires an immediate `yarn run eject`, which causes the loss of too many default configs, dependencies and automations.
The first step gets closer
It’s time to inventarize the changes we need in place. They can be found here.