Skip to content

Instantly share code, notes, and snippets.

@Miragium-code
Last active June 8, 2025 02:00
Show Gist options
  • Save Miragium-code/520bd9e01748dda65c3a0723e88eda1d to your computer and use it in GitHub Desktop.
Save Miragium-code/520bd9e01748dda65c3a0723e88eda1d to your computer and use it in GitHub Desktop.

my claim to guest271314

The task

  • create a website / web API depending directly on no more than 10 packages, but depending indirectly on more than 50 packages.
  • run the project, host it online or make sure it work at least locally. This will be version A.
  • Latter, change something in the code, and deploy the project again and keep all of the dependencies at the same versions as before. Deploy this new version. This will be version B.
  • Latter again, upgrade one indirect dependencies without changing the versions of your direct dependencies. Deploy this new version. This will be version C.
  • Then upgrade one or several direct dependency. Deploy this new version. This will be version D.
  • Finally, roll back all those changes and go back to version A, and deploy this version with exactly the packages it used at the time.

Protocol

  • Once you have completed the task, you will deliver the project in a way that will allow me to access version A, B, C and D. A git repository is prefered, but any other medium is allowed as long as I can access all versions.
  • You will provide instructions as to how the project is meant to be setup, either as documentation or support.
  • Once I have access to all versions of the project I will verify the following :
    • I am able to install all the dependencies at the exact versions you used
    • I am able to create a new version of the project whith the desired versions of the dependencies
    • I am able to manage dependencies as I do on any other project. This means I have access to commands (or procedures I can do entierly in the terminal) to :
      • list all the direct dependencies on the project
      • list all dependencies on the project, direct and indirect
      • add a new dependency and install it, along with all its indirect dependencies
      • change the version of a dependency
      • re-install all dependencies to their target version in the project
      • upgrade all dependencies to their latest version

Restrictions

  • You may use any registry for you dependencies, as long as it is publicly accessible on the web.
  • You may use any Javascript runtime that is publicly accessible.
  • As is good practice, you cannot include the dependencies in the render of the project you will send me (this could break if the project was deployed on a different OS or architecture). Instead, I will reinstall them when I deploy the project.

The Claim

You will not be able to do this by downloading the packages directly, even with an import map. You are gonna need a tool to remember the versions of all the 100+ packages, either an existing tool (like a package manager) or something you have to write yourself.

{
"name": "test",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "",
"type": "commonjs",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"bcrypt": "^6.0.0",
"ejs": "^3.1.10",
"koa": "^3.0.0",
"koa-body": "^6.0.1",
"koa-router": "^13.0.1",
"pg": "^8.16.0"
}
}
@guest271314
Copy link

And why the packages are dependencies. The point being folks tart out with grossly over-engineered Web siters for no reason in the first place. So, if you say you depend on 10 packages, you're gonna have to say what they're for and what they are.

@guest271314
Copy link

I step out for a while, then get banned from the Node.js discord.com server. Too funny. What a joke.

@iskandar7ss
Copy link

.

@guest271314
Copy link

The simple answer is

  1. Write entry point script.
  2. Bundle all dependencies to a single script, or multiple scripts if you prefer, once.
  3. Modify entry point script when required.

@Miragium-code
Copy link
Author

Alright, as discussed, I rewrote some parts to relax some unnecessary constraints, while clarifying what I expect and what I will test.

I also provided an example of dependencies you could use that I think are quite reasonable for a small project. Those 6 dependencies bring with them 101 other dependencies.

Here is the reasoning for each dependency

  • I am building a website, but building a lot of routes without a framework is messy, so I use koa and koa-router to organize all the route, and all the code they have in common into middleware
  • I need to parse formData, so I use koa-body.
  • I want to generate some dinamyc html content, so I use ejs
  • I have a database I need to connect to, so I use pg
  • I need to store user's password safely, so I use bcrypt

Because this exercise focuses on the management of dependencies, I don't really care how they are actually used in the code, or if they are used at all. They just need to be there, at a fixed version that I can redeploy once you deliver the project.

@guest271314
Copy link

@Miragium-code So this is Node.js-specific, correct? bcrypt depends on node-gyp-build, and a stable/release version of node?

@guest271314
Copy link

Save for the database, and perhaps even that, I think the requirement can be achieved using node builtins alone, without any dependencies.

@guest271314
Copy link

Fetching dependencies from the network directly using Deno

import * as bcrypt from "npm:[email protected]"
import * as ejs from "https://esm.sh/[email protected]";
import * as koa from "https://esm.sh/[email protected]";
import * as koaBody from "https://esm.sh/[email protected]";
import * as koaRouter from "https://esm.sh/[email protected]";
import pg from "npm:[email protected]";
// Do stuff
export { bcrypt, ejs, koa, koaBody, koaRouter, pg };

