73 comments

[ 131 ms ] story [ 381 ms ] thread
Of all the possible ways to write it, “Micro-front ends” definitely isn’t the right one. I thought it was about Webpack 5 dropping support for something.
Well, a lot of style guides prefer "front end" and "back end" instead of one word (similarly to a web server, and not a "webserver").

If that's given, "micro" creates a compound noun that comes with a dash. Hence, micro-front end. Whether it's correct, that, I strongly suspect, depends more on your style guide than anything else.

As far as I'm concerned, whatever makes the technical writer happy is good for me...

Maybe this is good and useful for some people: but to me it feels like a continuation of the dark slide that frontend tooling is going on. Way overcomplicated, likely brittle and buggy, significant barriers to just sitting down and building stuff.
I can't help but agree!

Where's the Visual Basic 6 of our era? :)

Sure, apps weren't pretty, but you could bang one out in a few days and start getting use from it.

That's why I've devoted my career to tooling, hoping to improve the situation [1]

[1] {cough, cough} https://mintdata.com is where we put our blood, sweat 'n tears as a result :)

You are my spirit animal. Where did these people come from that decided that front end development needed to be such a house of cards that it takes a masters degree to get a build system successfully set up and working and know how to fix it when it breaks every few days.
I personally don't think it's that hard to run `parcel` on the command-line. Front-end tooling is as complicated as any other tooling: as much as you need it to be.
Parcel is easy to use (as long as you stay on the golden path), but I have a hard time calling it simple.

Automagically installing dependencies that it fails to `require()` seems way out of scope for a bundler. Or managing Rust toolchains. Or a bunch of hard-coded rules that hard-exclude compiling stuff in `node_modules`. Unless they're in symlinks (presumably for Yarn workspaces?). And so on.

There's a new one called parcel? WTF?

I started with Grunt. Then came Gulp, webpack, and a couple of others. They all do pretty much the same thing, and yet apparently someone has come up with a new one called parcel.

Do they do this shit to make nice CV's so they can land FAANG jobs?

Everything was easier back when we used to use FTP to upload CSS and JS files to sit alongside index.html or index.php.

EDIT: I just googled and the first result is parceljs.org, but that one is blank with a BLM logo on it. Is there another site?

Parcel is old news, Snowpack and Vite is where it's at right now (not joking). Or you ditch node.js completely and go with Deno!
Crap. I totally thought you were joking. The insanity must stop.
All of those you used previously still work and are arguably more used than Parcel. I only mentioned it because it's entire premise is that those bundlers are too complicated, and Parcel literally just works out of the box, no configuration, for most things. It's neat, and you might enjoy it :)
I agree with the general sentiment of frontend tooling becoming more complex over time, but the thing about features like this one is that you don't ever have to use them or even think about them if you don't need to. But they sure are nice to have if you do need them.

Personally, I'm looking forward to implementing this at work, but I don't think I'll ever touch it for my personal projects.

Webpack's general design philosophy is to dump a bag of tools on your head and tell you to use them to assemble a build system. So anytime the bag gets larger, I cringe.
I don't disagree, but if you don't need the entire bag of tools, you can get by for quite some time (possibly indefinitely) using just `create-react-app` and friends. The issue with webpack is that the learning curve for going from CRA to manual tuning is incredibly steep, but what that buys you is full control over the entire build process.

I do wish there was a middle ground where you could use 90% sane defaults and customize the other 10% without taking on a huge amount of tool-specific baggage. Parcel is great for simple projects, but is not (in my very limited experience over a year ago) anywhere near customizable enough for more advanced use cases.

It's a great point that you don't need to use these things if you don't want to in your projects, but the caveat is that you will often end up working on projects other people created, and they might have done things like use a feature just because it seems cool, or create the project from a template that includes the kitchen sink and eventually rusts through.

In those cases, you have to understand the rusty sink at least well enough to fix it, and hopefully well enough to assess if it was the right tool for the job, and how to safely remove it if it really wasn't.

A great example of this is actually create-react-app. Many people who have no idea what they're doing start off an app using this toolset and end up with a boatload of things they aren't even aware of, like a half-baked service worker that by default caches the app's code in localStorage to enable offline app functionality!

