Hi. I have a couple questions about using mkYarnPackage
. I’m trying to nixify
this vscode extension since I had to patch it, and am using a flake.nix
. I had to yarn add vsce
, which was the only change to packages.json
.
From a dev shell with only the yarn
dependency, I can run yarn --offline compile
and
yarn --offline vsce package --yarn -o command-server.vsix
. This builds fine, and I can install the .vsix file into vscode.
The problems come when I try to nix build .
. The first problem is I get a ENOENT
from
some yazl
dependency:
$ yarn run compile
warning You don't appear to have an internet connection. Try the --offline flag to use the cache for registry queries.
$ tsc -p ./
> WARNING Using '*' activation is usually a bad idea as it impacts performance.
> More info: https://code.visualstudio.com/api/references/activation-events#Start-up
Do you want to continue? [y/N] y
> node:events:492
> throw er; // Unhandled 'error' event
> ^
>
> Error: ENOENT: no such file or directory, stat '/build/5sg0ck2mfpyccf2pzv1jr133lk15ravx-source/deps/command-server/command-server'
> Emitted 'error' event on ZipFile instance at:
> at /nix/store/ys3bczil4nlvaa7n5hyshrivafs46k84-command-server-modules-0.9.0/node_modules/yazl/index.js:30:26
> at FSReqCallback.oncomplete (node:fs:199:21) {
> errno: -2,
> code: 'ENOENT',
> syscall: 'stat',
> path: '/build/5sg0ck2mfpyccf2pzv1jr133lk15ravx-source/deps/command-server/command-server'
> }
>
> Node.js v20.10.0
I confirmed that /nix/store/5sg0ck2mfpyccf2pzv1jr133lk15ravx-source
doesn’t contain this file. So the easy solution is to create a file deps/command-server/command-server
in the project repo, git add it, and then rebuild, so that it gets populated into the build source folder. This builds (although the extension doesn’t work), but I don’t understand why this is happening only during nix build
, so am curious if anyone has any insight.
The second issue is that for my buildPhase
I had called yarn --offline vsce package --yarn -o command-server.vsix
and in my installPhase
I had:
mkdir $out
mv command-server.vsix $out
However, this always complains that command-server.vsix
doesn’t exist. If I use $PWD/command-server.vsix
the error indicates it’s operating from the same /build/...
folder above, but if I check it seems the .vsix is not written there.
The only way I’ve been able to solve this is to use echo y | yarn --offline vsce package --yarn -o $out/$pname.vsix
from the installPhase
, where I’m explicitly telling it to write to $out
, in which case I see the file in result
.
I’m curious what I’m missing and what the correct way to approach this second problem is. It seems fine to just write directly to $out
, but I expected the mv
to work and saw other examples online that seemed to use that approach, so would like to know why it fails.
My flake is quite simple:
{
description = "A Nix-flake-based development environment for command-server";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
outputs = { self, nixpkgs }:
let
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
pkgs = import nixpkgs { inherit system; config.allowUnfree = true; };
});
in
{
packages = forEachSupportedSystem
({ pkgs, ... }:
let
attrs = with builtins; fromJSON (readFile ./package.json);
in
{
default = pkgs.mkYarnPackage {
pname = with attrs; name;
src = ./.;
packageJson = ./package.json;
yarnLock = ./yarn.lock;
buildPhase = ''
# yarn tries to create a .yarn file in $HOME. There's probably a
# better way to fix this but setting HOME to TMPDIR works for now.
export HOME="$TMPDIR"
yarn tsc -p ./
'';
installPhase = ''
mkdir $out
echo y | yarn --offline vsce package --yarn -o $out/$pname.vsix
'';
distPhase = "true";
};
});
devShells = forEachSupportedSystem
({ pkgs }: {
default = pkgs.mkShell
{
packages = with pkgs;
[ yarn ];
};
});
};
}