[HN Gopher] Going Buildless
       ___________________________________________________________________
        
       Going Buildless
        
       Author : todsacerdoti
       Score  : 63 points
       Date   : 2024-09-08 09:53 UTC (13 hours ago)
        
 (HTM) web link (mxb.dev)
 (TXT) w3m dump (mxb.dev)
        
       | jeffreygoesto wrote:
       | You logged on via telnet, not ftp. And you tested with "telnet
       | webserver 80".
        
         | devbent wrote:
         | 2005 was definitely either ftp or ssh/scp mounts if working
         | from Linux!
        
           | surfingdino wrote:
           | You were also forever recompiling modphp.
        
       | devbent wrote:
       | I am going build less for a recent project. The main difference
       | for me is jsdoc vs typescript. There was a large initial learning
       | curve, and the syntax is ugly, and having to duplicate all my TS
       | types from the backend as JS doc types on the front end sucks,
       | but at the end of the day it does work.
       | 
       | I was surprised how well module imports work in modern browsers.
       | 
       | I've never used css preprocessors before, so that wasn't an issue
       | for me. I also have never nested CSS files, so that also wasn't
       | an issue for me.
       | 
       | Another pain point is not having type safety on my front end
       | calls to my backend. With TS I could use Zod on the front end as
       | well and have type checks in place before I make those API calls.
       | While obviously js doc tries to ensure at compile time that
       | things are the correct shape, that isn't the same level of
       | assurance.
        
         | tacone wrote:
         | You can use typescript on plain js files, just for type
         | checking, without the need of a build.
        
           | lyxell wrote:
           | I guess you mean relying only on type inference? That will
           | only get you so far. E.g. function parameters for
           | freestanding functions would still be untyped. For those to
           | be typed you need TypeScript or JSDoc annotations as OP
           | noted.
        
             | cdaringe wrote:
             | Probably the OP meant "allowJs" and "noEmit" flags give you
             | limited actual typechecking in your JS files
        
           | devbent wrote:
           | I'm already enabling @ts-check so they the jsdocs actually do
           | something!
        
       | deafpolygon wrote:
       | Hey wouldn't it be nice to go back to simpler times?
       | 
       |  _adds more complexity_
        
       | mikeocool wrote:
       | I begrudging tried tailwind css recently. I was shocked to find
       | that when using a CSS framework where you embed all of our
       | styling in HTML, I STILL needed a css build process to do trivial
       | things like customize the default link color.
        
         | jampekka wrote:
         | Tailwind is madness.
        
           | adamtaylor_13 wrote:
           | Eh, it fixes a different sort of madness in an elegant way.
           | Tailwind has gained huge traction for good reason.
           | 
           | I'll take its idiosyncrasies which take less than an hour or
           | so to understand (spread across a few days of usage) as
           | opposed to raw CSS which is a totally different sort of
           | madness.
        
             | jampekka wrote:
             | Apart from maybe container queries, Tailwind is little more
             | than inline CSS style with a bit different syntax. The
             | madness of CSS is not syntactic, and Tailwind doesn't
             | really help with that.
             | 
             | I can see that Tailwind does prevent architecture
             | astronauts going crazy. But that's a cultural issue, not
             | technological.
        
           | evilduck wrote:
           | I didn't like it at first glance either but Tailwind is very
           | sane. Every not-Tailwind approach I've encountered over the
           | last 20 years has laughably and without exception fallen into
           | the exact same problems that led to Tailwind being created:
           | https://adamwathan.me/css-utility-classes-and-separation-
           | of-...
           | 
           | If you're a solo dev, sure, you're free to do anything you
           | want and nobody will balk or complain about you causing them
           | extra work or having to clean up a mess later. If you're on a
           | small project and the CSS will fit onto a couple sheets of A4
           | paper, you also won't have enough volume of code to see major
           | benefit because you could just rewrite an entire UI of that
           | scope from scratch in a few hours. But on a team working with
           | a larger codebase Tailwind solves real problems in
           | maintaining styles across developers and over longer periods
           | of time.
        
             | jampekka wrote:
             | How does inline utility classes _help_ with not creating a
             | mess with a team?
             | 
             | Merits of semantic classes and class hierarchies are very
             | debatable. And CSS dropped the ball with style composition
             | (which e.g. SCSS fixes). And media/container query
             | ergonomics aren't ideal. But essentially hardcoding styles
             | inline is a very weird reaction to these. A bit like "let's
             | get rid of variables and hardcode values in functions
             | because OOP inheritance caused a mess".
        
               | et1337 wrote:
               | The article linked in the grandparent directly explains
               | how utility classes are different from inline styles:
               | there are infinitely many possibilities with inline
               | styles; not so with utility classes. The empirical
               | numbers in the article are fascinating. 400+ different
               | colors in a single CSS project that's supposed to be
               | "semantic". With utility classes, you are forced to
               | choose from a finite set of colors.
        
               | jampekka wrote:
               | That is not a matter of using inline utility classes. You
               | can and probably should use e.g. CSS variables or @apply
               | preprocessors to enforce a finite set of colors.
        
         | cjpearson wrote:
         | Tailwind is a CSS build process. If you only want to customize
         | the default link color it probably isn't the right choice. If
         | you want to avoid a build step, it's also not the right choice.
        
       | brainwipe wrote:
       | Articles like this remind me how little the browser environment
       | has moved on in recent times. Now all the work is done by the
       | frameworks.
        
       | wackget wrote:
       | This guy unironically wrote an entire article about how to "get
       | simplicity back" and avoid using server-side processing by doing
       | a bunch of crazy convoluted JavaScript crap which runs on "the
       | edge" (i.e. a server).
       | 
       | You can't make this up.
        
         | hinkley wrote:
         | Hedonic treadmill. Even the people who are old enough to
         | remember what simple used to be like have had their pain
         | thresholds reset by the intervening years. And then there's a
         | bunch of recent vintage senior people who don't know any other
         | way.
        
       | jampekka wrote:
       | Esbuild in serve mode is a very good emulation of "buildless".
       | Sad that its model, vs the usual fiddly file watching, isn't used
       | more.
        
       | cxr wrote:
       | If you _are_ going to use a build tool and you decide to create a
       | new one written in JS, then please write it in standard JS (i.e.
       | what Web browsers implement; nothing to do with standardjs.com)
       | that calls standardized APIs (again, all browsers--the things
       | that everyone already has installed--implement them). Please don
       | 't code directly against e.g. proprietary Node APIs.
       | 
       | If you have a stupid simple HTML+CSS+JS project that nevertheless
       | uses a build tool for some reason, a contributor should be able
       | to clone the repo, open the README, read the instructions on how
       | to build it and not encounter "first, install bun" (or whatever);
       | in 90+% of cases, those instructions don't actually need be
       | anything more complicated than "First, open the build script in a
       | browser tab. Now drag and drop the project folder onto the build
       | tool." You can double up and make that build script your README
       | if you want--call it README.html.
       | 
       | It's baffling the numbers of folks who decided to focus on JS
       | development because they wanted to draw on their
       | familiarity/desire for developing for the browser and out of
       | recognition that being able to create browser-based apps and
       | deploy to users without making them install anything is a huge
       | boon... and then went on to make a bunch of shoddy tooling that
       | despite itself being nominally written in JS still requires you
       | to download a bunch of other stuff to run it and doesn't leverage
       | the standard JS runtime that everyone _already_ has installed.
        
         | adamtaylor_13 wrote:
         | I feel like installing node is an incredibly low bar. I agree
         | on the principle, but reality is that "first installing bun" is
         | so damn easy that reality and principle diverge quickly.
        
           | saulpw wrote:
           | For now.
        
           | wiseowise wrote:
           | Good luck installing bun on my locked work machine that
           | doesn't have bun cleared.
        
             | hinkley wrote:
             | Does this system prevent you from installing node via nvm?
        
         | wiseowise wrote:
         | > Please don't code directly against e.g. proprietary Node
         | APIs.
         | 
         | What Node APIs are proprietary?
        
           | mattlondon wrote:
           | All of them? You need to have node installed to use them.
           | 
           | Standard APIs work in chrome or Firefox or safari.
        
             | fragmede wrote:
             | but you have to have chrome or Firefox or safari installed
             | to use those APIs. What if you're somewhere that doesn't
             | have any of those as an option?
        
         | franciscop wrote:
         | Please clarify how you'd be e.g. reading JS files in a
         | Node.js/Bun/worker/function/etc without using Node.js (or any
         | of those platform/runtime-specific platforms) APIs? I'm not
         | sure I'm following.
        
           | nine_k wrote:
           | "Drag the project folder onto that" probably means you're
           | uploading the entire project, and them make the result
           | downloadable (as e.g. tar.gz or zip), without ever having to
           | _directly_ interact with stuff like filesystem.
           | 
           | If that could be pulled off, it would be a great way to
           | isolate the build process and prevent malicious packages or
           | build tools from mucking with your system.
           | 
           | Does not look very realistic for projects of any considerable
           | size though.
        
             | cxr wrote:
             | "upload" and "download" are misnomers, but yeah, pretty
             | much.
             | 
             | To the original commenter: I don't recommend using Node. I
             | said use the World Wide Wruntime instead. Even so, there's
             | a difference between an app that might incidentally use an
             | API somewhere down the line versus programming directly
             | against that interface.
             | 
             | Look at the early versions of the TypeScript compiler.
             | Here's 1.8: <https://github.com/microsoft/TypeScript/blob/r
             | elease-1.8/src...>
             | 
             | tsc doesn't care whether it's running on Node or in the
             | browser or somewhere else. I think the TypeScript team
             | originally bootstrapped it with the Windows Script Host
             | JScript implementation (available pre-installed on all
             | Windows machines) and didn't start using Node until later
             | on.
             | 
             | The only thing the compiler cares about is that something
             | implements the ts `System` interface, so the compiler can
             | invoke e.g. the read-file operation (which belongs to
             | `sys`, i.e. `sys.readFile`) and that it does what it's
             | supposed to do. And it can use the method/capability for
             | listing directory contents, the one for getting the
             | arguments, and so on. That's all defined and implemented
             | straightforwardly in a short file sys.ts.
             | 
             | Figure out what services (capabilities) your program
             | _actually_ needs and sketch out an interface that permits
             | all those things. Then write your program against that
             | interface. It 'll make your program more readable, anyway.
             | 
             | > Does not look very realistic for projects of any
             | considerable size though.
             | 
             | Define "realistic" (or "considerable size"). All of
             | Firefox's non-core (i.e. not Gecko) components and the
             | build phase involving them that produces the final release
             | package (~90MB[1]) could probably work this way. (If anyone
             | actually cared about it[2].) Maybe even VSCode, too.
             | 
             | Could you do this with any given project you stumble across
             | on GitHub today? Maybe not, but that's because your average
             | NPM programmer turns out programs that use entirely Too
             | Much Fucking Code for what ultimately is just a todo app or
             | whatever. I once benchmarked create-react-app's "hello
             | world" exercise from a blank slate a few years ago. The
             | numbers involved ended up with `node_modules/` taking up
             | something like just under HALF A GIGABYTE of disk space.
             | For a "hello world" app. That's nuts.
             | 
             | 1. <https://ftp.mozilla.org/pub/firefox/nightly/2024/09/202
             | 4-09-...>
             | 
             | 2. <https://news.ycombinator.com/item?id=41358029>
        
         | mattlondon wrote:
         | Agreed. Too much stuff assumes NPM is available for installing
         | things. I don't have NPM installed and I never want to install
         | it either.
        
           | davidmurdoch wrote:
           | What languages do you use that don't have a package manager?
        
             | sabbaticaldev wrote:
             | you don't need to use npm to add packages to a JS project
        
       | ciconia wrote:
       | I'm currently working on a dashboard-type SPA, with no build
       | tools. Just a single file of HTML, a single file of CSS, a bunch
       | of plain JS files with an import map, and a single dependency on
       | d3 (also imported as a module). In total about 10Kloc.
       | 
       | I have to say, it's been a few years since I last did front-end
       | dev work, and I was really pleasantly surprised by how much
       | better CSS and Javascript became. All in all, it's been a really
       | positive experience.
        
       | azeirah wrote:
       | I sshed into my personal site vps this morning, created a file
       | with vim, pasted in the html and added some styles by copying
       | them from a php file in the same directory.
       | 
       | All on the server!
       | 
       | Do I get nerd creds now? <3
        
       | jweir wrote:
       | Except for CSS via Sass I have not used a build process in all
       | these years.
       | 
       | And recently I rewrote our CSS to use modern syntax and nesting
       | and variables and etc. - no more Sass!
       | 
       | It worked great but then customers started to complain and send
       | messed up screenshots.
       | 
       | Turns out a lot of Android phones are using an older browser and
       | a couple of customers were locked into old versions of Chrome by
       | corporate policy.
       | 
       | Fortunately this was all nesting rules. So renaming the css file
       | to scss and running it though Sass fixed the issues.
        
       | bryanrasmussen wrote:
       | >The obvious tradeoff for a buildless workflow is performance. We
       | use bundlers mostly to concatenate files for fewer network
       | requests
       | 
       | generally small parallel requests perform better than large
       | single requests in a modern situation - modern browsers, HTTP 2+
       | etc. - in my experience - but there can be a lot of caveats about
       | that statement.
       | 
       | However the import statements in the css are not downloaded in
       | parallel last time I checked - and probably never would be
       | because of ways css works, so this using import statements inside
       | css instead of having a build of a single css is actually the
       | worst possible solution I think (ok there is probably something
       | even worse that you could build if you really wanted to but worst
       | "reasonable" solution)
        
         | hinkley wrote:
         | The goal of buildless is to avoid friction in the code-build-
         | test cycle. There are time cutoffs beyond which the human brain
         | tries to multitask, and the multitasking involves making
         | multiple adhoc estimates per hour, which we all know are always
         | off by 2. Every three minute pause wants to become six.
         | 
         | So the trick is if you can keep the build to seconds you don't
         | change your workflow. Which means you might be able to pick one
         | transpiler like Less, and throw a watch on it, and still be
         | fine.
         | 
         | As long as, that is, you make a cultural decision not to go
         | fucking nuts with the CSS. You need a low threshold for
         | triggering tech debt cleanup.
        
       | apitman wrote:
       | Most of my web projects these days are vanilla. I'd been dabbling
       | on simple things for years, but it took a big leap a few months
       | ago when I discovered Web Components are still a thing and have
       | come a _long_ way since 2012. We 're finishing up re-writing an
       | app at work that went from a ~17 dependency Vue app to a ~2
       | dependency (d3js) Web Component app. The codebase is a joy to
       | work on. No more dependency hell. We don't even need npm. The
       | code, as committed to git, will probably still run unmodified on
       | browsers in 20 years. It's a great feeling.
       | 
       | A few tips:
       | 
       | * If you have a lot of JS files and want excellent performance
       | you may still be able to skip a build step by leveraging
       | `modulepreload`
       | 
       | * If you want some typing while still running without a build
       | step, you can use JSDoc to embed TypeScript annotations for your
       | JS[0].
       | 
       | * If you really want to have a mostly HTML site but don't want to
       | manually duplicate code, I've had decent success with a technique
       | I call "tuplates"[1][2]. Basically it's a very simple templating
       | tool where the output is intended to be committed to git. It uses
       | comments so it's language agnostic.
       | 
       | * If you go web components I highly recommend these best
       | practices[3]. A lot of them were confusing for me at first but
       | just keep them on your radar as you're learning.
       | 
       | [0]: https://www.typescriptlang.org/docs/handbook/jsdoc-
       | supported...
       | 
       | [1]: Description: https://github.com/anderspitman/tuplates-
       | js/blob/master/READ...
       | 
       | [2]: Latest implementation:
       | https://github.com/anderspitman/tuplates
       | 
       | [3]: https://web.dev/articles/custom-elements-best-practices
        
       | cies wrote:
       | What is a build for? The article does not really articulate it.
       | 
       | * Dependency management (use libs so you dont have to
       | write/maintain that code yourself) * Code generation (we use that
       | for added typesafety: jOOQ the SQL eDSL, and OpenAPI3 for
       | generated clients + server-side DTOs) * Compilation (compile
       | higher-level languages with strong type-safety guarantees, e.g.
       | Kotlin, Elm, Haskell, Rust, TypeScript; to lower-level or dyn-
       | typed/quirky languages, e.g. JS, WASM, byte-code, binaries)
       | 
       | Three pretty important advantages!
       | 
       | Sure builds come with added complexity, so it is a trade off. But
       | when carefully picking technologies this can greatly pay back the
       | cost of complexity.
       | 
       | Now, if you compile, say, JS to JS (less to CSS) with brittle
       | build tools such as npm (shell commands in a string in a JSON
       | called packages.json), and low quality dependencies, then the
       | advantage your build step probably negative.
        
       | somishere wrote:
       | I'll always start vanilla / build-less with best intentions. In
       | fact, I often start sans JS too if I can get away with it.
       | 
       | But inevitably the complexity of my projects increase. My
       | patience with focus, refresh, review cycle crashes. My first stop
       | is usually vite, just for hot reload at first, but then for raw
       | imports, and I do like nested CSS. When I find myself beginning
       | to roll my own reactivity I tend to read up on the latest state
       | of vue and svelte and drop whichever one feels right into the
       | mix. It goes on.
       | 
       | All with the best intentions.
        
       ___________________________________________________________________
       (page generated 2024-09-08 23:01 UTC)