My own experience with that specific issue was of people building a production system on top of an ejected create-react-app, who ended up with deployment issues where some users arrived to a blank page after some deploys. It just seemed to happen randomly.

It turned out that after some deploys, for some users, the default CRA service worker's cache and the webpack js minify+chunk configuration, and the 404 redirect configuration for firebase, didn't play well together. You could end up with new code calling cached code which requested chunks that didn't exist anymore, and getting served html 404s with status 200, so the cache wouldn't bust properly. Understanding this, debugging it, and solving it safely (in part by safely deregistering the service worker for all users) took ~days!

The really upsetting part is that no one involved in building this app (neither founders nor original create-react-app-running devs) ever wanted service workers, nor a progressive web app offline code cache, nor code chunking, nor optimistic 200-html pages in place of 404s. But those were all default options and packages and stackoverflow copypasta that got cargo culted in, and it produced a bit of a tower of crap.

That default service worker setup was frustrating. Even for local development, it would mess things up sometimes.

Luckily they turned it off for new Create React App projects a while back - so at least it shouldn't haunt any new apps.

The worst software hairball I've ever had to untangle was a react/redux/saga monstrosity that was excruciating difficult to debug or improve. I finally got permission to rip most of that out and the resulting plain react app was fairly pleasant to work on.

So yeah, software development fads matter whether you personally follow them or not.

I was recently brought onto a project to add a couple of simple screens to an app. Any other react project it would have taken a couple of days so I was surprised the previous estimate was for weeks of development effort. Opened up the hood to find saga, and quickly discovered why it would was weeks of effort.
Yep. Don’t use it for smaller projects. You can. But why. It’s designed for scale issues. Just cause you can doesn’t mean you should haha. I’m not using it on any personal projects because there’s no actual need for it. I’ve got it in production. Replaced tag management, personalization, configs, no page reloads between apps.

I’d argue that MF simplified tooling and gives us back simple import capabilities. At least compared to everything else I’ve tried in the past 10 years

As a co creator of it. It’s very resilient. Running over 6000 handwritten modules with no issues at the moment. Other companies are applying it to 50,000 handwritten modules.

I’d say that it’s most helpful for those at scale. If you don’t actively need it. Definitely don’t use it haha

Does it finally work magically out of the box like Parcel does?
Webpack, just like Parcel, has always "worked" out of the box without installing anything extra. You do still have to write a tiny webpack.config.js. Bundles code just fine by just including `webpack` and `webpack-cli` in my project.
IME parcel has been much easier to use than webpack for medium-complexity projects.
In addition to needing to write a config, you also need to find and install plugins (loaders) for various file types, and those plugins need to be configured as well. The idea is that parcel handles that for you automatically. For Webpack, there's often competing plugins, and beyond that competing workflows e.g. TypeScript via tsc, or transpilation via Babel and typechecking via tsc.

Still, parcel is not 100% seamless in the sense that whilst parcel doesn't (generally) require plugins, you do still need to add/install regular file type dependencies. "typescript" for .ts files, and "sass" for .scss files and so on.

I actually still have zero idea how webpack configs and plugins really work. I just end up in a nested soup of config options where nothing really seems to be the same if it's defined at a different level. It eventually just randomly works. Every new plugin results in the order of things being randomly changed until it works again. It's bizarre. Truly unpleasant from an epistemological point of view - I want to understand but cannot.
> you also need to find and install plugins (loaders) for various file types, and those plugins need to be configured as well

No, you don't _need_ to find and install plugins, unless you need it because you're going further beyond than the core use case of webpack.

You're comparing two tools that have different focuses and compare them on the axis of "working out of the box" which some specific use case in mind. Parcel might work out of the box for React, because it was created to provide that experience. Webpack wasn't created for that, but to provide customizations for its users. Of course Parcel is gonna be better at providing that experience

So this is like Server Side Includes (SSI) but with shared state and built on top of JS modules?
Yes, but please, can you avoid going around saying that? My children depend on the money I earn by selling support for this. Complexity is a virtue of our industry, and by embracing it, we will all be richer and happier.
Honestly, that looks like the most horrifying piece of tech that I really wanna learn and try...