Bundling all dependencies in a single script

bun build --target=node --packages=bundle --outfile=bundle.js index.js

Run the bundle with Deno

$ deno repl -A --unstable-node-globals
Deno 2.3.5+7a837f9
exit using ctrl+d, ctrl+c, or close()
> import * as mod from "./bundle.js";
undefined
> console.log(mod);
...
    },
    DatabaseError: [class DatabaseError extends Error],
    TypeOverrides: [Function: TypeOverrides],
    escapeIdentifier: [Function: escapeIdentifier],
    escapeLiteral: [Function: escapeLiteral],
    Result: [class Result],
    utils: {
      prepareValue: [Function: prepareValueWrapper],
      normalizeQueryConfig: [Function: normalizeQueryConfig],
      escapeIdentifier: [Function: escapeIdentifier],
      escapeLiteral: [Function: escapeLiteral]
    }
  }
}

Run the bundle with Bun

$ bun repl
Welcome to Bun v1.2.16
Type ".help" for more information.
[!] Please note that the REPL implementation is still experimental!
    Don't consider it to be representative of the stability or behavior of Bun overall.
> import * as mod from "./bundle.js"
undefined
> console.log(mod);
...
    },
    DatabaseError: [class DatabaseError extends Error],
    TypeOverrides: [Function: TypeOverrides],
    escapeIdentifier: [Function: escapeIdentifier],
    escapeLiteral: [Function: escapeLiteral],
    Result: [class Result],
    utils: {
      prepareValue: [Function: prepareValueWrapper],
      normalizeQueryConfig: [Function: normalizeQueryConfig],
      escapeIdentifier: [Function: escapeIdentifier],
      escapeLiteral: [Function: escapeLiteral]
    }
  }
}

Node.js doesn't support static ECMAScript Modules in REPL mode. Node.js parses ECMAScript Module as CommonJS when there's no top-level static import in the file, and doesn't re-parse as ECMAScript Module after code analyzation. And because of that package.json file, that is not necessary when using network imports with Deno.

node ./bundle.js
(node:38713) Warning: Failed to load the ES module: /home/user/bin/bundle/bundle.js. Make sure to set "type": "module" in the nearest package.json file or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/home/user/bin/bundle/bundle.js:1
import { createRequire } from "node:module";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1665:18)
    at Module._compile (node:internal/modules/cjs/loader:1707:20)
    at Object..js (node:internal/modules/cjs/loader:1898:10)
    at Module.load (node:internal/modules/cjs/loader:1468:32)
    at Module._load (node:internal/modules/cjs/loader:1285:12)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:152:5)
    at node:internal/main/run_main_module:33:47

Node.js v25.0.0-nightly202506070c6e16bc84

Least amount of changes to get node to parse the ECMAScript Module as an ECMAScript Module... Rename package.json?

deno repl -A
Deno 2.3.5+7a837f9
exit using ctrl+d, ctrl+c, or close()
> await Deno.rename("package.json", "_package.json")

Now node will parse the ECMAScript Module as an ECMAScript Module

node -e "import * as mod from './bundle.js'; console.log(mod)"
...
    DatabaseError: [class DatabaseError extends Error],
    TypeOverrides: [Function: TypeOverrides],
    escapeIdentifier: [Function: escapeIdentifier],
    escapeLiteral: [Function: escapeLiteral],
    Result: [class Result],
    utils: {
      prepareValue: [Function: prepareValueWrapper],
      normalizeQueryConfig: [Function: normalizeQueryConfig],
      escapeIdentifier: [Function: escapeIdentifier],
      escapeLiteral: [Function: escapeLiteral]
    }
  }
}

Alright, we've got Version A. of the requirement. Get rid of what we don't need. The script with all bundled dependencies is in bundle.js

deno clean
bun pm cache rm
rm -rf node_modules

bundle.js https://gist.github.com/guest271314/d83e3770e24c3b497561e0d9a767fa13

@guest271314
Copy link

Detail: I changed index.js to this for bun build, because Bun doesn't support network imports, either.

import * as bcrypt from "bcrypt";
import * as ejs from "ejs";
import * as koa from "koa";
import * as koaBody from "koa-body";
import * as koaRouter from "koa-router";
import pg from "pg";

export { bcrypt, ejs, koa, koaBody, koaRouter, pg };

Using Deno and direct network imports avoids reliance on package.json and node_modules directory creation.

@guest271314
Copy link

Looks like bcrypt depends on .node file. So at least that file in node_modules need to be kept around outside of bundle.js.

Another detail. This is what I use with Deno to support the bare Node.js globals (global, specifically) with the original index.js file, which also fetches dependencies from NPM, when necessary, and creates the node_modules folder node and bun expect

deno -A --allow-scripts --node-modules-dir=auto index.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment