Using metro-bundler on a web application
We all know metro as the react-native bundler, as the project that was only created to work with react-native, to generate code that the native bridge was able to read and render your mobile device application. But as any other bundle, it has the same capabilities to be used on web as well. Now the question is, is it capable? Let’s find out!
Before even installing any npm module i went directly to the docs to see what i needed and if it was going to be hard to implement.
When i started reading the docs i thought it was really bad or i had not understood it but it actually is really bad, let me tell why: we all are used to user friendly tools like webpack, rollup and parcel; where all the configs, all the options are available and well documented. Yeah, that is not going to happen on metro.
Building
They actually have a cli, which is intended to help, but all options are not described on their website. At first i saw a metro.config.js file and i thought with myself: oh, similar to webpack, let me try to configure it and pass parameters to cli. WRONG!! That does not happen.
I either: had to use the cli or create a js file to pragmatically call the metro api.
As you see here, we call loadConfig (to load metro.config.js, which you can configure to enable babel lookup and other stuff), the entry and output. There are also few other parameters which you can pass as onComplete, which is similar to an afterDone hook on webpack.
After that just run this file on node, and your compilation process is going to start.
More options can be seen here: https://facebook.github.io/metro/docs/en/api#async-runbuildconfig-options
For the “config file”: https://facebook.github.io/metro/docs/en/configuration#configuration-structure
Dev Server
Metro comes with a dev server as well, but it doesn’t generate html and serve it with your assets as other bundlers do, so you need to manually start it and link your assets within your html.
This does the same thing as described before plus starting a server on port 8080.
Now you have your javascript being serverd. Metro has the possibility of serving multiple types of bundles (that is why it is used for android and ios), for web we are interested on the .bundle file. Given the example, we are going to link on our html as the follow:
<script src=”http://localhost:8080/src/index.bundle"></script>
The .bundle extension is the browser version output.
Now just open your html file on your browser and you are good go to!
More dev server configs: https://facebook.github.io/metro/docs/en/api#async-runserverconfig-options
Feedback
So the takeaways from this experience are: metro is a promising bundler, it has so many different features that other bundlers don’t, specially on the cache side of things. You can have different types of stores for your cache, Remote, Local, etc. This enhances the speed post first build, where all devs can have your cache linked to a remote one and code on higher speed.
Configs could be more user friendly, we are all used to modern tools that allows us to define everything on a single file and give that to be consumed, but that is not quite what happens with metro. I actually opened an issue there asking for an enhancement but i got 0 replies, and it has been more than a month ago.
Docs are ok, they are not as descriptive as i would like, but at least covers all the configs available, different than other docs out there (i’m look at you webpack).
It is promising, could turn into the only bundler that any dev would need, bundling for web and native, but it has a long walk to reach that point. The performance is not that bad at all, not as optimised as a fastpack for example but not bad for a product that is < 1.0.0 and not that used for web.
It also has an easier codebase, it is easy to read, uses modern javascript (es6), async await and the abstractions used are less compless than other bundlers! So easy to contribute to!
I hope facebook invest a lot more on metro, if so we could kill all other bundlers and have just one for all platforms!
You can check these examples of configs here: