Download npmDeps in buildRustPackage

Hello!

I have a multi-language project that builds correctly using nix. I want to simplify the following code - the first target only exists to download the npm deps that are used by the later rust part - is there any way to combine those two?

Thanks!

          npm-deps = pkgs.buildNpmPackage {
            # used only to create the node_modules folder
            name = "npm-deps";
            src = ./.;

            npmDeps = pkgs.importNpmLock {
              npmRoot = ./.;
            };

            npmConfigHook = pkgs.importNpmLock.npmConfigHook;

            buildPhase = ":";

            installPhase = ''
              mkdir -p $out
              cp -r node_modules $out
            '';

            fixupPhase = ":";
            checkPhase = ":";
          };

          backend = pkgs.rustPlatform.buildRustPackage {
            name = "backend";
            src = ./.;

            cargoLock = {
              lockFile = ./Cargo.lock;
            };

            nativeBuildInputs = global-packages;
            HOME = "./home";

            buildPhase = ''
              mkdir -p ${backend.HOME}            
              cp -r ${npm-deps}/node_modules .
              chmod -R 777 node_modules # to prevent Error: EACCES: permission denied, mkdir '/build/s4bnqnz1prnhv383fpn2hqm29m7ifn3g-source/node_modules/react-native-css-interop/.cache'
              make rootfs
            '';

            checkPhase = "make test";

            installPhase = ''
              mkdir -p $out
              cp -r output/rootfs/* $out
              chmod +x $out/bin/* #  TODO remove this hack
            '';
          };

I had to do something similar recently.

  npmDeps = buildNpmPackage {
    inherit pname version src;

    npmDepsHash = "sha256-3+XXPUhCKAKBDHVMwruyNlFqVlBVjSLYCWXHqWdo3UM=";

    makeCacheWritable = true;

    installPhase = ''
      mkdir -p $out
      cp -r node_modules -t $out
    '';
  };

You could try importNpmLock.buildNodeModules which seems to be designed for your use case (with src = ./.)? (I couldn’t get it to work when the npmRoot was given by a src derivation, but maybe I’m missing something.)

Some nits: likely npmDeps and npmConfigHook don’t need to be explicitly specified, just a hash npmDepsHash (as above). You can skip the build phase with dontNpmBuild (or dontBuild) and the fixup phase with dontFixup. The check phase is skipped with doCheck = false (the inverse of the other two).

1 Like

It should be enough to add npmConfigHook to nativeBuildInputs.

2 Likes

you can use fetchNpmDeps(Nixpkgs Reference Manual) plus npmHooks.npmConfigHook to automatically install the node_modules directory. see nixpkgs/pkgs/servers/isso/default.nix at 03750d6c8c5fa08472700d24441bede21e5776ab · NixOS/nixpkgs · GitHub for an example(line 26 with fetchNpmDeps, then add npmHooks.npmConfigHooks to the nativeBuildInputs)

you should do both inside the backend function you have

2 Likes