IFD-embracing Nix expression to import pnpm-lock.yaml files in Nix derivations
nixpkgs nix flake pnpm
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(docs): add README

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>

authored by

Sefa Eyeoglu and committed by tangled.org ed858ae0 a7de836e

+154
+154
README.md
··· 1 + # importPnpmLock.nix 2 + 3 + Nix tooling to import `pnpm-lock.yaml`s so you can build reproducible Node.js 4 + packages without package manager regrets. 5 + 6 + ## Importing 7 + 8 + ### The flakey way 9 + 10 + If you use Flakes, then you should know most of what comes next. 11 + 12 + Add importPnpmLock as an input: 13 + 14 + ```nix 15 + { 16 + inputs = { 17 + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 18 + importPnpmLock = { 19 + url = "git+https://tangled.org/scrumplex.net/importPnpmLock.nix"; 20 + inputs.nixpkgs.follows = "nixpkgs"; 21 + }; 22 + }; 23 + } 24 + ``` 25 + 26 + After that you can either consume the overlay `importPnpmLock.overlays.default` 27 + or directly add `importPnpmLock.legacyPackages.<system>.importPnpmLock` and 28 + `importPnpmLock.legacyPackages.<system>.iplConfigHook` to your derivation 29 + inputs. 30 + 31 + ### The classic way 32 + 33 + No matter if you use niv, npins or god forbid nix channels, you can just fetch 34 + this repo as a tarball from 35 + <https://tangled.org/scrumplex.net/importPnpmLock.nix/archive/main> and consume it. 36 + 37 + Below are some examples using npins for convenience: 38 + 39 + ```sh 40 + # npins - as a tarball 41 + $ npins add tarball https://tangled.org/scrumplex.net/importPnpmLock.nix/archive/main --name importPnpmLock 42 + 43 + # npins - as a git repo (bonus: pins tags, instead of latest commit!) 44 + $ npins add git https://tangled.org/scrumplex.net/importPnpmLock.nix --name importPnpmLock 45 + ``` 46 + 47 + After adding importPnpmLock.nix to npins, you can use it like this: 48 + 49 + ```nix 50 + let 51 + sources = import ./npins; 52 + 53 + pkgs = import sources.nixpkgs { }; 54 + 55 + # Use ipl attrs directly 56 + ipl = import sources.importPnpmLock { inherit pkgs; }; 57 + 58 + # Use it as an overlay 59 + pkgsWithIPL = import sources.nixpkgs { 60 + overlays = [ 61 + (final: _: import ../Projects/importPnpmLock.nix { pkgs = final; }) 62 + ]; 63 + }; 64 + in 65 + # do something 66 + ``` 67 + 68 + ## Usage 69 + 70 + This repository exposes two outputs. 71 + 72 + 1. `importPnpmLock` - the actual function that generates a reproducible cache 73 + of all dependencies defined in `pnpm-lock.yaml` 74 + 2. `iplConfigHook` - the configuration hook that runs `pnpm install` with some 75 + fluff to make it all work in your actual derivation 76 + 77 + An example is best suited to show how these work together: 78 + 79 + ```nix 80 + { 81 + importPnpmLock, 82 + iplConfigHook, 83 + pnpm_10, 84 + stdenv, 85 + }: 86 + stdenv.mkDerivation (finalAttrs: { 87 + pname = "my-package"; 88 + version = "1.14.4"; 89 + 90 + src = ./.; 91 + 92 + # iplConfigHook uses the great mitm-cache under the hood, which is why this 93 + # attribute has to be called mitmCache 94 + mitmCache = importPnpmLock { 95 + # pname and version are required to to make it look nicer 96 + inherit (finalAttrs) pname version; 97 + 98 + # Path to the lock file. This causes IFD! 99 + lockFile = ./pnpm-lock.yaml; 100 + 101 + # Tarballs and Git dependencies don't have hashes, that's why those need to 102 + # be specified manually :/ 103 + manualEntries = { 104 + "my-weird-unstable-package@https://codeload.github.com/copilot/my-weird-unstable-package/tar.gz/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" = 105 + "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; 106 + }; 107 + }; 108 + 109 + nativeBuildInputs = [ 110 + # iplConfigHook hooks into configurePhase to prepare the pnpm workspace 111 + iplConfigHook 112 + # pnpm needs to be added explicitly! 113 + pnpm_10 114 + ]; 115 + 116 + 117 + # Optionally define additional flags for pnpm install 118 + # pnpmInstallFlags = [ 119 + # "--shamefully-hoist" 120 + # ]; 121 + 122 + buildPhase = '' 123 + runHook preBuild 124 + 125 + # or any other script 126 + pnpm run build 127 + 128 + runHook postBuild 129 + ''; 130 + 131 + installPhase = '' 132 + runHook preInstall 133 + 134 + # Or anything else really 135 + cp -r dist/ $out 136 + 137 + runHook postInstall 138 + ''; 139 + }) 140 + ``` 141 + 142 + ## Caveats 143 + 144 + - IFD - As Nix does not support importing/reading YAML files natively, we have 145 + to convert `pnpm-lock.yaml` files to JSON so we can parse them. This introduces 146 + a performance loss that other places can explain in much more detail. 147 + - Manual hashes for tarballs - `pnpm-lock.yaml` does not store hashes for 148 + tarballs, and by extension Git sources. That means those will still need to be 149 + specified by hand, making automated updates by the likes of Renovate or 150 + dependabot more cumbersome. 151 + - Huge cache - As the parser is very dumb, it will always create a cache for 152 + the whole lockfile, even if you just want to build a tiny component of a huge 153 + monorepo. On the other hand, there will only be a single cache for the whole 154 + monorepo! There may be ways to reduce the cache in the future.