Translating Dust templates to JSX
So.. React, amirite???
All those accomplishments, without even being a framework.
Here in the Mobile Web team, we don’t follow any strict JS frameworks — or at least, any popular ones — and we use a mix of legacy and modern technologies. Although that works well for us, manipulating DOM is usually hard, and we wanted to alleviate this by reducing the number of “manual” updates, increasing our code reuse and worrying less about memory leaks.
After some investigation, React was considered the best choice and we decided to go with it.
I joined Badoo in the middle of this process. Having bootstrapped and worked on React projects previously, I was aware of its pros and cons in practice, but migrating a mature application with millions of users is a completely different challenge.
Our own HTML files were well organised, and most of our rendering was done as simply as
template.render(). How could we retain this order and simplicity while moving to React? To me, technical difficulties aside, one idea was obvious: replace our existing calls with JSX code.
After some initial planning I gave it a go and wrapped up a command-line tool that performs two simple things:
template.render()calls with the HTML content
Of course, this would only move us halfway, because we would still have to modify the HTML code manually. Considering the volume and number of our templates, I knew that the best approach would be something automated. The original idea sounded simple enough — and if it can be explained, it can be implemented.
After demoing the initial tool to teammates, the best feedback I got was that there is a parser available for the templating language that we used. That means that we could parse and translate code much easier than we could with regular expressions, for example. That’s when I really knew that this would work!
Lo and behold, after several days a tool was born to convert Dust.js HTML-like templates to JSX React code. We used Dust, but with a wide availability of parsers, the process should be similar for translating any other popular templating language.
For more technical details, skip to the Open-source section below. We used tools like Esprima to parse JS code, and a PEG.js parser generator to parse Dust templates. In the very simplest of terms, it’s about translating this type of template code:
to its JSX code equivalent:
See side-by-side comparison here.
After this, our process was pretty much straightforward. We automatically converted our templates from one format to another, and everything worked as expected (thank you, automated testing). To begin with, we preserved our old
template.render() API to keep changes isolated.
Of course, with this approach you still end up with templates and not “proper” React components. The real benefit is in the fact that it’s much easier, if not trivial, to switch to React from templates that are already JSX, in most cases by simply wrapping a template code in a function call.
You might think: why not write new templates from scratch instead? The short answer is that there was nothing wrong with our old templates — we simply had a lot of them. As for rewriting them and working towards true componentisation, that’s a different story.
Some might argue that the component model is just another trend that might pass, so why commit to it? It’s hard to predict, but one possible answer is that you don’t have to. If you iterate quickly, you can try out different options, without spending too much time on any of them, until you find the format that works best for your team. That’s actually one of the core concepts for us at Badoo.
In the spirit of doing one thing well, we’ve built these internal tools in several parts:
- dust2jsx — package responsible for actual Dust to JSX translation
- ratt (React All The Things) — command line tool for reading/writing files on disk. Responsible for including referenced templates, and uses
dust2jsxinternally to transform code
We’ve even open-sourced these tools — be sure to check them out, as well as other open-source materials on our GitHub page. Please contribute or simply leave us a comment if you find them useful.