Using overrideAttrs on Nixpkgs with buildNpmPackage
In NixOS, overrideAttrs
allows to customize the arguments passed to stdenv.mkDerivation
.
This is useful for things like modifying src
to change the version of a package, or adjusting the flags used to build a package:
final: prev: {
zig_0_12 = prev.zig_0_12.overrideAttrs (_: {
# workaround for https://github.com/NixOS/nixpkgs/issues/317055
strictDeps = !prev.stdenv.cc.isClang;
});
}
However, this method does not (directly) work for packages built with wrappers around mkDerivation
.
For example, buildNpmPackage
acts as wrapper around mkDerivation
.
Calling overrideAttrs
will overide parts of mkDerivation
, but will not allow for the modification of arguments passed to buildNpmPackage
.
This makes changes to a file like package-lock.json
(using patches
or a postPatch
script) impossible, as it’s too late to modify the npmDeps
that have been fetched and passed to mkDerivation
at this point.
Although though patches
can be used to modify the package-lock.json
file present in src
, the NPM dependencies have already been fetched and modifications to package-lock.json
will have no effect.
In other words, overrideAttrs
affects mkDerivation
, not buildNpmPackage
or other helpers
Since buildNpmPackage
cannot be modified, its output (which is passed to mkDerivation
) can be modified instead.
npmDeps
is a derivation created by fetchNpmDeps
; to override it, fetchNpmDeps
can be provided with new arguments, such as patches that are not present in the original buildNpmPackage
invocation of fetchNpmDeps
.
zwave-js-server = prev.zwave-js-server.overrideAttrs (old: rec {
# to update: run `npm update` in the zwave-js-server repo (or npm install --only-lock-file)
# copy package-lock.json to the patches dir
# update the npmDepsHash with `nix run nixpkgs#prefetch-npm-deps package-lock.json`
patches = (old.patches or [ ]) ++ [
./zwave-js-server/logging-unknown-type.patch
];
postPatch = ''
cp ${./zwave-js-server/package-lock.json} ./package-lock.json
'';
npmDeps = final.fetchNpmDeps {
inherit (old) src;
inherit postPatch;
hash = "sha256-ECdmSOugInD7JFEvjkeQfMyrJzKhOIQHs3MwOFEpoSk=";
};
});
The goal of this override is to use a custom version of npmDeps
with updated dependencies.
A newer package-lock.json
is provided (replacing the old one present in src
), along with a new hash.
This new hash is calculated by running nix run nixpkgs#prefetch-npm-deps package-lock.json
with the new/ updated package-lock.json
file.
Finally, a patch is applied to src
—this is the more usual use of overrideAttrs
, providing an additional patch to apply against src
.
This patch will be applied after fetching the NPM dependencies (which is done by fetchNpmDeps
, prior to running mkDerivation
).
To further update the dependencies, update the package-lock.json
file (using npm update
or similar), then update the hash with nix run nixpkgs#prefetch-npm-deps package-lock.json
.