Install node_modules from package.json + package-lock.json
package.json
and package-lock.json
. this is handled by the lockTree function from npm/logical-tree. the original npm
would deduplicate "transitive" dependencies and build a flat node_modules, but here we build a deep node_modules with symlinks to a local store in node_modues/.pnpm/
.node_modues/.pnpm/
. the *.tar.gz
files are provided by npmlock2nix
. to unpack, we call tar xf package.tar.gz
node_modules/(name)
to node_modues/.pnpm/(name)@(version)/node_modules/(name)
node_modues/.pnpm/(name)@(version)/node_modules/(name)
to node_modues/.pnpm/(parentName)@(parentVersion)/node_modules/(name)
preinstall
install
postinstall
. process the dependencies in depth-first order (last-level dependencies first, first-level dependencies last), so that child-dependencies are available.prepare
or prepublish
script, also install its devDependencies
(TODO verify)preinstall
install
postinstall
prepublish
preprepare
prepare
postprepare
. docs: lifecycle scripts (look for npm install
)npm ci
or "npm clean install" will
todo
this program should produce the same result as pnpm install
,
so testing can be as simple as
package.json
and package-lock.json
files.
these files must be valid, since this program will do no validationnode_modules
to node_modules-actual
pnpm import
(to produce a pnpm-lock.yaml
file) and run pnpm install
,
move node_modules
to node_modules-expected
diff -r node_modules-actual node_modules-expected
the only difference should be pnpm-internal files,
like node_modules/.pnpm/lock.yaml
(the current lockfile of pnpm)
this program should produce the same result as
pnpm install
except for obvious bugs in pnpm, like pnpm does not install peerDependencies like npm v7.
in this case, npm
(the original nodejs package manager) defines the expected behavior
update: pnpm
has now implemented
the option auto-install-peers
pnpm config set auto-install-peers true
but this is NOT satisfying,
because it has NO effect on pnpm install
.
it only has an effect on pnpm add some-package
so currently, pnpm
can NOT be used as a drop-in replacement for npmv7
(and thanks to the insane complexity of pnpm, its hard to add this feature)
workaround: add a pnpm hook
https://github.com/pnpm/pnpm/discussions/3995#discussioncomment-1647425
// .pnpmfile.cjs
function readPackage(pkg) {
pkg.dependencies = {
...pkg.peerDependencies,
...pkg.dependencies,
}
pkg.peerDependencies = {};
return pkg;
}
module.exports = {
hooks: {
readPackage,
},
};
https://github.com/canva-public/js2nix
The `nodeModules` is a Nix derivation that contains a compatible with [Node.js module resolution algorithm](https://nodejs.org/api/modules.html#all-together) layout. Note that the layout of the resulting `node_modules` is similar to what [`PNPM`](https://pnpm.io) package manager is providing, that is not a [flat](https://npm.github.io/how-npm-works-docs/npm3/how-npm3-works.html) layout but rather the canonical layout with symlinked (from the Nix store) npm packages into it. To find out more about the project, its background, implementation details, how to use it please go to the [documentation space](https://github.com/canva-public/js2nix/blob/main/docs/README.md).