TLDR: Libraries should let innovation come either from within the core or from plugins/middleware out in the wild. Trying both approaches in parallel can light up the wrath among both users and plugin/middleware maintainers that cannot keep up with the breaking changes.
Webpack just went 4.0 and it has LOTS of new goodies! Yaaaaaayyy 🤗
But there were LOTS of breaking changes, including the plugin/loader system, so you cannot migrate until all the 15 Webpack plugins and loaders you depend on have migrated as well. Aaahhhhhh 😕
Before I go into my little rant, let me clear some things up: I love webpack. I do. I cannot remember how my FE workflow was before it. Seriously, wow life was before hot-reloading? Did we really used to reload the page ourselves? Yuck.
I am also very aware to it's contribution to the current state of JS ecosystem, along with other bundlers and, of course, Babel. We should be very grateful for them. Thanks to everyone involded. Sincerely.
Now. What's the problem with it? Well, to put it in just a few words: Webpack is schizophrenic.
Hold on. I'll elaborate.
If you are a developer of a popular library/framework, one of the many challenges you have to overcome is to figure out how innovation keeps making it's way into it.
Why? Because people love innovation! It's one of the best ways to keep old users engaged while still attracting new ones.
But how? I'll point out two specific and contrasting ways by telling a couple of "sad" stories.
Fast Cargo Ship
You are a library that solves a big problem that lots of people have. You have all features in the same place. Batteries included. Standalone. You are a beautiful giant. Everyone loves you.
Suddenly, a competitor library appears. People start posting on medium that it is faster, simpler, lighter, shinier and yet, it has more features than you.
That's not good. People are starting to forget about you. They're exposing all the problems you have. Problems you didn't even know you had until this arrogant library showed up.
But it's all good. You're humble. You learn from your mistakes and you change fast. In no time, you publish a new version of yourself. Faster, simpler, lighter and with even more features than your competitor.
Of course there were lot's of breaking changes. That's how the world works, keep up or go down.
You release a migration path. You're sure that even if it's a little painful to go through it, people we'll see the benefits and follow along.
And you're right. People do! They still love you. You gorgeous giant!
Ahh, the happiness. The love.
All the Medium tutorials about you. That will show that arrogant library.
But wait… What's that? An even newer and shinier competitor, bringing a whole newer and better approach to solve the same problem.
Here it comes the negative Medium posts again.
You are a small library that solves a small and specific problem. But in the best way possible. Flawless. Not a thing to take out, not a thing to put in. You are perfect. Everyone trusts you.
You're so perfect that people thinks you should do more. You should solve even more problems perfectly. You disagree, but still. You want people to be happy. You want people to look up to you.
So you come up with a plugin system. You put up a documentation about it, showing how things should be done, what conventions should be followed and what patterns are best to be applied.
So people start building more and more awesome plugins that solves so much more problems that you would ever thought you could have solved by yourself. You're a vibrant ecosystem.
And you know what's the best part? You 're still perfect.
Hmmmm. Look. What an interesting new trending library. It has a whole new look into the problem you're solving. Wow. So many articles comparing you two. Oops. In some of them, you're losing.
You're worried. Are you not perfect? Should you change?
Look a all this plugins counting on you. If you change to much, hell will break loose. How much time will all these plugins need to catch up with the changes? Some of these plugins are even as popular as you. People will be very angry. All their beloved plugins will become useless.
But you can still change. You can still get better. You can still be even more perfect. But you have to do it slowly. Bit by bit. Little by little.
And that's fine. Your plugin system is so flexible people will find a way to keep up with all these new competing solutions that keeps popping up.
Or will they?
What? Why are they not doing anything?
You're slowly fading away. Getting forgotten. It can be due to the smaller and smaller attention span of this generation, or all the new libraries that gets released every week, or even your plugin ecosystem that is keeping you locked in.
Maybe after everyone has moved on, you can surprise them with a big change. Who knows.
There's Beauty In Both Tragedies
You may have noticed both approaches have their strengths and weaknesses, like everything else in life. Also, some of the description may have have left you feeling that you've seen that happen before and I'm sure you did.
One recent example that comes to mind that can represent a Fast Cargo Ship is Angular. Which has been in a fast pace of breaking changes for some time now. But it changed for the better (some people might disagree and that's fine) and it still is one of the most popular full-featured FE frameworks out there.
There's a couple of examples to represent the Slow Kayaks. One of them is JQuery, that even with the 3.0 release (that took ages to come out), few things that have relevant impact on users actually changed and although it is slowly loosing "market share", it still is the most used JS library in the world.
The other example of a Slow Kayak is the popular node.js library, express.js, that has not changed much for a very long time, but it has a huge middleware ecosystem that somehow keeps growing. Although it dated, it still is one of the go-to node.js server abstraction.
Both approaches have their perks. Both approaches for introducing changes have their drawbacks.
Libraries that focus on being full-featured can worry less about 3rd party integrations and are more free to introduce breaking changes to the core itself. Also, planning a migration path is much easier as maintainers have control of the whole scope of changes. Sure, some users will still complain about having to migrate but some people always complain about any change anyway.
In the other hand, libraries that focus on being extensible/pluggable are much more restrained when it comes to introduce breaking changes because maintainers now have to think not only about the scope of the library itself but also how these changes would impact the whole ecosystem of extensions/plugins. And the more popular the library becomes the more careful maintainers need to be. In the worst cases, usually when the extension/plugin system has not been designed in the most extensible way possible, these libraries are doomed to staleness. But when the extensions system is well designed, maintainers and community can then focus on building features purely by building and maintaining extensions. Users can then choose freely what features they'll use.
But What All That Has To Do with Webpack?
The problem with Webpack is that it does not pick a side. It wants to be batteries-included but pluggable, standalone but extensible, everything you need out of the box but extensible.
By merging both approaches, the harm of their drawbacks become even more visible. By releasing many breaking changes too often will force users of old versions to have to:
- Migrate Webpack itself to use new features
- Wait for plugin maintainers to release new plugins that supports the new Webpack version
And that, fellas, takes time. Time that will likely bring little or no value to the end-user of their application. In other words, the cost is too high for the seemingly little gain.
Also, even new Webpack adopters will have a hard time doing something useful with it, because all the plugins in the ecosystem will need some time to catch up (and some of them may never do).
Which, to be honest, it doesn't make much sense to me. If it is so full featured, why do we need all these plugins?
Have you ever ejected a Create React App? Have a look at package.json. Almost 30% of the dependencies are Webpack related. Dependencies of which every project that I have seen that uses Webpack always use them. I'm talking about you
sw-precache-webpack-plugin, plus an infinitude of loaders.
However, if we use so many plugins, why does Webpack still seems so heavy weight? Shouldn't all the heavy lifting be done by the plugins/loaders? Where does all the weight comes from?
Lot’s of the changes introduced in the version 4 had to do with HMR, Code Splitting, Lazy Loading and Configuration defaults. Shouldn't the plugin system have been designed in a way such that these features were added and maintained purely using plugins? And by doing so, wouldn't migration paths be smoother and granular?
Or if you think all these really should be in the core library, shouldn't the plugins that performs popular tasks like html-injection, css-extraction, assets-manifest generation and many others, also belong in the core?
And if you think Webpack doesn’t change that much just go here and type
webpack in the input. Look at how many versions it has. Compare it to other popular (older) libraries like
lodash. Wow, right?
Ultimately, my questions are:
- If it is a standalone library, should it need anything else? Should it ever need a plugin/middleware system? Shouldn't innovation come from within?
- If it is a plugin/middleware based library, how often should it's core change? Shouldn't innovation come from outside (hence, plugins)?
- What’s the Webpack design principle that states what should be a core feature and what should be a userland plugin?
- Should both changes introduction approaches ever merge?
Listen. I am very aware things need to evolve. Get better. Adapt. I'm totally in favor of going forward. Always.
I'm not complaining about the changes themselves, but where and how they're being introduced.
Which leads me to my next point.
But That's Not Our Fault
Oh, but it is.
Sure, the library maintainers could design a better, easier way to introduce breaking changes. But we are the ones asking for all these features. ALL. THE. TIME.
Think about it. Open-source libraries are just keeping up with the demand. If they're changing that much, if so many solutions for the same problems done in a different way keeps being released then maybe, just maybe, it's because we are asking for it.
We are schizophrenic too. We keep asking for the newer, shinier and better, but then complain about how fast changes are coming.
If I'd have to say one good thing about Webpack's change pace (or any other library for that matter), I'd say it shows library maintainers are listening to their users and keeping up with their competitors. That's always healthy.
Changes usually means we're going towards a better direction (there are some exceptions, sure), but there is always the good and the bad way to introduce breaking changes depending on a given context. By choosing to be both Standalone and extensible, Webpack might be making it hard for both users and plugin developers to keep up with it's changes. And some of them may never do.
Do you disagree with me? I'd love to hear thoughts about this. Go on, I can take it.
Also, I apologize for any grammatical errors you may come across. English is not my native language.