Hacker News new | ask | show | jobs
by vhiremath4 1206 days ago
The decoupling of URLs that host your dependencies and the URLs that host your application feels like an important uptime measure currently. If the URLs that host your dependencies go down in an NPM world, you can't build and deploy new code but your app is still up. It seems, if the URLs that host your dependencies go down in a Deno world, your app goes down if those dependencies have not yet been cached (even on the server).

Am I missing something? This might not be terrible if it becomes the standard to host your own mirror internally.

7 comments

Dependencies in package.json are essentially just links to the npm CDN. (admittedly with a constraint solver in front that determines the exact link to use).

`npm install` is equivalent to `https://deno.land/manual@v1.31.1/tools/vendor` in that they both fetch your dependencies and store them locally, so your app can run without downloading the deps.

The just-in-time builds section of the linked article describes an approach where you dynamically bundle, at request time. If your server already has all the deps vendored then it won't need to fetch them at runtime and your app will stay up even if the URLs go down.

Deno caches your dependencies locally.

If you are building something that demands high availability you probably want to host the dependencies yourself though. Which is easy, you just copy them and serve them as static files (assuming their license allows that use).

Dope this answers my question. Honestly as I've become a more seasoned developer, I've increasingly come to appreciate the utility of mirrors for build systems too.

It's not always simple in every module system though. Currently, I want to figure out how to create a mirror for our Electron codebase, but it's tough because some of the modules fetch gyp native headers that live in other locations (including the Electron core packages themselves) and NPM doesn't always know what to do. The Electron core header URLs flake every 2-3 weeks or so and inevitably we lose a lot of engineering time.

Hoping Deno continues to gain steam and makes this simpler since everything is URLs all the way down.

There's a command line option to use a local (project) directory for said cache, and you can commit into your code repo... so no package down time to worry about.

Though, hard to beat live ref to a githubusercontent url.

On Android we do the same with help of Gradle. It retrieves library from a remote source and caches it. If there is no cache, next time your Gradle tries to build, it will download the library from a remote source. If remote host fails, you can not build your app. One of popular host providers had issues couple of times in last year, and it wasn't nice. https://github.com/jitpack/jitpack.io/issues?q=is%3Aissue+so...
Deno should have like a mirrors.manifest.js file that stores your dependency links, and mirrors, should one source go down... that way it wouldn't be such a problem, the only big issue might be ensuring the sources don't have a rogue link or two from bad actors, where they do something nefarious like build a useful package then swap it out for a bad version later on, and put only on a mirror so when things go south it triggers, of course there could be bots/queues that periodically take md5s of the code, or just whenever version changes occur, so that would stop that.
This exists and is part of the deno executable; see [1] for more info.

1. https://deno.land/manual@v1.31.1/tools/vendor

Deno puts a hash of the dependency contents in a lock file so it can ensure the contents of a dependency haven't been changed unexpectedly: https://deno.land/manual@v1.29.2/basics/modules/integrity_ch...
I think the benefits of leaning on a (very familiar) protocol instead of a central repository outweigh the risks you describe

Like you mentioned- mirrors could become more common, and relying on HTTP makes it incredibly easy to host your own mirror. And import-maps mean you can mirror anything and everything in your dependency tree

Let's not forget, back in the day every major site relied on a client-side request to a jQuery CDN :)

I think so yes, but then some people are talking about cache which means it's not really JIT... And then even with cache it's blackboxed, you are not sure it's good or that the cache will not be discarded. #OncallNightmare
You can cache all dependencies in one go whenever you want. It doesn't have to be done in real time when the code is run.