In my org, most teams that need it have like one front end dev that's shared among three other teams, and like one or two people who can hammer out some React and don't hate JS to help out with most of the stuff. I suspect this would be an utter madness for that kind of a team.

And yet I feel like I wanna try that for our next project.

Good luck coordinating. A result of acquisitions, my product has a combination of Angular, React, Vue and server-rendered pages. And each front-end is deployed as it's own node app, so no shared CDN, which complicates module federation further. Certainly not Webpack's fault.
Is coordination worth the effort?
I question it. Inarguably, every microfrontend shipping its own copy of React DOM, Angular Core, etc is wasting bandwidth. Do our customers perceive page slowness due to this lack of optimization? No. Is conversion harmed? No, because we're a B2B SaaS company.

This is not to diminish the work of the Webpack contributors. I still think it's a wonderful feature, and folks with less messy situations (e.g., for organizations still doing micro-frontends, but everyone's using a single UI framework-- their adoption of module federation would likely have less friction) and thus be worth the effort.

> my product has a combination of Angular, React, Vue and server-rendered pages.

This is intended by Micro Front.

Most Billions Dollars SaaS are based on this Frankenstein type of architecture, the goal is simple :

- Support legacy code with Zero Effort

The result for the end user is absolutely horrendous , it create slow and bloated web pages with Megabytes of JavaScript with UI of various style and behavior similar to Confluence/ Jira etc...

This architecture fits perfectly fit the state of the current market :

- Push lots of stuff out "as fast as possible"

- Turn over in software in +20%, people who build Jira 5 years ago aren't there anymore , they cashed in their stocks and went somewhere else to get a bigger paycheck

- The people who build those apps , most of the time , don't use them...

Leaders of Atlassian use Gmail and GDrive , I'm pretty confident that they don't even use Jira or any of their own software...

Those apps are so slow and bloated it's astonishing...Yet when something is the "norm" in the industry , it's definitely not an issue.

Let's not bury the lede here. The problem is with coordinating, not the colorful selection of technologies used. Most teams use abstractions on top of Webpack, because they are not interested in how a bundler works, and would rather focus on product features (from a business perspective: I can somewhat appreciate this sentiment). Since most teams haven't ever picked up Webpack, and barely touch facades surrounding it, good luck telling them to add module federation to their configuration.
Nice. Now all the clients pretending to develop microfrontends (by breaking up the repos) but shipping one big js bundle can stop fucking lying now.
This seems like something useful that I hope to never have to debug
The goal of micro-frontends (different teams being able to deploy "their" parts of an application) is nice and all, but I still don't see how this is going to work when the shared modules release breaking changes. So now all those different teams that work on different parts of the same applications will still need to do one massively coordinated release in which they all migrate to the newer version at the same time, and a single team delaying things can put the work of all other teams on hold.
Exactly this. But... from my limited experience: one team will just break things and then everyone just needs to correct their stuff as soon as they can because it's just not working anymore. Coordination takes time but has no place in the world of "move fast and break things".

Could be just my limited experience, though.

I think some people are using feature flags for this

  > I still don't see how this is going to work
  > when the shared modules release breaking changes
The team I'm working on is currently working on such an application, and that problem is the one I've been worried about most. What do we do when there is a major version breaking-change upgrade of the shared design system?

If you are working within a singular repository (monorepo), you can make a singular commit that fixes all parts of your application at once, and since it is deployed in one go there will be no breakage in production.

On the other hand, if you have a shared library that affects multiple repositories, somehow everybody needs to do the PR at the same time, and somehow every deploy needs to be synchronised in order that all micro frontends are updated at the same time. How can that be done in a way which doesn't cause breakages? What if one team is slower to update than every other team? What crazy piece of infrastructure might we require for this kind of gradual distributed upgrade?

This almost certainly sounds crazy to most engineers, but at the organisation I work they build quite a lot of App Store style applications which amalgamate 100s of other applications into one gigantic application. Additionally, for some legacy reason, we are tied into using separate repositories for each line-of-business micro frontend.

