> I hate hate hate that modern web development requires a build system
Why? For any sufficiently complex software system, a build system serves as a reducer whose input is something that is more convenient for developers, ie huge codebase with tons of utilities and annotations, and whose output is something more optimized to run on the end users' devices.
It's good to do such optimization because there will be, at least for a successful project, many orders of magnitude more EUs than devs. And an automated solution can do much more optimization than any team of devs could ever hope to do manually.
And that's before you get into obfuscation, although I can't tell whether that's necessary more for user security or just protecting IP.
(Not a web dev, I write in a compiled language in my day-to-day.)
One more thing to know, to update, to break, to configure, to consider when debugging. The existence of source maps proves just one aspect of the pain this indirection and complexity introduces. I’m not necessarily arguing the trade offs don’t make it worth it, merely that there is a cost and there are good reasons we’d want to avoid it if, all else being equal, we can.
Then you can just use ESM straight in the browser... The payload will be bigger, but it's all JS turtles the way down.
I think for me the only small down side (beyond request count/size) is you couldn't use JSX and a lighter interface (preact or similar). One option would be a service worker to transpile JSX on demand... which I guess wouldn't be too hard to do.
Because the need for a tool that bridges the impedance mismatch only hides the impedance mismatch even more, it allows developers to be even more remote from end users than before. It doesn't even start to question why we have an impedance mismatch in the first place. It keeps engineers in their position of those-who-know, and end-users in their position of those-who-need, preventing appropriation of technology.
As software engineers we ought to question if we're going in the right direction, and "more complexity" is not something I agree is better
In what other similar user-facing system would that be the case? There is an impedance mismatch just in the fact that a UI is much different from code itself. There is a mismatch between what your parents can learn to use (UI) vs. what computers can understand (code). Most other UI projects are compiled (native apps), and they don’t even need to care about sending that final executable over the wire very quickly, or even other web optimizations a bundler might do like code splitting.
These systems become complex because the web is a much different deploy target than, say, iOS.
Having to manually kick off a build process is another thing that I have to go do that takes me out of the flow and is another point where things can go wrong.
When you run a Deno script, it has a build step that it does internally, so I don't have to think about it, and I don't have to configure anything. It just works because it was designed that way. I don't know why more language runtimes aren't.
Even when I want to compile a JavaScript bundle to run in the browser and there is an explicit build step, `deno bundle` is far simpler and more pleasant to use than the mess of npm packages I would have to worry about in the Node world.
Fun fact: the "compilation" step in my company's React project is the biggest consumer of CI minutes by far across our entire organization, beating out every one of the Maven compile and test loops
But, since the devs don't care, there's only so much finger wagging I can do
Over the course of a month or two the time taken to compile a single .ts file in our codebase climbed from 'too small to measure' up to '7 seconds'. It eventually turned out that a single type definition in the file was causing all typechecks to become incredibly slow. Getting timing data out of build tools like rollup was brutal, and editors with tsc integration like vs code/sublime text would just lag and misbehave. This regression had occurred without anyone noticing, because we all just assumed it was normal for 'build and bundle our typescript' to take a long amount of time despite how simple our code was.
I have to say, for some reason one of the more satisfying things to do is dramatically speed up a lengthy build. It’s hard to beat taking a build that runs forever and making it take a few seconds.
I don’t know why. Perhaps it’s because it’s something you and your peers use constantly so when it speeds up the quality of life for all in the shop improves. I mean, it’s not often you get to make an improvement to your project that directly affects everybody working on it.
Perhaps it’s because of the challenge and that most developers absolutely hate fucking around with the build system. Example: the parent poster. Build systems are can be pretty archaic but have a ton of features that most people don’t exploit.
Perhaps it’s because it is easy to timebox and has a readily apparent set of diminishing returns. You can generally make a single change, push it to production and if that is the only change you made you’ve still added value.
Perhaps it is because almost all of the changes you make don’t alter how the end user (other devs) use the build system. Short of swapping the build system entirely most of the time everything you do changes nothing for the developer.
Perhaps it is because it is a good distraction from whatever it is you should be working on. You can squeeze it into spaces where you don’t have much in the pipeline or need to think something through.
Whatever it is, I love fucking around with build systems.
And that is one of the main reasons I hate build systems. If I have to use a build system it had better work perfectly the first time and every time, never slow me down, and never ever require any fiddling or maintenance.
To me that's a definition of make work. A good development ecosystem should require no wizardry to make it perform well. And it adds absolutely zero value for the end user of your product. This is why myself and 99% of developers abhor Rube Goldberg build systems like those that permeate JS.
Had similar issues with linting/formatting... switched to rome.tools a couple months ago and really happy with the change. I'm really looking forward to that project's goals too.
I'm not really sure, I haven't followed the development that closely... I know I tried it... and it was pretty close... when I was ready to switch, had done some testing, and had to adjust several of the defaults to be closer to the existing linter config. That said, the reformat/lint-fix was so fast, it wasn't that big a deal. Did it in two commits, one with just the linter config, another with the reformats in a separate commit.
The whole project can be scanned and reformatted and lint-fixes applied in under a second... the eslint config with TS took several seconds... as a precommit hook it felt pretty painful in practice, now you don't even notice it.
If they do as well for build options (once added), I'll be very happy indeed.
Granted, we have all moved from receiving updates to languages/frameworks once every 1-3 years (C# etc) or C++ with 3-8 years and instead get them monthly (sometimes even daily).
Devs from the past who wrote chunks of FORTRAN that sat on a "dusty 386 in the basement for 30 years" are still around, what do they think of the constantly evolving field/goalposts vs more traditional, slower release cadence of languages/frameworks/software in general (afaik; I wasn't around for it).
Build CI should be configured with a very aggressive upper limit to catch those regression but it's often forgotten; even I don't do it often while I have been bit more than once.
Not being snarky, but Lisp and Forth should have interactive experiences that the other languages do not have. The Pascal related languages are renowned for being designed to be compiled at high speed.
This is a wonderful book, "The School of Niklaus Wirth: The Art of Simplicity"
You can use Python or PHP or some other language that doesn't have a build system, and whose performance and security model bests that of server side JS. (Deno, Node, Bun, etc.)
I run one Node/Js server and several Nginx/Php servers.
When Node was released, it had better handling of multiple long-lived connections. Nowadays, support for SSE on Node trails all other servers, and the dream of "Isomorphic" code that doesn't need to be rewritten has not panned out (in JS, at least).
The main reason I could imagine someone choosing Deno now is that it is the tool they know best (such as someone fresh out of college). Which may not be a bad reason, but it is hardly the best tool for the job.
Try Deno anyway, if you haven't. The DX is very nice. I am very fast at cranking out small CLI tools -- and it gives binaries. Though sometimes I debate if Python is better for these tools, since it's so easy to get something going there too. For a JS maximalist stack, Deno no question.
Why? For any sufficiently complex software system, a build system serves as a reducer whose input is something that is more convenient for developers, ie huge codebase with tons of utilities and annotations, and whose output is something more optimized to run on the end users' devices.
It's good to do such optimization because there will be, at least for a successful project, many orders of magnitude more EUs than devs. And an automated solution can do much more optimization than any team of devs could ever hope to do manually.
And that's before you get into obfuscation, although I can't tell whether that's necessary more for user security or just protecting IP.
(Not a web dev, I write in a compiled language in my day-to-day.)