I'm pretty new to Nix, and I'm trying to build a derivation around an Eleventy static site project.
I have a build
script in my package.json file defined as "npx eleventy"
. When I run npm run build
, it compiles all the source files into a folder of static assets called public/.
I have a derivation defined like:
mysite.nix
{ buildNpmPackage, lib }:
let
fs = lib.fileset;
sourceFiles = fs.gitTracked ./.;
in
buildNpmPackage rec {
npmDepsHash = "sha256-+4lLBQ+UQ2XT0wwE6jADxG1UNZjLkQCLvvN1SdiUwZY=";
pname = "mysite";
src = fs.toSource {
root = ./.;
fileset = sourceFiles;
};
version = "0.0.1";
}
and default.nix
let
# channel 24.11-darwin
# 2025-02-20
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/d27f39bcb57207b9b891f7beaed84bd50e757201.tar.gz";
pkgs = import nixpkgs { config = {}; overlays = []; };
in
{
mysite = pkgs.callPackage ./mysite.nix { };
}
(Tip: this is a nixpkgs hash that for some cursed reason builds Node's entire runtime from source, and it takes several hours. I really don't think my issue is specific to the particular version of the runtime I'm using, so if you're trying to reproduce my issue, it would be a good idea to pin to a different commit.)
I can build the site using nix-build --attr mysite
and it builds just fine, and I can even see the output from the Eleventy command claiming to be writing files out too a folder called "public", so I know it's working roughly how I expect, but it doesn't output a directory called public/ anywhere in the result symlinked directory.
And perhaps this makes sense, right? Because there's no "bin" attribute to my package.json (Okay, I admit having tried that despite it making no sense.)
So I guess what I'm asking is: Is there a good way of making buildNpmPackage
derivations that output a directory instead of a single bin
? Or are derivations just a bad tool for this?
Hat tip to @BryanBennett@tilde.zone who gave me the answer on Mastodon.
buildNpmPackage
inherits from mkDerivation
, so you can just get the directory by overriding postInstall
.
buildNpmPackage rec {
npmDepsHash = "sha256-+4lLBQ+UQ2XT0wwE6jADxG1UNZjLkQCLvvN1SdiUwZY=";
pname = "mysite";
src = fs.toSource {
root = ./.;
fileset = sourceFiles;
};
postInstall = ''
cp -rv public/ $out
'';
version = "0.0.1";