I've been testing and experimenting over the past week or so with installing Node.js-specific packages - without using npm
because somebody claimed Can this be used to create/download npm as a standalone executable? #3237
npm can’t be eliminated from the equation when you’re dealing with JavaScript ¯_(ツ)_/¯
Well, let's see about that...
First I had to get all of the dependencies from package.json
and/or package-lock.json
file. Turns out different packages can depend on different versions of the same named module. Ever hear about "callback hell"? Well, Node.js module dependency system can be dependency hell.
Fortunately for me, due to personal reasons I am evil now (TM) (Rebel Circus). So I fit right in in hell, hell I thrive in chaos.
I tried jsDelivr and UNPKG Ecmascript Module versions of the core dependencies I needed to build a program using a GitHub repository that uses CommonJS exclusively. Unfortunately, Rollup throws errors for read
module SyntaxError: The requested module 'https://cdn.jsdelivr.net/npm/read@2.1.0/+esm' does not provide an export named 'default'.
package.json
and package-lock.json
are not the same animal.
https://www.reddit.com/r/node/comments/184hkw1/comment/kaxn88r/:
Because 1) Throwing away a package-lock.json and re-resolving/-installing everything can give a different result, and 2) package-lock.json stores the hoisted node_modules tree, not just resolved packages.
Take ajv as an example.
The package-lock.json contains 5 versions of it (6.12.6, 8.8.2, 8.10.0, 8.11.0, 8.11.2) but resolving again from the package.json now will give you 2 versions (6.12.6, 8.12.0), which is what npmgraph.js.org counts.
Also, your code actually counts ajv 6 times
ajv ajv-formats/node_modules/ajv copy-webpack-plugin/node_modules/ajv mini-css-extract-plugin/node_modules/ajv webpack-dev-middleware/node_modules/ajv webpack-dev-server/node_modules/ajv Because ajv-formats/node_modules/ajv and webpack-dev-server/node_modules/ajv are the exact same package (ajv@8.8.2) that appears twice in the filesystem. In the general case, it is not possible to perfectly dedupe packages in a node_modules tree.
I'm curious what you get using npm and/or yarn
For yarn v4 I got 542 packages. One of the reasons is that it treats node-gyp as an explicit dependency while npm treats it as implicit.
Didn't test with npm but they should match the two numbers you got depending on whether you use the lockfile or not
(Emphasis added)
And 496 Modules in
Sure. Package lock files are basically a snapshot of a given-project's dependency tree. The exact content of a package.json file is a product of the order and timing in which modules are installed for any given project.
While lock files and package.json files are similar in some ways, they're different enough that supporting them is non-trivial. See also #148
I think I got more than enough of the dependencies with this, iterating package-lock.json
.
let nodePackageDependencies = [
...new Set(
Object.entries(
(await (await fetch(
"./package-lock.json",
)).json()).packages,
).map((
[key, { dependencies = {}, devDependencies = {} }],
) => [
key.replace(/^node_modules\//, ""),
...Object.keys(dependencies),
...Object.keys(devDependencies),
]).flat().filter(Boolean),
),
];
Wait a minute... I've got bun
right there next to deno
and node
in ~/bin
. Let's see what bun
has to say about this controversy...
install Install dependencies for a package.json (bun i)
Alright... I don't have npm
installed. So Bun folks must have figured something out about how to fetch Node.js packages.
Here you go (npm
is not deliberately installed on my machine. If bun
uses npm
it's under the hood)
$ bun install
Installs packages listed in package.json to ~/.bun/install/cache
. Initially complained about the package-lock.json
file not being veriosn 3, so I removed the package-lock.json
file from the directory and proceeded testing.
$ bun install
bun install v1.0.14 (d8be3e51)
error: Please upgrade package-lock.json to lockfileVersion 3
Run 'npm i --lockfile-version 3 --frozen-lockfile' to upgrade your lockfile without changing dependencies.
user@user:~/telnet-client-web-ext$ bun install
bun install v1.0.14 (d8be3e51)
+ @typescript-eslint/eslint-plugin@5.62.0 (v6.13.0 available)
+ @typescript-eslint/parser@5.62.0 (v6.13.0 available)
+ clean-webpack-plugin@4.0.0
+ copy-webpack-plugin@11.0.0
+ css-loader@6.8.1
+ dotenv@16.3.1
+ eslint@8.54.0
+ eslint-config-google@0.14.0
+ gh-pages@4.0.0 (v6.1.0 available)
+ html-loader@3.1.2 (v4.2.0 available)
+ html-webpack-plugin@5.5.3
+ mini-css-extract-plugin@2.7.6
+ style-loader@3.3.3
+ ts-loader@9.5.1
+ typescript@4.9.5 (v5.3.2 available)
+ wbn-sign@0.1.0 (v0.1.2 available)
+ webbundle-webpack-plugin@0.1.3
+ webpack@5.89.0
+ webpack-cli@4.10.0 (v5.1.4 available)
+ webpack-dev-server@4.15.1
+ webpack-merge@5.10.0
+ xterm@4.19.0 (v5.3.0 available)
+ xterm-addon-fit@0.5.0 (v0.8.0 available)
494 packages installed [5.67s]
user@user:~/telnet-client-web-ext$ bun run build
$ webpack --config webpack.wbn.js
Setting the empty headerOverrides to IWA defaults. To bundle a non-IWA, set `integrityBlockSign { isIwa: false }` in your plugin configs. Defaults are set to:
{"content-security-policy":"base-uri 'none'; default-src 'self'; object-src 'none'; frame-src 'self' https: blob: data:; connect-src 'self' https:; script-src 'self' 'wasm-unsafe-eval'; img-src 'self' https: blob: data:; media-src 'self' https: blob: data:; font-src 'self' blob: data:; require-trusted-types-for 'script'; frame-ancestors 'self';","cross-origin-embedder-policy":"require-corp","cross-origin-opener-policy":"same-origin","cross-origin-resource-policy":"same-origin"}
assets by path *.js 4.34 KiB
asset main.js 3.05 KiB [emitted] [minimized] (name: main)
asset runtime.js 910 bytes [emitted] [minimized] (name: runtime)
asset sw.js 361 bytes [emitted] [from: assets/sw.js] [copied] [minimized]
asset worker.js 50 bytes [emitted] [from: assets/worker.js] [copied] [minimized]
assets by path images/ 21.2 KiB
asset images/icons-512.png 14.2 KiB [emitted] [from: assets/images/icons-512.png] [copied]
asset images/icons-192.png 5.14 KiB [emitted] [from: assets/images/icons-192.png] [copied]
asset images/icons-vector.svg 1.89 KiB [emitted] [from: assets/images/icons-vector.svg] [copied]
asset telnet.swbn 32.6 KiB [emitted]
asset manifest.webmanifest 721 bytes [emitted] [from: assets/manifest.webmanifest] [copied]
asset index.html 253 bytes [emitted]
Entrypoint main 3.94 KiB = runtime.js 910 bytes main.js 3.05 KiB
runtime modules 2.48 KiB 3 modules
./src/index.js 4.74 KiB [built] [code generated]
LOG from webbundle-webpack-plugin
<i> isolated-app://<ID>/
webpack 5.89.0 compiled successfully in 1500 ms
user@user:~/telnet-client-web-ext$ npm --help
Command 'npm' not found, but can be installed with:
sudo apt install npm
So, we can rack that spurious claim up as false.
Have a great day!