My goal is that the following command should run generate.js
which will use d3.js
to build a svg file.
$ nix build 'github:MatrixManAtYrService/buildsvg#svg'
$ ls result
output.svg
That repo (https://github.com/MatrixManAtYrService/buildsvg) has a flake.nix
with this derivation in the outputs:
packages.svg = pkgs.stdenv.mkDerivation rec {
name = "generate-svg";
src = self;
buildInputs = [ pkgs.nodePackages.nodejs ];
buildPhase = ''
export NODE_PATH=${src}/node_modules
node ${src}/generate.js
'';
installPhase = ''
mkdir -p $out
cp output.svg $out/
'';
};
But instead of completing, the node
command fails with this error:
Error: Cannot find package '/nix/store/a76p6qgrxlx0safvxrqx5aknhszvg703-source/node_modules/opentype.js/package.json' imported from /nix/store/a76p6qgrxlx0safvxrqx5aknhszvg703-source/generate.js
at legacyMainResolve (node:internal/modules/esm/resolve:215:26)
at packageResolve (node:internal/modules/esm/resolve:841:14)
at moduleResolve (node:internal/modules/esm/resolve:927:18)
at defaultResolve (node:internal/modules/esm/resolve:1157:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:390:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:359:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:234:38)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:87:39)
at link (node:internal/modules/esm/module_job:86:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
Node.js v20.12.2
The top of generate.js
looks like this:
import fs from 'fs';
import * as d3 from 'd3';
import opentype from 'opentype.js'; // <--- failure is here
import D3Node from 'd3-node';
So I know that some of my modules are being imported correctly. Also, If I use a nix devshell, it works fine:
devShells.default = pkgs.mkShell {
buildInputs = [
pkgs.nodePackages.nodejs
];
shellHook = ''
export NODE_PATH=$PWD/node_modules
'';
};
$ nix develop
$ node generate.js
SVG generated successfully.
My package.json
indicates these dependencies, and I've run npm install
which caused them to be downloaded into node_modules
(pardon if this is obvious, I'm a nodejs newbie).
I have sprinkled ls
statements into the buildPhase
and verified that /nix/store/a76p6qgrxlx0safvxrqx5aknhszvg703-source/node_modules/opentype.js/package.json
does indeed exist, despite what the error says.
Why is my nix build failing, while the same command works fine in a devshell?
I have a habit of copying .gitignore
files from other projects. In this case I mistakenly copied a .gitignore
from a python project which included these lines:
dist/
bin/
This caused nix to omit certain files when it copied my project into the nix store for the build:
node_modules/opentype.js/bin/ot
node_modules/opentype.js/bin/server.js
node_modules/opentype.js/bin/test-render
node_modules/opentype.js/dist/opentype.js
node_modules/opentype.js/dist/opentype.js.map
node_modules/opentype.js/dist/opentype.min.js
node_modules/opentype.js/dist/opentype.min.js.map
node_modules/opentype.js/dist/opentype.module.js
node_modules/opentype.js/dist/opentype.module.js.map
So opentype.js
's package.json
was present in the nix store, but the above parts of that package were missing. This caused the import to fail.
It's unfortunate that the error message did not indicate the files which were actually missing, but instead points the reader at package.json
which exists.