Merge pull request #258384 from doronbehar/buildNpmPackage-makeWrapperArgs

buildNpmPackage: support makeWrapperArgs

authored by Doron Behar and committed by GitHub d090cd9a b8446541

+26 -2
+15 -1
doc/languages-frameworks/javascript.section.md
··· 161 162 `buildNpmPackage` allows you to package npm-based projects in Nixpkgs without the use of an auto-generated dependencies file (as used in [node2nix](#javascript-node2nix)). It works by utilizing npm's cache functionality -- creating a reproducible cache that contains the dependencies of a project, and pointing npm to it. 163 164 ```nix 165 { lib, buildNpmPackage, fetchFromGitHub }: 166 ··· 190 }; 191 } 192 ``` 193 194 #### Arguments {#javascript-buildNpmPackage-arguments} 195 ··· 204 * `npmBuildFlags`: Flags to pass to `npm run ${npmBuildScript}`. 205 * `npmPackFlags`: Flags to pass to `npm pack`. 206 * `npmPruneFlags`: Flags to pass to `npm prune`. Defaults to the value of `npmInstallFlags`. 207 208 #### prefetch-npm-deps {#javascript-buildNpmPackage-prefetch-npm-deps} 209 210 - `prefetch-npm-deps` can calculate the hash of the dependencies of an npm project ahead of time. 211 212 ```console 213 $ ls ··· 216 ... 217 sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 218 ``` 219 220 ### corepack {#javascript-corepack} 221
··· 161 162 `buildNpmPackage` allows you to package npm-based projects in Nixpkgs without the use of an auto-generated dependencies file (as used in [node2nix](#javascript-node2nix)). It works by utilizing npm's cache functionality -- creating a reproducible cache that contains the dependencies of a project, and pointing npm to it. 163 164 + Here's an example: 165 + 166 ```nix 167 { lib, buildNpmPackage, fetchFromGitHub }: 168 ··· 192 }; 193 } 194 ``` 195 + 196 + In the default `installPhase` set by `buildNpmPackage`, it uses `npm pack --json --dry-run` to decide what files to install in `$out/lib/node_modules/$name/`, where `$name` is the `name` string defined in the package's `package.json`. Additionally, the `bin` and `man` keys in the source's `package.json` are used to decide what binaries and manpages are supposed to be installed. If these are not defined, `npm pack` may miss some files, and no binaries will be produced. 197 198 #### Arguments {#javascript-buildNpmPackage-arguments} 199 ··· 208 * `npmBuildFlags`: Flags to pass to `npm run ${npmBuildScript}`. 209 * `npmPackFlags`: Flags to pass to `npm pack`. 210 * `npmPruneFlags`: Flags to pass to `npm prune`. Defaults to the value of `npmInstallFlags`. 211 + * `makeWrapperArgs`: Flags to pass to `makeWrapper`, added to executable calling the generated `.js` with `node` as an interpreter. These scripts are defined in `package.json`. 212 213 #### prefetch-npm-deps {#javascript-buildNpmPackage-prefetch-npm-deps} 214 215 + `prefetch-npm-deps` is a Nixpkgs package that calculates the hash of the dependencies of an npm project ahead of time. 216 217 ```console 218 $ ls ··· 221 ... 222 sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 223 ``` 224 + 225 + #### fetchNpmDeps {#javascript-buildNpmPackage-fetchNpmDeps} 226 + 227 + `fetchNpmDeps` is a Nix function that requires the following mandatory arguments: 228 + 229 + - `src`: A directory / tarball with `package-lock.json` file 230 + - `hash`: The output hash of the node dependencies defined in `package-lock.json`. 231 + 232 + It returns a derivation with all `package-lock.json` dependencies downloaded into `$out/`, usable as an npm cache. 233 234 ### corepack {#javascript-corepack} 235
+11 -1
pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh
··· 16 cp "${npmWorkspace-.}/$file" "$dest" 17 done < <(@jq@ --raw-output '.[0].files | map(.path) | join("\n")' <<< "$(npm pack --json --dry-run ${npmWorkspace+--workspace=$npmWorkspace} $npmPackFlags "${npmPackFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}")") 18 19 while IFS=" " read -ra bin; do 20 mkdir -p "$out/bin" 21 - makeWrapper @hostNode@ "$out/bin/${bin[0]}" --add-flags "$packageOut/${bin[1]}" 22 done < <(@jq@ --raw-output '(.bin | type) as $typ | if $typ == "string" then 23 .name + " " + .bin 24 elif $typ == "object" then .bin | to_entries | map(.key + " " + .value) | join("\n")
··· 16 cp "${npmWorkspace-.}/$file" "$dest" 17 done < <(@jq@ --raw-output '.[0].files | map(.path) | join("\n")' <<< "$(npm pack --json --dry-run ${npmWorkspace+--workspace=$npmWorkspace} $npmPackFlags "${npmPackFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}")") 18 19 + # Based on code from Python's buildPythonPackage wrap.sh script, for 20 + # supporting both the case when makeWrapperArgs is an array and a 21 + # IFS-separated string. 22 + # 23 + # TODO: remove the string branch when __structuredAttrs are used. 24 + if [[ "${makeWrapperArgs+defined}" == "defined" && "$(declare -p makeWrapperArgs)" =~ ^'declare -a makeWrapperArgs=' ]]; then 25 + local -a user_args=("${makeWrapperArgs[@]}") 26 + else 27 + local -a user_args="(${makeWrapperArgs:-})" 28 + fi 29 while IFS=" " read -ra bin; do 30 mkdir -p "$out/bin" 31 + makeWrapper @hostNode@ "$out/bin/${bin[0]}" --add-flags "$packageOut/${bin[1]}" "${user_args[@]}" 32 done < <(@jq@ --raw-output '(.bin | type) as $typ | if $typ == "string" then 33 .name + " " + .bin 34 elif $typ == "object" then .bin | to_entries | map(.key + " " + .value) | join("\n")