Couldn't you version shared modules to avoid this?
What do you mean by "versioning" them? If you mean running two different versions of the same library and putting them in different shared modules, then: maybe, that depends on the library. I'm quite sure that that's not possible with React, though, and I've experienced the same problem at a previous employer that insisted on using Polymer: Web Components have their own tag name (e.g. <google-maps>), and you can't run multiple versions of them at the same time because they'll both want to claim that tag.
I opened a PR to upgrade my project to webpack 5 in 2019. Still haven't merged it since Webpack 5 still isn't released. If they have no further breaking changes, they ought to release and do a 5.1 with further non-breaking new functionality.
Like <Frame/> but better!
The Webpack dev team's time would be much better spent on making their code strongly typed, with configuration especially having a strong type definition. We need less Webpack to deal with, not more.
This is basically micro-services ideology but applied to the front-end. To me, all of this reads as:

"We couldn't agree on a programming language, framework, or set of common development practices, so everyone gets their own individual silo and never has to worry about what everyone else is doing."

Does anyone pay attention to the organizational problem that underlies all of this? You have to agree as a team on this stuff. Microservices is not a way to solve a technical problem, but a way to bandaid an organizational/people problem. You simply couldn't get 2 different front-end or back-end teams to agree on some policy or framework, so now you put an explicit rift between them with this microservice bs.

We did monolith->micro-services->monolith. I will rewrite a system from scratch before i put it into a leaky box and try to wrap an API around it ever again. You can try to sell this as some sort of way to migrate away from legacy without rewriting code but that is a bullshit siren song that is never true in any reality. You will likely save more time over the long haul building 1 coherent system (both frontend and backend). Keeping legacy around and pushing it further and further into container inception is not a rational technical solution if you actually want to pay down your technical debt at any point.

We already kind of solved this problem at IMDb using Webpack 3 and 4 (with tons of hackery). It was, all things considered, a terrible idea.

We ended up with a web page with 10 nearly identical sections implemented 10 different ways by 10 different developers across 10 different git repositories.

Micro-frontends are cancer, please don't fall for it. You can get much more done for less with a single webserver and a graphQL service, not matter your project's scope.

No front-end on earth needs multiple teams to build it - if it does, your product is convoluted and needs to be split up and/or simplified.

I don't understand anything here about the microfronted.

Why would you do that ?

You can already share and resuse components, modules, stores, functions ?

What I don't see here ?

The use case I've seen is for iteratively moving away from a legacy system.

Say you have monolithic front end and you want to move to a new framework/version/etc. Instead of rewriting the whole app, you can approach it feature-by-feature and slowly replace the legacy app, Ship of Theseus style[0].

[0]: https://en.wikipedia.org/wiki/Ship_of_Theseus

This is exactly what we're doing now. Some of the problems we've seen thus far is how to maintain packages but allow for high-iteration development. It is cumbersome using a packaging service, so at best it's being able to decide what to keep in a shared rep, versus things that are being rapidly developed in it's own rep. Any component that needs specific tweak then becomes duplicated and sadly, code-reuse and maintainability suffers.

Another problem is tracking down inter-component bugs, especially if the code is behind a repository. How am I to make small tweaks? Bleh!

I haven't digested what Webpack 5 is doing, but I'm skeptical, mostly because I don't like Webpack's plugin implementation.

> You can already share and resuse components, modules, stores, functions?

You're absolutely right that we can, but the issue is that most teams are too large or too disorganised to share complex codebases, so they choose to do a hard division: splitting the code itself.

Here's an argument that I love: Microservices and microfrontends are (most of the time) a failure of encapsulation [1].

Of course there are other benefits, such as separate deployment processes and ability to use different frameworks.

[1] https://michaelfeathers.silvrback.com/microservices-and-the-...

To me, microservices were more about scalability than encapsulation.

Maybe that's the reason that I find serverless more promising.

