{ pkgs', system, ... }: let releaseInfo = import ../config/release.nix; src = ../..; # Read the package-lock.json as a Nix attrset packageLock = builtins.fromJSON (builtins.readFile (src + "/package-lock.json")); # Helper function to safely get attributes getAttr = attr: def: set: if builtins.hasAttr attr set then builtins.getAttr attr set else def; # Create an array of all (meaningful) dependencies deps = builtins.attrValues (removeAttrs packageLock.packages [""]) ++ builtins.attrValues (removeAttrs (getAttr "dependencies" {} packageLock) [""]); # Turn each dependency into a fetchurl call fetchTarball = p: pkgs'.fetchurl { url = p.resolved; hash = p.integrity; }; tarballs = map fetchTarball deps; # Write a file with the list of tarballs tarballsFile = pkgs'.writeTextFile { name = "tarballs"; text = builtins.concatStringsSep "\n" (map (x: x.outPath) tarballs); }; stdenv = pkgs'.stdenv; in stdenv.mkDerivation { inherit src; name = "node-module"; version = releaseInfo.version; buildPhase = '' #!${pkgs'.bash}/bin/bash source ${pkgs'.common}/bin/common mkdir -p $out/ cd $out cp -r $src/package.json . cp -r $src/package-lock.json . export HOME=$PWD/.home export npm_config_cache=$PWD/.npm export npm_config_offline=true total_cores=$(nproc) half_cores=$((total_cores / 2)) echo "Total cores: $total_cores" if [ $half_cores -lt 1 ]; then half_cores=1 fi printf "will cite\n" | parallel --citation nice -n 10 parallel -j $half_cores -a ${tarballsFile} npm cache add "{}" || { echo "Failed to cache some packages" exit 1 } sleep 1 nice -n 10 npm ci --verbose --prefer-offline --no-audit --progress=true --loglevel=error || { echo "Retrying npm ci without cache" sleep 5 nice -n 10 npm ci --verbose --prefer-offline --no-audit --progress=true --loglevel=error || { echo "Failed to install dependencies" exit 1 } } ''; buildInputs = with pkgs'; [projectNodeJS getent strace coreutils bash rsync parallel findutils]; system = system; }