Experiment: build an MFE with Vite instead of frontend-build/webpack

I find webpack to be slow and complicated to understand whenever changes are required. So I decided to see how much work it would take to completely replace our frontend-build (wrapper around webpack + babel + etc.) with a more modern approach - specifically using Vite.

I picked a small MFE, the profile MFE for the experiment.

Surprisingly, it wasn’t actually that hard to do. What you can see from the proof of concept PR is:

  • The changes required (at least for a small-ish MFE) are fairly small (note: my PR includes a couple cleanups and TypeScript conversions that are not strictly required to use Vite.)
  • The Vite config file is less than 50 lines, whereas the Webpack config has almost 10x as many lines of code
  • The Vite dev server is much faster to start and hot reload
  • The Vite production build is faster
  • The Vite production build uses half as much memory
  • The Vite production build is smaller
  • The Vite version has full TypeScript support, which frontend-build only has on the alpha branch.
  • The tests are all passing essentially unchanged
  • It works without any changes to tutor-mfe nor frontend-platform nor any other repo
  • I suspect the results could be improved even further with some small fixes to frontend-platform, frontend-component-header, etc.

For now, I didn’t try changing frontend-build itself - it’s also possible that this change could be achieved for all MFEs by changing frontend-build rather than changing each MFE. (But personally I wonder if we could use Vite/Jest in such a standard way that the required per-MFE config is so minimal that there is no need for frontend-build at all.)

Given all this, I think it’s seriously worth considering replacing webpack with Vite or one of the other modern bundlers in the near future. I’m wondering if others think the benefits of something like this would outweigh the costs, or not?

Tagging @arbrandes @xitij2000 @Jason_Wesson @regis

6 Likes

If we can find reasonable drop-in replacements for the webpack plugins/loaders we use, and (top of mind for me) a module federation implementation that functions well, we can probably simplify and speed up our builds by switching to another bundler. And if it makes the Typescript migration easier, niiiice.

My concern would be the blast radius of the migration, and how invasive a change it is. From your PR, doesn’t look too bad.

Is Vite the right choice, do you think? I follow bundler news in general, but there’s a lot out there these days, and it’s hard to tell if any particular contender is eating the world or what.

Hot take: I like that the diff is small. I like that it allows us to deprecate a dependency (frontend-build). I like that it’s all faster.

Hot questions: will it work with frontend-plugin-framework? Will it work with module federation (a.k.a The New OEP-65)?

That one I can answer quickly: Yes :slight_smile: feat: A leaner example app that is built using Vite by bradenmacdonald · Pull Request #54 · openedx/frontend-plugin-framework · GitHub

Vite is a choice, and just one I’m familiar with (I’ve also used the Rust-based one build into Next.js). I honestly don’t know how it compares to other newer ones. What I like is that it’s relatively fast and flexible, while still supporting most stuff we want “out of the box” with minimal configuration. I believe some of the new pure-Rust bundlers would be even faster.

1 Like

But personally I wonder if we could use Vite/Jest in such a standard way that the required per-MFE config is so minimal that there is no need for frontend-build at all.

I like the spirit of this idea, but am admittedly skeptical. My hot take is that even if we are able to get our configuration for Vite/Jest down to a simple “vanilla” config, frontend-build still has value for consolidating dev dependencies for our build, test, and linting libraries. If we ditch it, all those dependencies get dumped into MFEs and our maintenance burden goes up substantially. The moment we need to step away from the vanilla config, add a plugin, deal with a security issue or bug fix, we suddenly have to do it separately in 20 places instead of 1 place and bumping a single dependency.

That was the idea anyway. :slight_smile:

I’m hoping to leverage frontend-build extensively to simplify the work of enabling module federation, for instance.

1 Like

I’ll try to look into how this works with module federation and also if the vite functionality can just be pushed into frontend-build as a toggleable option, making the per-MFE changes even smaller.

1 Like

TAKE MY MONEY!

2 Likes

Vite was one of several options identified in Discovery: Faster build tool · Issue #126 · openedx/wg-frontend · GitHub . We ultimately closed that issue about a year ago because Vite and Turbopack had recently been released, seemed more promising than the other options we had identified, but weren’t quite production-ready yet. With that context, it’s quite possible that Vite or Turbopack is now ready for adoption (but it may be worth a quick scan to see if anything else passed them up in the meantime).

3 Likes

I have a new demo, that builds on my previous demo of the Vite-based profile MFE. This one shows a “shell” MFE that provides the header and footer, and dynamically loads the profile MFE as needed within the shell. It only loads a single copy of React, Paragon, etc.

In other words, this demonstrates many of the features desired for OEP-65 Composable Microfrontends.

2 Likes