From 384b1e5b91172cd9a031745266779389f6e31e02 Mon Sep 17 00:00:00 2001 From: Doron Behar Date: Mon, 2 Oct 2023 17:07:31 +0300 Subject: [PATCH 1/3] docs/javascript/buildNpmPackage: Document bin, man and npm pack behavior --- doc/languages-frameworks/javascript.section.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/languages-frameworks/javascript.section.md b/doc/languages-frameworks/javascript.section.md index fb1dd898c8a2..861db3679dee 100644 --- a/doc/languages-frameworks/javascript.section.md +++ b/doc/languages-frameworks/javascript.section.md @@ -161,6 +161,8 @@ git config --global url."https://github.com/".insteadOf git://github.com/ `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. +Here's an example: + ```nix { lib, buildNpmPackage, fetchFromGitHub }: @@ -191,6 +193,8 @@ buildNpmPackage rec { } ``` +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. + #### Arguments {#javascript-buildNpmPackage-arguments} * `npmDepsHash`: The output hash of the dependencies for this project. Can be calculated in advance with [`prefetch-npm-deps`](#javascript-buildNpmPackage-prefetch-npm-deps). From d6521ce1868450a6b3fd6840a391cb213d3d9631 Mon Sep 17 00:00:00 2001 From: Doron Behar Date: Mon, 2 Oct 2023 17:08:40 +0300 Subject: [PATCH 2/3] docs/javascript/buildNpmPackage: Document fetchNpmDeps Co-authored-by: Lily Foster --- doc/languages-frameworks/javascript.section.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/languages-frameworks/javascript.section.md b/doc/languages-frameworks/javascript.section.md index 861db3679dee..291629e3a711 100644 --- a/doc/languages-frameworks/javascript.section.md +++ b/doc/languages-frameworks/javascript.section.md @@ -211,7 +211,7 @@ In the default `installPhase` set by `buildNpmPackage`, it uses `npm pack --json #### prefetch-npm-deps {#javascript-buildNpmPackage-prefetch-npm-deps} -`prefetch-npm-deps` can calculate the hash of the dependencies of an npm project ahead of time. +`prefetch-npm-deps` is a Nixpkgs package that calculates the hash of the dependencies of an npm project ahead of time. ```console $ ls @@ -221,6 +221,15 @@ $ prefetch-npm-deps package-lock.json sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= ``` +#### fetchNpmDeps {#javascript-buildNpmPackage-fetchNpmDeps} + +`fetchNpmDeps` is a Nix function that requires the following mandatory arguments: + +- `src`: A directory / tarball with `package-lock.json` file +- `hash`: The output hash of the node dependencies defined in `package-lock.json`. + +It returns a derivation with all `package-lock.json` dependencies downloaded into `$out/`, usable as an npm cache. + ### corepack {#javascript-corepack} This package puts the corepack wrappers for pnpm and yarn in your PATH, and they will honor the `packageManager` setting in the `package.json`. From fc96f6d0fdac6ac8e06af95c6ed416cb7c7d4e2e Mon Sep 17 00:00:00 2001 From: Doron Behar Date: Sun, 1 Oct 2023 13:41:42 +0300 Subject: [PATCH 3/3] buildNpmPackage: support makeWrapperArgs --- doc/languages-frameworks/javascript.section.md | 1 + .../node/build-npm-package/hooks/npm-install-hook.sh | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/languages-frameworks/javascript.section.md b/doc/languages-frameworks/javascript.section.md index 291629e3a711..f35fd83cc594 100644 --- a/doc/languages-frameworks/javascript.section.md +++ b/doc/languages-frameworks/javascript.section.md @@ -208,6 +208,7 @@ In the default `installPhase` set by `buildNpmPackage`, it uses `npm pack --json * `npmBuildFlags`: Flags to pass to `npm run ${npmBuildScript}`. * `npmPackFlags`: Flags to pass to `npm pack`. * `npmPruneFlags`: Flags to pass to `npm prune`. Defaults to the value of `npmInstallFlags`. +* `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`. #### prefetch-npm-deps {#javascript-buildNpmPackage-prefetch-npm-deps} diff --git a/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh b/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh index 64ddcbd567fc..c5824a6b232b 100644 --- a/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh +++ b/pkgs/build-support/node/build-npm-package/hooks/npm-install-hook.sh @@ -16,9 +16,19 @@ npmInstallHook() { cp "${npmWorkspace-.}/$file" "$dest" done < <(@jq@ --raw-output '.[0].files | map(.path) | join("\n")' <<< "$(npm pack --json --dry-run ${npmWorkspace+--workspace=$npmWorkspace} $npmPackFlags "${npmPackFlagsArray[@]}" $npmFlags "${npmFlagsArray[@]}")") + # Based on code from Python's buildPythonPackage wrap.sh script, for + # supporting both the case when makeWrapperArgs is an array and a + # IFS-separated string. + # + # TODO: remove the string branch when __structuredAttrs are used. + if [[ "${makeWrapperArgs+defined}" == "defined" && "$(declare -p makeWrapperArgs)" =~ ^'declare -a makeWrapperArgs=' ]]; then + local -a user_args=("${makeWrapperArgs[@]}") + else + local -a user_args="(${makeWrapperArgs:-})" + fi while IFS=" " read -ra bin; do mkdir -p "$out/bin" - makeWrapper @hostNode@ "$out/bin/${bin[0]}" --add-flags "$packageOut/${bin[1]}" + makeWrapper @hostNode@ "$out/bin/${bin[0]}" --add-flags "$packageOut/${bin[1]}" "${user_args[@]}" done < <(@jq@ --raw-output '(.bin | type) as $typ | if $typ == "string" then .name + " " + .bin elif $typ == "object" then .bin | to_entries | map(.key + " " + .value) | join("\n")