Live data from Hacker News

The tragedy of running an old Node project

abdisalan.com

381–390 of 412 posts

Re: The tragedy of running an old Node project

#381

Earlier quoted context omitted.

Good for you, my experience with Jekyll is closer to OP's experience with Node. I have a big website that I built in 2014, with tons of custom plugins, that is now stuck on Jekyll 2.x and Ruby 2.x, and has a ton of hidden C++ dependencies. The way I build it now is using a Dockerfile with Ubuntu 18.04. I probably could update it given enough effort, but I was rather thinking of rewriting it in Astro.js or Next.js.

If you're looking for a stable target you should not even consider Next.

Just avoid JavaScript frameworks altogether.

Re: The tragedy of running an old Node project

#382
post #379

Earlier quoted context omitted.

In the last few years C# did away with implicit nulls. Nullable and non-nullable object references are disambiguated with T? and T. There are multiple keywords and expressions to further make it nice to work with these. You would be correct to note that there are "nullability holes" in certain edge-case scenarios, particularly around JSON serialization. But other than that it's a pretty smooth sailing. If you do use…

I know it's a bit like Kotlin. I heard though that C#'s move still has some std lib bits that are nullable.

The idea is not to never have nulls. It is pointless (ha) - the way to understand T? vs T in C# is like an optional.

The entirety of standard library is annotated since long time ago. All new and not so new projects are also null-aware. Pretty much either completely legacy libraries or libraries that explicitly removed Nullable: enable that is set by default for all new project templates do not have those.

As I mentioned previously - it isn't perfect, but the level of "good enough" of NRTs in .NET is such that the nullability is a solved problem.

Re: The tragedy of running an old Node project

#383
post #361
post #358

Earlier quoted context omitted.

"your framework prebuild is created by somebody else running a script and my framework prebuild is created by me running a script." you are right, i didn't read it that way, but i get it now. i forgot about that aspect of vue, but if i read that correctly the joke is on them because the single file component syntax is one reason i initially rejected vue. i felt that it would make editing harder because editors would…

Yeah, I can see how you read my initial comment, and given the combination of "I could probably have been clearer" and "my approach does not seem to be one people take very often" it makes sense for you to've read it how you did, hence me turning the verbosity up to 11 for my second attempt at explaining it :D Given the javascript is still inside a tag I would presume any editor that can handle a normal HTML page wit…

Given the javascript is still inside a tag I would presume any editor that can handle a normal HTML page with some inline javascript wouldn't notice the difference

i agree. it's been a while that i looked at vuejs, and i don't know why i came away with a different impression before. must have not looked closely enough.

i haven't seen mobx before, but when i read the description i wonder why i need it. my preferred framework is aurelia and as far as i can tell aurelia already does what mobx claims to solve, in particular this part (from the mobx github page):

Trying to update a record field? Simply use a normal JavaScript assignment — the reactivity system will detect all your changes and propagate them out to where they are being used

it is actually the primary reason why i like aurelia. with aurelia i don't even have to mark properties as observable. it figures that out on its own based on the bindings i make in the html template.

