mkYarnModules in 2024
As of today, the documentation for the mkYarnModules
function in the official <code>nixpkgs</code> docs
leaves something to be desired.
There’s no introduction to the tool, an explanation of how it works, or any holistic examples/function signatures.
Through grepping the nixos/nixpkgs
GitHub
, I managed to create this a minimum viable usage example:
pkgs.mkYarnModules {
pname = "myYarnProject";
packageJSON = ./package.json;
yarnLock = ./yarn.lock;
version = "0.0.0";
};
When you build this, you’ll get a result
like1:
result
├── deps
│ └── myYarnProject
└── node_modules
├── myYarnProject -> ../deps/myYarnProject
├── example-dep-1
├── example-dep-2
└── ... more deps ...
The whole function signature here :
mkYarnModules = {
name ? "${pname}-${version}", # safe name and version, e.g. testcompany-one-modules-1.0.0
pname, # original name, e.g @testcompany/one
version,
packageJSON,
yarnLock,
yarnNix ? mkYarnNix { inherit yarnLock; },
offlineCache ? importOfflineCache yarnNix,
yarnFlags ? [ ],
ignoreScripts ? true,
nodejs ? inputs.nodejs,
yarn ? inputs.yarn.override { inherit nodejs; },
pkgConfig ? {},
preBuild ? "",
postBuild ? "",
workspaceDependencies ? [], # List of yarn packages
packageResolutions ? {},
}: {
# ...
}
Note that you can pass in a yarnNix
if you want to. This would be the nix expression resulting from running yarn2nix
in the directory containing your package.json
and yarn.lock
. mkYarnModules
will do this for you, but I could see this information being handy to get me out of a jam one day.
Why this came up
I’m using this to get <code>bun</code> support in my project.
Bun is super fast. It’s honestly hard to use npm
now for dependency resolution.
There’s not yet a native bun2nix
, and I didn’t want to spend a ton of time learning the complexities of <code>dream2nix</code>
. Luckily, though, bun
can output yarn.lock
files2, in addition to the normal bun.lockb
. I have this as part of my build process:
bun install --yarn
which generates a yarn.lock
that is then picked up later in my derivation:
# example.nix
{pkgs, ...}:
let
nodeDeps = pkgs.mkYarnModules {
pname = "exampleDeps";
packageJSON = ./package.json;
yarnLock = ./yarn.lock;
version = "0.0.0";
};
in
pkgs.stdenv.mkDerivation {
name = "example";
src = ./.;
buildInputs = with pkgs; [hugo git nodePackages.prettier tailwindcss];
buildPhase = ''
runHook preBuild
cp -r ${nodeDeps}/node_modules ./.
# inject deps here ☝️
tailwindcss -i assets/css/main.css -o static/css/styles.css
hugo
prettier -w public '!**/*.{js,css}'
runHook postBuild
'';
installPhase = "cp -r public $out";
}
Future work
I think that a lot could be done to make the documentation on this better. I’ll see if I can find the time to upstream what I’ve learned.
-
I only tested this on my blog project , which doesn’t have any JavaScript build steps. So this output might look slightly different, depending on your project structure. However, the
node_modules
anddeps
directories will still be the same. ↩︎ -
Yarn v1, to be precise. ↩︎