When you write code in a team, you optimize for readability, maintainability etc. You spread your code over 5 directories, 50 subdirectories, 3000 files.
When you want to run this in a browser environment, it needs to be optimized for delivery - faster download, less time-to-be-interactive. You need to split your JS codebase as per routes in your app, and load chunks as per user demand.
Not just JS, you'd have to compile and inline your CSS, base-64 encode your images to data-urls, generate image stripes.
Before all these, you'd have to lint your code, and run unit tests on your code.
I fail to see how you can do all these with just a script tag. You need some sort of a compiler / transpiler; and a task runner that gives you a handy interface to these.
The package manager has no dependency, other than the Node runtime itself.
As for arbitrary toolchain, the metadata is codified with semantic versions in your package.json. You're one install step away from downloading all the necessary packages.
One thing I think lot of Node project misses, is to not add which Node version is to be used. It's not because it's impossible to do that - there are two well documented ways to do that (via .nvmrc and "engines" entry in package.json)
The fundamental issue is that the overwhelming majority of interactive websites today don't actually need to be interactive, and may even be better off as old-fashioned HTML pages served by the server.
But people love over-complicating stuff, and when the end result is complex the toolchain has to be complex too, not just for one person but the whole team. Then you end up with developers who spend more time wrestling with webpack et al than working on actual features.
Some of the incentives fueling this trend could be viewed as undesirable (e.g. monstrous ads on news sites as a desperate bid for profitability), but that doesn't negate the fact that the incentives exist, and aren't simply "people love over-complicating stuff".
To illustrate, hacker news and reddit work fine with javascript disabled, and the javascript they use is simple and just makes some interaction like voting work nicer. Even amazon, which is a pretty bulky and interaction-heavy site, works quite well with javascript disabled.
As for incentives vs over-complication, there's an interaction there. The incentives are to put some fancy whirly whingding on your website because it looks flashy and your target audience has (according to you) fast internet connections and web browsers. The incentives are to do this with the minimum of effort even if that means serving multiple-meg, javascript-heavy pages that don't even have any interaction.
Your solution to the JS ecosystem is to make news websites less interactive. I see why you long for simpler times but I don't see how that fixes things.
For those of us who are building applications we need the complexity. It solves problems that come from the fact that the web has evolved from a hypertext system to an application platform.
One of the trends I'm seeing is that a lot of developers once they have built one web site as a SPA they seem to start thinking everything should be built this way. More consideration should be given to deciding which is appropriate.
I'm not saying don't build applications. I'm saying web applications can be server-only and should not spill over into the client.
Again there are exceptions - things like control panels or consoles do benefit from being SPAs. But in a lot of cases there is also nothing wrong or insufficient or unsatisfactory (from a UX perspective) about clicking a link and having the server send you pre-rendered HTML. JavaScript can still be used as icing on the cake to enhance those interactions, such as by displaying a spinner on the submit button and disabling it once the user clicks it.
We need lots of tooling to keep our code readable across a zillion files.
And it is worse than you mention. You rarely get 60 files per directory, and, in addition to the files you want, your package manager and build system add a few zillion of their own that all can break your build in 'interesting' ways.
To compile a Qt app you need: - the meta object compiler (moc) to add dynamic features to C++ for Qt use - the Resource Compiler (rcc) to embed icons or sounds as arrays in header files - the Qt Quick Compiler if you are using QML files for your interface - the C++ compiler, linker, etc.
This is either driven by CMake, qmake or your IDE!! I see you can use Qbs to generate the CMake or qmake files! I remember learning CMake, make, ant, etc being non-trivial!
Oh, and you were on your own when it comes to dependencies!
Of course, your point still stands. But's a tradeoff. C++/Qt has a ton of compile-time bloat, while Node/Electron has runtime bloat (see the Slack client using hundreds of megs of ram). And you can use bindings, like PyQt, where you have Python/Qt and then you get Python's dependency management.
Comparing C++ to Node or Python doesn't help me. If I could write Python that run in the browser I wouldn't be commenting here.
[1]: https://unpkg.com
I used to prefer a 0-dependency, no-build format for sites. Nowadays if something doesn't have an npm module it's enough for me to not want to use it for a variety of reasons.
I used to install "dependencies" by copy and paste and was happy, but because I didn't know how it could be better. Despite all of npm's woes (which are many) the concept is sound, and not just for JavaScript.
Just look at all the Node.js drama. Today I read they want to fork again, while they just consolidated their last fork...
It seems as if it's impossible to publish a Javascript project without taking for granted that the developer has, or even wants, a package manager with dependencies, arbitrary toolchain and transpiler along with it.
Maybe I'm just a dinosaur for not wanting my "build process" for javascript to be more complicated than including a script tag. That's probably what it is.