Replace npm deps with nix deps

For some reasons (see motivation here) I need to use nix’s version of a node package instead of the one written in package.json. How can I tell nix to use all deps from package.json except one that should come from nix? (for now I use npmHooks.npmConfigHook + fetchNpmDeps but I’m happy to use anything that works)

1 Like

You could try to npm uninstall $PACKAGE the package(s) to override then npm link $PATH/TO/NIX-STORE during the installPhase
As you noted in your other post, patching is only a temporary fix for the current branch and not so reliable for the long term (need to keep an eye on changes on each releases)

Personal opinion here, but I would tend to avoid “nixifying” npm (same for e.g docker) stuff

  • more time to get it setup
  • time to maintain
  • npm already is a declarative way to setup dependencies
  • if working in a team, you can’t always force other members to use nix
    Would be relevant for hosts if you deploy smth there but still an overkill IMHO

Thanks, but I tried:

   postInstall = ''
     echo "-->> ls"
     ls node_modules
     echo "-->> uninstall playwright"
     npm uninstall playwright
     echo "-->> ls"
     ls node_modules
     pushd ${playwright-driver}
     echo "-->> link"
     npm link
     popd
     echo "-->> install"
     npm link playwright
     echo "-->> ls"
     ls node_modules
     cp -r node_modules $out/lib
   '';

but it fails with

npm warn Unknown env config "nodedir". This will stop working in the next major version of npm.
npm error code EACCES
npm error syscall symlink
npm error path ../../../qhm5mhzyqdk54k9yyjk1wl16y80gwkc0-playwright-core-1.52.0
npm error dest /nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/playwright-core
npm error errno -13
npm error Error: EACCES: permission denied, symlink '../../../qhm5mhzyqdk54k9yyjk1wl16y80gwkc0-playwright-core-1.52.0' -> '/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/playwright-core'
npm error     at async symlink (node:internal/fs/promises:1007:10)
npm error     at async /nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:729:7
npm error     at async Promise.allSettled (index 0)
npm error     at async [reifyPackages] (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:336:11)
npm error     at async Arborist.reify (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:141:5)
npm error     at async Link.linkPkg (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/lib/commands/link.js:147:5)
npm error     at async Npm.exec (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/lib/npm.js:208:9)
npm error     at async module.exports (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/lib/cli/entry.js:67:5) {
npm error   errno: -13,
npm error   code: 'EACCES',
npm error   syscall: 'symlink',
npm error   path: '../../../qhm5mhzyqdk54k9yyjk1wl16y80gwkc0-playwright-core-1.52.0',
npm error   dest: '/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/playwright-core'
npm error }
npm error
npm error The operation was rejected by your operating system.
npm error It is likely you do not have the permissions to access this file as the current user
npm error
npm error If you believe this might be a permissions issue, please double-check the
npm error permissions of the file and its containing directories, or try running
npm error the command again as root/Administrator.
npm error Log files were not written due to an error writing to the directory: /nix/store/zfjz0bvr7s2blggz7y4izndavsp4wg2f-npm-deps/_logs
npm error You can rerun the command with `--loglevel=verbose` to see the logs in your terminal

I also tried npm install ${playwright-driver} but I get:

       > npm error Error: EPERM: operation not permitted, chmod '/build/source/node_modules/playwright-core/cli.js'
       > npm error     at async chmod (node:internal/fs/promises:1085:10)
       > npm error     at async Promise.all (index 0)
       > npm error     at async Promise.all (index 0)
       > npm error     at async #createBinLinks (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js:396:5)
       > npm error     at async Promise.allSettled (index 0)
       > npm error     at async #linkAllBins (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js:377:5)
       > npm error     at async #build (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js:162:7)
       > npm error     at async Arborist.rebuild (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js:67:7)
       > npm error     at async [reifyPackages] (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:336:11)
       > npm error     at async Arborist.reify (/nix/store/azpqgrv58akzqkj8fq8kb5dyc2jjk7zk-nodejs-24.2.0/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:141:5) {
       > npm error   errno: -1,
       > npm error   code: 'EPERM',
       > npm error   syscall: 'chmod',
       > npm error   path: '/build/source/node_modules/playwright-core/cli.js'
       > npm error }
       > npm error

Now, I just ended up with:

  postInstall = ''
    rm -rf node_modules/playwright
    ln -s ${playwright-driver} node_modules/playwright
    cp -r node_modules $out/lib
  …

and it seems to work… is it really the recommended approach?? Or have I done something silly with npm link?

  postInstall = ''
    rm -rf node_modules/playwright
    ln -s ${playwright-driver} node_modules/playwright
    cp -r node_modules $out/lib
  …

That kinda does same as what npm link does

Only difference is that package is not referenced in package.json / package-lock.json.
If running npm update, it might get overridden though

Errors you get from npm link are permission related, check this maybe (or just check on github or other stackoverflow for these error messages): "npm link" results in "permission denied" · Issue #35 · rustwasm/wasm_game_of_life · GitHub

Might also be due to how nix manages nix-store