The largest, most painful and apparent issue with JS related build tools is that they change and break. Frequently.
And no, `package.lock` is not enough of a solution, because you will have to update dependencies at some point. Congrats, you now have multiple moving, breaking parts in your dependency tree that throw the weirdest and unrelated errors. So you're hunting down github issues, workarounds and patches, while still not really knowing what the problem was. The bonus here is that you need to remove these workarounds at some later point because your build tools and libraries have fixed the issues, so your code breaks again with very fun error messages or just straight up opaque and weird behaviors.
At some point we have to ask why we're doing this to ourselves. It's not fun at all.
Agreed. Try inheriting a project that hasn’t been updated for a few years. Between the absolute dependency hell, and major breaking changes, there is huge temptation to just rewrite the whole thing.
Even a basic application requires layers upon layers of dependencies. Many of them are not as mature as people like to think either.
Rollup has always been a straightforward path. Vite (built on rollup) is super clean. Before that even, webpack was relatively stable between versions.
If you just used Gulp / Grunt / Browserify I am a little more sympathetic, especially with Grunt / Gulp, but I always felt their limitations were obvious.
Browserify somehow managed to snatch defeat from the jaws of victory IMO
I think almost of these are on the list of past and present enemies. I haven't used Vite but I have better things to do than change the build tool in dozens of projects a year without any guarantees that it will not break like the rest of them.
if you adopted vite from 1.0, you wouldn't have a need to change build tools in dozens of projects a year. Its really stable. Same with rollup. Webpack (was?) a little less stable, but it didn't churn at that rate either.
I'm just not sure where the churn is from. If you're talking about meta frameworks, like create-react-app, that churn alot and change things underneath, I get it, though with tools like that, one should always seek to stay on the happy path only, as its otherwise a recipe for disaster.
Everything you said is true, but it's not limited to JS once you add 'package.lock' isn't a solution.
I've had compatibility issues with rebar, rubygems, pip, go modules and many more.
Once you're pulling in third party dependencies and the tools that manage them - in any development environment - you open yourself up to these issues. At some point, you have to update dependencies and/or tools (for security reasons if nothing else). And at some point, either the dependencies or the tools will break in a way that has you hunting down issues and workarounds that are outside the scope of what you're actually trying to accomplish.
Is JS significantly worse in this regard? It does seem like the propensity for many small packages increases the surface area of things that can go wrong, but that doesn't seem to be a flaw in the tooling.
The problem is that if your underlying stuff, like npm, webpack, babel or w/e changes or breaks, then _everything else_ breaks too. _All_ your dependencies can have potential issues. Meaning you have to update them and boom you code breaks too now, because someone decided to change the API.
And yes that means that bigger surface area leads to more problems.
This is less severe if you are only working on few projects at a time that you gradually update. It still sucks and is completely unnecessary, but only in tiny bits over a spread out time period.
However if touch code from just a year ago, then you might get some of these fun, breaking changes and bugs. Even more fun if you're not familiar with the build tool, or the packaging tool, because there are a dozen of those around as well and someone decided to use X at the time because why not. And you need a specific version of those too.
The Go modules thing is similarly painful, but it's not the best example of what I describe, because there is a very clear cut change from the previous way of doing things. It sucks but there is a clear path forward. With a JS project you get the feeling that you are walking on a minefield.
JS is significantly worse. npm, yarn, webpack, babel, rollup, vite etc etc. Too many dependencies. Too many breaking changes. if build fails, error messages are horrendously cryptic.
Change, sure. We've had browserify, parcel, rollup, webpack. Then the next wave hit with snowpack, esbuild, vite, lasso, turbopack etc.
There's a few that have hung around like rollup and webpack, but there's definitely a constant feel of chasing the dragon when it comes to js bundlers/builds, if not JS tooling as a whole.
I have encountered a mix of several weird bugs and breaking changes with gulp, webpack, rollup and what ever Nextjs uses. Also build related bugs with several popular libraries and the resulting versioning and dependency issues. NPM has disappointed me in similar ways at least a couple of times too. Babel is its own hell.
Basically touching a JS project that hasn't been updated monthly is incredibly anxiety inducing.
And now there are several new build tools since a relatively short while, which makes the issue even worse. They might be improvements in some dimensions but they all invent their own little world again, promising this or that. But it all sounds so familiar and I already lost trust.
I'm proud to say I recently published a library on npm and decided to specifically deliberately not publish anything other than ESM. Now bundle sizes are significantly smaller.
That’s the right thing to do. The issue that I mentioned included switching suddenly in highly depended-on packages without waiting for major end-user tools to catch up, splitting NPM across ESM for few months. It was a deliberate and non-systematic action. That’s why it’s worth ignoring it here.
Absolutely nothing and I advocate and push for them wherever possible.
But I mentioned them for the usually very vocal crowd on HN (and others) that dominate any JS orientated conversation by pissing and crying that build tools exist.
Apparently, to this crowd, the act of compiling code is perfectly OK everywhere else but a travesty to need or want to do any of that for software that runs in a browser. Weird.
Build and dependency management is the worst part of the javascript ecosystem. Other languages do this much better. We're not against build tools for javascript. We're against bad ones.
I'm only against adding a build tool when it's a small project that shouldn't require that complexity. I've seen projects where maintaining the build setup was more work than maintaining the code.
Yes, I've seen that too and it's a testament to how bad the ecosystem is.
However, the kinds of problems that existed in 2015 thanks to detracting tools like WebPack and Babel don't really exist now with the fact that browsers support ES modules and Node is dragging its heels but now mostly supports ES modules.
With things like typescript and vite I now never have the problems that used to be common. In fact when I see people creating brand new projects in 2023 using WebPack I cry a little in side.
At some point having a bad tooling experience can't be solely blamed on the tools. It's a choice.