Sometimes it appears that microservices contrarians are just focused on nitpicking while turning a blind eye to the myriad of advantages that justify their existence and widespread adoption. It's similar to how it's fashionable to criticize Java or C++ just for the heck of it. Sure, the architecture style is not a panacea and there are plenty of downsides and some projects made poor decisions and some evangelists try to make a career selling their snake lard. However, one just need to understand that vertical scaling is not a panacea or effective in reducing latency or providing reliability to understand the need for microservices.
I feel like the debate between the microservices evangelists and the contrarians are "Microservices are a best practice you should almost always use" and "Microservices are a tool for primarily splitting up development teams when they get too large to manage, i.e. a technical solution to an organization problem".
The organizational part is just one of the many advantages, and arguably the least relevant of the bunch as it's only relevant for huge projects requiring dozens of developers working concurrently
Is modularity a huge benefit when most languages allow you to compose applications into modules which have keywords to enforce encapsulation?

And scalability seems like an incremental benefit at best. If you're cpu bound you can load balance without microservices. And if you're database bound (and have already cached, optimized, and scaled up your db) you can scale up your db to multiple instances. Even Stackoverflow runs their entire infrastructure on just 4 db machines.

> an argument that I love: Microservices and microfrontends are (most of the time) a failure of encapsulation [1]

There are plenty of problems and challenges with microservices, but that rant makes no sense at all. The blogger does not understand the upside of running separate processes? And then although he presents himself totally oblivious to the problem somehow asserts that "programming languages give us all we need to encapsulate state and environment", claiming that any shortcoming is due to people doing it wrong?

Quite frankly, that article is just a rant devoid of any rational point, and it surprised me how it has been presented as some sort of argument on an entire architecture style.

(comment deleted)
I've had a similar experience. I spent a few weeks hacking with a team to discover what was killing their productivity and it all came down to the early decision to adopt micro-frontends.

The only place I can imagine this working is at the very, very top end of the organizational scale: somewhere like Facebook where they have the engineering discipline and know-how to manage hundreds of front-end engineers working on a single application.

For every other use case if micro-frontends seem like a good idea it's because something else is going wrong in your development process.

The last assertion is problematic. A team of engineers can only produce so many pages -- you could reasonably need multiple teams to work on different parts of the product's UI.
In my company, micro-front ends was appreciated by the development teams involved. It seemed to reduce problems with delivery to production, probably because of splitting up our tests (which were too slow). It is worth noting that we introduced micro-front ends along with a change to the philosophy of the product and also a change to the technology. So our front-ends might be better described as separate applications that happen to be presented to users within a seamless shell.
We have spoken before. Hashed module ids? Cli that figures it out? I based webpack external import off that. Then rearchitected webpack for MF. IMO MFEs were a cumbersome idea, however the mechanics of module Federation make it hard to locate real issues. 10 repos, likely overkill. However there is a very real use case. I’m working companies that have 300 teams of 20 devs per team and over 50,000 handwritten modules. No matter how efficient you make something. The build still takes 40 min.

Your use case sounds like overkill, suboptimal with 10 MFEs that are similar. I’d suggest a monorepo if you’re not bottlenecked.

I see it coming into play with automated UI building systems
A poorly organised company will always be a poorly organised company regardless of the tools it uses.
I'm hoping that module federation will enable multiple, separately deployed services to reuse assets so that users moving between those services may do so without redownloading the same things over and over.

We've been able to achieve this to good effect using Webpack 4 with some hackery (https://www.matthinchliffe.dev/2020/06/03/taming-webpacks-co...) but I'd love to be able to point to something documented and official instead... this sort of looks like it might meet this need. Fingers crossed.

This title was quite hard for me to parse. I was thinking, what is Micro-front and why is it ending?
Can we please stop overcomplicating the terminology around frontend architecture? The whole Isomorphism craze was bad enough - lets not make this stuff more complex than it needs to be and create confusion by over-loading existing terms like containers.

Whats being proposed here are dynamically linked shared libraries, they expose some functionality & also consume dependencies (that may be shared). Theres no need to be talking about containers, federation, orchestration etc...

Micro-front ends sound like a bad idea, and exactly like the sort of thing our architects would think is a good idea. Does anybody know of any horror story blog posts so I can show my manager, just in case?
Please change my mind: I think that sharing modules on the run is not related on microfrontends. Actually what you can achieve with module federation it's achievable with npm modules. The main difference is that are accessible at run time and that them are sharing common dependencies. But it would be a hell to handle deployment and breaking changes.