It's not just build time, it's the indirectness. I'm seriously contemplating dropping it for a next project and just writing straight JS, whichever dialect (es6?) has the widest adoption.
For most people working on larger projects, though, the advantages of real dependency management (however broken NPM is) and transpiling JSX or TS is worth the compilation, which you get used to.
Living without a bundler was alright.
At my last job we checked Google Analytics and almost 100% of our users were on greenfield browsers, so we moved to that and had no issues.
Common Lisp had true liveness for decades; it's almost mandated by the standard, it's designed in such a way that you can actually recompile a function, or even redefine objects, adding or removing properties or methods, at fucking runtime without restarting the application. Objects already instantiated will remain so and will be updated to reflect the change. You don't restart. That's the true "liveness", but seriously you don't get it until you try it, and once you get it you become depressed because you realize it doesn't really exist in any mainstream language.
JavaScript is some decades behind this dream, even with stuff like Webpack.
This can be done in a number of other common languages today such as Java (JVM languages) and C# (probably all .NET languages). Most IDEs I've seen for those platforms support it.
Substantial enough changes to the code can require an application restart, but most changes you might make like changing the implementation of a function, adding new functions to a class, etc., will not. Hot Code Replacement (HCR) has been supported since Java 1.4: https://wiki.eclipse.org/FAQ_What_is_hot_code_replace%3F
Fully dynamic languages like Lisp and Smalltalk permit a greater degree of this than statically typed languages do, however, since they don't have types and a type system to wrangle with. When I've used it, hot code replacement supported most of the changes that conceptually make sense to support.
I do procedural music in JS/web audio, and my projects are set up so that changes to the logic and instruments all happen live, while the music continues to play.
How is that different from what you're describing? What specifically can't webpack/HMR do?
I’m not an expert, but I think the way it works is that Webpack provides a way for JS modules to register callbacks for what should happen when Webpack detects changes in them and recompiles them. React then provides such a callback implementation for component modules that causes the individual component to re-render. Webpack’s development server also provides a way to inject new code into your app running in a browser.
Things get a little more complicated if you want to hot reload things that deal intimately with state, like Redux reducers or middleware. AFAIK people usually just have the browser do a full page reload when changes are detected in those modules. I think Webpack will actually automatically trigger a full page reload if it detects a change in a module which does not explicitly declare how hot module reloading should be handled.
I only mention React and Redux because it’s the only major stack I’m at all familiar with; I don’t know if other stacks provide similar functionality.
Erlang provides this as well, as do many dynamic languages. However, aside from certain Lisps and Smalltalk that are image based, and a few others, liveness and source persistence are typically traded off for each other. I can make a live change to a Ruby system if it is set up to provide a REPL, but unlike a live Smalltalk change I won't then have the source code for the changed but available the same way it is for the rest of the system. As a result, in many languages live coding features are mostly a tool for experimentation (usually in nonproduction environment!) on code that will eventually be incorporated into traditional source tree for a from-scratch build.
- Zope (python app server) had a feature where you could debug a web application (in production) in a private session, so all code modifications you did in your session were private until you committed the code.
The hypothetical build system can, whenever files change, run the build again (in a container), execute tests (complaining when you break one), or let you keep the debugger open while you're editing (best attempt made to fast forward).
This is probably better suited for modern languages with proper modules and incremental builds, like Rust, C++20, Java9.
Plus webpack got a lot better even in that regard, and there's alternatives like Parcel pushing the curve. Web devs sometimes don't realize how good they have it :-)
Doing an `npm run dev` type of command in a reasonably set up JS project is very much this staged execution model the author talks about. Everything gets cached, on disk and in memory, only changes are recompiled, and reloads are fast, partial, and often hot-swapped. It's quite close to the maximum level of "liveness" I can imagine.
It's kind of amazing how JS took over older and more established languages in this sense - and we're still not content (judging by how popular it is to complain about webpack). This is great.