Почему этот импорт javascript не работает в сборке nix, но успешен в оболочке nix?

Моя цель состоит в том, чтобы запустить следующую команду generate.js, которая будет использовать d3.js для создания svg-файла.

$ nix build 'github:MatrixManAtYrService/buildsvg#svg'
$ ls result
    output.svg

В этом репозитории (https://github.com/MatrixManAtYrService/buildsvg) в выходных данных есть flake.nix с таким выводом:

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/
  '';
};

Но вместо завершения команда node завершается с ошибкой:

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

Верхняя часть generate.js выглядит так:

import fs from 'fs';
import * as d3 from 'd3';
import opentype from 'opentype.js';  // <--- failure is here
import D3Node from 'd3-node';

Итак, я знаю, что некоторые из моих модулей импортируются правильно. Кроме того, если я использую оболочку разработчика nix, она работает нормально:

devShells.default = pkgs.mkShell {
  buildInputs = [
    pkgs.nodePackages.nodejs
  ];
  shellHook = ''
    export NODE_PATH=$PWD/node_modules
  '';
};

$ nix develop
$ node generate.js
SVG generated successfully.

Мой package.json указывает на эти зависимости, и я запустил npm install, что привело к их загрузке в node_modules (извините, если это очевидно, я новичок в nodejs).

Я добавил утверждения ls в buildPhase и убедился, что /nix/store/a76p6qgrxlx0safvxrqx5aknhszvg703-source/node_modules/opentype.js/package.json действительно существует, несмотря на то, что говорит ошибка.

Почему моя сборка nix не удалась, хотя та же команда отлично работает в devshell?

🤔 А знаете ли вы, что...
JavaScript позволяет создавать динамические и интерактивные веб-приложения.


57
1

Ответ:

Решено

У меня есть привычка копировать .gitignore файлы из других проектов. В этом случае я по ошибке скопировал .gitignore из проекта Python, который включал следующие строки:

dist/
bin/

Это привело к тому, что nix пропустил определенные файлы при копировании моего проекта в хранилище nix для сборки:

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

Итак, opentype.js's package.json присутствовал в магазине nix, но вышеуказанные части этого пакета отсутствовали. Это привело к сбою импорта.

К сожалению, сообщение об ошибке не указывает файлы, которые на самом деле отсутствовали, а вместо этого указывает читателю на package.json, который существует.