Search code examples
npmnix

How to set NPM command line flags with `node2nix`?


Trying to install Puppeteer, but it keeps failing for some storage.googleapis.com security limitations as the install process is trying to download the latest Chromium binary from there. After looking at many related GitHub issues (1,2,3), the only thing that works is setting npm's --unsafe-perm=true command line flag when using a non-Nix-installed npm.

I couldn't find anything in the main node2nix README and in the node2nix --help output on how to specify additional NPM command line flags. (Did I overlook something?)

Found the buildNodePackage lambda below in the node2nix source with an npmFlags argument defaulting to an empty string:

  # Builds and composes an NPM package including all its dependencies
  buildNodePackage =
    { name
    , packageName
    , version
    , dependencies ? []
    , buildInputs ? []
    , production ? true
    , npmFlags ? ""
    , dontNpmInstall ? false
    , bypassCache ? false
    , reconstructLock ? false
    , preRebuild ? ""
    , dontStrip ? true
    , unpackPhase ? "true"
    , buildPhase ? "true"
    , ... }@args:

If this npmFlags needs to be overridden, how would I do this?


Solution

  • The final Nix expression depends on the node2nix use case (1 and 2), but the good thing is that the same set of Nix expressions need to be overridden:

    node2nix will generate three files in either case:

    1. node-env.nix
      Defines buildNodeSourceDist, buildNodePackage, and buildNodeShell overridable Nix expressions. The latter two both have both have an npmFlags attribute in their argument.

    2. node-packages.nix
      Defines a lambda enumerating all dependencies, and returns an attribute set.

    • Use case 1's attribute set contains
      tarball (to make source archive via buildNodeSourceDist)
      package (to build the project via buildNodePackage), and
      shell (to set up a dev environment for the the project via buildNodeShell)

    • The attribute set returned in use case 2 consists of the name of the packages built via buildNodePackage, from the input list (usually located in node-packages.json).

    1. default.nix Imports node-packages.nix, and calls the imported lambda, returning either of the two attribute sets above.

    To specify flags, one can override the input attribute set, using the example mentioned in the node2nix README:

    {pkgs ? import <nixpkgs> {
        inherit system;
    }, system ? builtins.currentSystem}:
    
    let
      nodePackages = import ./default.nix {
        inherit pkgs system;
      };
    in
    nodePackages // {
      
      # use case 1
      # ==========
      # shell   = nodePackages.shell.override {
      # package = nodePackages.package.override {
    
      # use case 2
      # ==========
      aPackageName = nodePackages.aPackageName.override {
        npmFlags = "--unsafe-perm=true";
      };
    }