though mobx may be interesting when i work with other frameworks that don't do that. i'll have to keep that in mind. (edit: it looks like it may come in handy when statemanagement becomes complex: https://stackoverflow.com/questions/39454579/best-practice-u... )

keeping things as simple as possible barring some slight effort towards ergonomics, plus knowing that I understand every part of what's going on

yeah, i like that too.

I just thought you might find my setup vaguely interesting

i do indeed. thanks a lot for that. my own setup is actually also quite simplistic, but not deliberately so. it's mostly lazyness. i simply don't want to be bothered to put a lot of effort into a better dev setup. i'd rather work on actual code. so i start with plain vim without any addons, and only slowly change stuff when i run into a problem that really bothers me. solaris, AIX, irix is where i started.

Re: The tragedy of running an old Node project

#384
post #373

Earlier quoted context omitted.

one of the most crucial packages that use node-gyp are bcrypt and argon2. Both are needed heavily for password hashing while implementing authentication and while pure js alternatives are available, they run terribly

Use bcryptjs https://www.npmjs.com/package/bcryptjs

i did mention "and while pure js alternatives are available, they run terribly"

Re: The tragedy of running an old Node project

#385

I call this phenomenon "node rot". Judging by the comments here, it seems like a universal experience. My favorite is the way that Python projects rot. Not only does Python's setuptools give you all the fun that node-gyp does, the common practice of versioning packages with packagename>=1.25.5 means you're almost guaranteed breakages as pip installs newer versions of packages than what the project was built with.

Oh, one of the worst forms of torture is definitely trying to get a random Python AI project from GitHub running locally. There's almost always a conflict between versions Python, Cuda, Pytorch, and a hodgepodge of pip and conda packages. Publishing a requirements.txt is the bare miminum everybody usually does, but that's usually not enough to reconstruct the environment. The ecosystem should just standardize to using declaratively prebuilt container environments or something.

Granted, my experience is mostly from the GPT-2 era, so I'm not sure if it's still this painful.

Re: The tragedy of running an old Node project

#386
post #383
post #361

Earlier quoted context omitted.

Yeah, I can see how you read my initial comment, and given the combination of "I could probably have been clearer" and "my approach does not seem to be one people take very often" it makes sense for you to've read it how you did, hence me turning the verbosity up to 11 for my second attempt at explaining it :D Given the javascript is still inside a tag I would presume any editor that can handle a normal HTML page wit…

Given the javascript is still inside a tag I would presume any editor that can handle a normal HTML page with some inline javascript wouldn't notice the difference i agree. it's been a while that i looked at vuejs, and i don't know why i came away with a different impression before. must have not looked closely enough. i haven't seen mobx before, but when i read the description i wonder why i need it. my preferred fr…

When I start with "plain" vim the first thing I do is drop in https://trout.me.uk/X11/vimrc to nerf it back to as close to ex-vi as I can get - because my muscle memory comes from classic vis (between the mostly-BSDi job and the mostly-Solaris job I did devbox sysadmin for a software house, so I got to handle Solaris, AIX, IRIX, Tru64, SCO OpenSewer, and a couple others all at the same time ;) my experience of ex-vi versus vim is "when I typo in ex-vi it beeps at me, when I typo in vim it activates yet another feature I didn't know existed and breaks my concentration."

I took a quick look at aurelia after you mentioned it and am clearly going to have to take a deeper look at some point, I'm curious how it's handling all that under the hood, and for cases it handles well it does indeed look really rather nice (though being me I'll need to take it apart before considering using it, automagic reactivity is really cool but only when I can reliably dry-run its path through the framework in my head as I'm writing the code that (ab)uses it).

(so, cheers for mentioning aurelia, all the best conversations involve both/all people involved coming away with extra things/ideas to poke at :)

Anyway. To mobx:

I think the best may to understand mobx before you've actually used it is roughly "it not only provides simple reactivity stuff, when stuff starts getting more complicated you'll find that the more powerful tools you wanted are already there, implemented, and will show you what they're doing in the devtools out of the box."

As an example, computed() is very handy (and the one mobx feature other than just "reacting to changes" that most frameworks' reactivity implementations *do* copy, although I have vague memories of them not always copying it as thoroughly as I'd like) - so this is a bit of a "too simple" example but we're in HN comments so

    class SomeData {
    
      @observable rawData = [];

      @observable sortBy = 'someField';
    
      @computed get data () {
        let { sortBy, rawData } = this;
        return rawData.toSorted((a, b) => (a[sortBy] - b[sortBy]));
      }
    }
(sort function designed for numerics only, dumbass example is dumbass)

and then assuming your display component is tracking its dependencies somehow, a change to the `someData.sortBy` field will automatically expire the cached `data` element and notify the component so it can re-render, at which point `data` gets recalculated and re-cached (and all this will show up as events in the devtools if you've stuck them into your page somewhere).

Since aurelia is basically taking apart your bindings to figure out what to observe, I think it wouldn't be able to track that, and you'd instead have to make sure that when `sortBy` gets changed it fires a trigger to recalculate the `data` field (and then aurelia *would* notice that getting set to a new value).

(aurelia may be smarter than I think, but the only way I can think of for it to *be* the necessary amount of smarter would basically be to implement a subset of mobx's makeAutoObservable and I don't think it does that and I don't think given aurelia's (clearly consciously chosen) aesthetic it *should* do that)

I'm tending towards having viewstate kinda objects as a layer and then model objects behind them, so `rawData` would delegate to the model objects in the above example - then the code that modifies the data I'd be persisting to a backend doesn't have to think/know about how it's going to be displayed, but if you modify it - `addTodo` or an `editTodo` or similar - the change notifications will propagate outwards, expiring things in the viewstate, causing things in the view to notice and re-render themselves as required.

This is especially noticeable to me when e.g. I'm writing a data viewer onto a table of log entries (or something in that vague area, *handwaves vigorously*) and I want to have a 'Refresh' button - that triggers something in the model layer that does a `fetch()` call or whatever, and then sets the new model data to whatever the backend sends back ... and then everything re-renders, keeping all my display choices intact because the viewstate layer didn't get touched.

My experience of learning mobx included a number of "oh for crying out loud, I've implemented half of this feature the hard way in three projects before now" moments - and *that* was what made me fall in love with it.

You might also want to bookmark (and then mostly ignore for the moment) mobx-keystone, which is Even More Complicated under the hood, but provides fairly simple syntax for declaring a tree of reactive state classes that provides (typed if you're using typescript) constructors for you, tree snapshots if you want to be able to save your session state to the backend to resume later, and mutation event logging as JSON-able objects that also includes reverse versions so you can get full undo with a fairly minimal amount of effort (I never, ever want to write undo functionality by hand again, that always required a significant amount of bourbon). Not necessarily to actually *use*, mind you, but seeing what keystone is capable of was useful to my understanding of what mobx itself was capable of.

I ... there's definitely a "would rather be writing code than yak shaving my setup" aspect to my choices, but it's definitely also a question of having as few layers as possible between me and What Actually Happens so things reliably behave how I expect them to behave. Debugging is much more fun for me when I can be confident I'm debugging *my* code rather than there being a decent chance I'm actually debugging how I've misunderstood something else two layers down.

(also, if you're not doing anything particularly strenuous, I'd suggest having a look at bun as an alternative to node, all my 'real world' and/or work stuff is node and I'm not particularly offended by it, but bun is definitely a smoother and more DWIM experience for me, at least so far)

Re: The tragedy of running an old Node project

#387
post #380

Earlier quoted context omitted.

I prefer Assembly before any of the fringe languages you mentioned. There are no types in Assembly, and I rather like it that way. If you know how to work with data, then there's very little confusion about what you're doing. And there's a reason practically nobody uses the languages you mentioned, and Javascript is so wildly popular. Most people don't really like or need type nagging systems. Sure, if you're trying…

JS is popular due to it being the only browser lang. Did you forget that? Also: TS popularity shows that not everyone in the JS community agree with you. For server side web dev you will find that statically typed langs (Java, Kotlin, C#, Go) are a big chunk of the pie. Sure it also comes down to taste, but if you work in a large team, having stronger types can greatly help to keep the codebase in shape. (better IDE…

Typescript is still nowhere near as popular as Javascript, and likely never will be. It's overkill for the vast number of uses of Javascript.

Re: The tragedy of running an old Node project

#388
post #380

Earlier quoted context omitted.

JS is popular due to it being the only browser lang. Did you forget that? Also: TS popularity shows that not everyone in the JS community agree with you. For server side web dev you will find that statically typed langs (Java, Kotlin, C#, Go) are a big chunk of the pie. Sure it also comes down to taste, but if you work in a large team, having stronger types can greatly help to keep the codebase in shape. (better IDE…

Typescript is still nowhere near as popular as Javascript, and likely never will be. It's overkill for the vast number of uses of Javascript.

JS's uses have been growing steadily. The language was clearly not "designed" (I saw a talk about the first 10d of JS, little actual designing happened).

TS is to the rescue when you have a big JS project, because that's what JS is not good at: big projects and large teams.

Re: The tragedy of running an old Node project

#389
post #277
post #149

Earlier quoted context omitted.

The only problems I've run into are related to certain package repos that went offline. So you have to track down suitable versions of certain packages on other repos. OTOH with Node I always find myself in dependency hell with dealing with old projects.

In my experience this only happen if the project does not have a lock file and does not specify a node version (two good practice that must be followed).

I'm talking about upgrading dependencies. Something that's rarely easy in a JS/TS project with lots of dependencies.

Re: The tragedy of running an old Node project

#390
post #386
post #383

Earlier quoted context omitted.

Given the javascript is still inside a tag I would presume any editor that can handle a normal HTML page with some inline javascript wouldn't notice the difference i agree. it's been a while that i looked at vuejs, and i don't know why i came away with a different impression before. must have not looked closely enough. i haven't seen mobx before, but when i read the description i wonder why i need it. my preferred fr…

When I start with "plain" vim the first thing I do is drop in https://trout.me.uk/X11/vimrc to nerf it back to as close to ex-vi as I can get - because my muscle memory comes from classic vis (between the mostly-BSDi job and the mostly-Solaris job I did devbox sysadmin for a software house, so I got to handle Solaris, AIX, IRIX, Tru64, SCO OpenSewer, and a couple others all at the same time ;) my experience of ex-vi…

i get you on vi. i was there (3000 years ago ;-), although only at the tail end of it in the early 90s. i switched from emacs to vi because of my sysadmin job.

i am really curious what you make of aurelia once you take it apart. please ping me if it is not to much trouble. i discovered aurelia when angularjs 1 was being redeveloped into angular 2. rob eisenberg was invited to the angular team based on his work on durandal but when his ideas were not accepted he left again and built aurelia instead. aurelia is not perfect either, but it was way better than angular 2 or vue at the time.

on your mobx example, you are right, aurelia doesn't track everything. it may be able to handle some level of complexity but i certainly had situations where i had to explicitly send a signal to get aurelia to update values.

Post reply on HN