···552552553553### Yarn {#javascript-yarn}554554555555-Yarn based projects use a `yarn.lock` file instead of a `package-lock.json` to pin dependencies. Nixpkgs provides the Nix function `fetchYarnDeps` which fetches an offline cache suitable for running `yarn install` before building the project. In addition, Nixpkgs provides the hooks:555555+Yarn based projects use a `yarn.lock` file instead of a `package-lock.json` to pin dependencies.556556+557557+To package yarn-based applications, you need to distinguish by the version pointers in the `yarn.lock` file. See the following sections.558558+559559+#### Yarn v1 {#javascript-yarn-v1}560560+561561+Yarn v1 lockfiles contain a comment `# yarn lockfile v1` at the beginning of the file.562562+563563+Nixpkgs provides the Nix function `fetchYarnDeps` which fetches an offline cache suitable for running `yarn install` before building the project. In addition, Nixpkgs provides the hooks:556564557565- `yarnConfigHook`: Fetches the dependencies from the offline cache and installs them into `node_modules`.558566- `yarnBuildHook`: Runs `yarn build` or a specified `yarn` command that builds the project.···610602})611603```612604613613-#### `yarnConfigHook` arguments {#javascript-yarnconfighook}605605+##### `yarnConfigHook` arguments {#javascript-yarnconfighook}614606615607By default, `yarnConfigHook` relies upon the attribute `${yarnOfflineCache}` (or `${offlineCache}` if the former is not set) to find the location of the offline cache produced by `fetchYarnDeps`. To disable this phase, you can set `dontYarnInstallDeps = true` or override the `configurePhase`.616608617617-#### `yarnBuildHook` arguments {#javascript-yarnbuildhook}609609+##### `yarnBuildHook` arguments {#javascript-yarnbuildhook}618610619611This script by default runs `yarn --offline build`, and it relies upon the project's dependencies installed at `node_modules`. Below is a list of additional `mkDerivation` arguments read by this hook:620612621613- `yarnBuildScript`: Sets a different `yarn --offline` subcommand (defaults to `build`).622614- `yarnBuildFlags`: Single string list of additional flags to pass the above command, or a Nix list of such additional flags.623615624624-#### `yarnInstallHook` arguments {#javascript-yarninstallhook}616616+##### `yarnInstallHook` arguments {#javascript-yarninstallhook}625617626618To install the package `yarnInstallHook` uses both `npm` and `yarn` to cleanup project files and dependencies. To disable this phase, you can set `dontYarnInstall = true` or override the `installPhase`. Below is a list of additional `mkDerivation` arguments read by this hook:627619628620- `yarnKeepDevDeps`: Disables the removal of devDependencies from `node_modules` before installation.629621630630-### yarn2nix {#javascript-yarn2nix}622622+#### yarn2nix {#javascript-yarn2nix}631623632632-WARNING: The `yarn2nix` functions have been deprecated in favor of the new `yarnConfigHook`, `yarnBuildHook` and `yarnInstallHook`. Documentation for them still appears here for the sake of the packages that still use them. See also a tracking issue [#324246](https://github.com/NixOS/nixpkgs/issues/324246).624624+WARNING: The `yarn2nix` functions have been deprecated in favor of `yarnConfigHook`, `yarnBuildHook` and `yarnInstallHook` (for Yarn v1) and `yarn-berry_*.*` tooling (Yarn v3 and v4). Documentation for `yarn2nix` functions still appears here for the sake of the packages that still use them. See also a tracking issue [#324246](https://github.com/NixOS/nixpkgs/issues/324246).633625634634-#### Preparation {#javascript-yarn2nix-preparation}626626+##### Preparation {#javascript-yarn2nix-preparation}635627636628You will need at least a `yarn.lock` file. If upstream does not have one you need to generate it and reference it in your package definition.637629···646638}647639```648640649649-#### mkYarnPackage {#javascript-yarn2nix-mkYarnPackage}641641+##### mkYarnPackage {#javascript-yarn2nix-mkYarnPackage}650642651643`mkYarnPackage` will by default try to generate a binary. For package only generating static assets (Svelte, Vue, React, WebPack, ...), you will need to explicitly override the build step with your instructions.652644···697689}698690```699691700700-#### mkYarnModules {#javascript-yarn2nix-mkYarnModules}692692+##### mkYarnModules {#javascript-yarn2nix-mkYarnModules}701693702694This will generate a derivation including the `node_modules` directory.703695If you have to build a derivation for an integrated web framework (rails, phoenix..), this is probably the easiest way.···732724}733725```734726735735-#### Pitfalls {#javascript-yarn2nix-pitfalls}727727+##### Pitfalls {#javascript-yarn2nix-pitfalls}736728737729- If version is missing from upstream package.json, yarn will silently install nothing. In that case, you will need to override package.json as shown in the [package.json section](#javascript-upstream-package-json)738730- Having trouble with `node-gyp`? Try adding these lines to the `yarnPreBuild` steps:···751743 - The `echo 9` steps comes from this answer: <https://stackoverflow.com/a/49139496>752744 - Exporting the headers in `npm_config_nodedir` comes from this issue: <https://github.com/nodejs/node-gyp/issues/1191#issuecomment-301243919>753745- `offlineCache` (described [above](#javascript-yarn2nix-preparation)) must be specified to avoid [Import From Derivation](#ssec-import-from-derivation) (IFD) when used inside Nixpkgs.746746+747747+#### Yarn Berry v3/v4 {#javascript-yarn-v3-v4}748748+Yarn Berry (v3 / v4) have similar formats, they start with blocks like these:749749+750750+```yaml751751+__metadata:752752+ version: 6753753+ cacheKey: 8[cX]754754+```755755+756756+```yaml757757+__metadata:758758+ version: 8759759+ cacheKey: 10[cX]760760+```761761+762762+For these packages, we have some helpers exposed under the respective `yarn-berry_3` and `yarn-berry_4` packages:763763+764764+- `yarn-berry-fetcher`765765+- `fetchYarnBerryDeps`766766+- `yarnBerryConfigHook`767767+768768+It's recommended to ensure you're explicitly pinning the major version used, for example by capturing the `yarn-berry_Xn` argument and then re-defining it as a `yarn-berry` `let` binding.769769+770770+```nix771771+{772772+ stdenv,773773+ nodejs,774774+ yarn-berry_4,775775+}:776776+777777+let778778+ yarn-berry = yarn-berry_4;779779+in780780+781781+stdenv.mkDerivation (finalAttrs: {782782+ pname = "foo";783783+ version = "0-unstable-1980-01-01";784784+785785+ src = {786786+ #...787787+ };788788+789789+ nativeBuildInputs = [790790+ nodejs791791+ yarn-berry.yarnBerryConfigHook792792+ ];793793+794794+ offlineCache = yarn-berry.fetchYarnBerryDeps {795795+ inherit (finalAttrs) src;796796+ hash = "...";797797+ };798798+})799799+```800800+801801+##### `yarn-berry_X.fetchYarnBerryDeps` {#javascript-fetchYarnBerryDeps}802802+`fetchYarnBerryDeps` runs `yarn-berry-fetcher fetch` in a fixed-output-derivation. It is a custom fetcher designed to reproducibly download all files in the `yarn.lock` file, validating their hashes in the process. For git dependencies, it creates a checkout at `${offlineCache}/checkouts/<40-character-commit-hash>` (relying on the git commit hash to describe the contents of the checkout).803803+804804+To produce the `hash` argument for `fetchYarnBerryDeps` function call, the `yarn-berry-fetcher prefetch` command can be used:805805+806806+```console807807+$ yarn-berry-fetcher prefetch </path/to/yarn.lock> [/path/to/missing-hashes.json]808808+```809809+810810+This prints the hash to stdout and can be used in update scripts to recalculate the hash for a new version of `yarn.lock`.811811+812812+##### `yarn-berry_X.yarnBerryConfigHook` {#javascript-yarnBerryConfigHook}813813+`yarnBerryConfigHook` uses the store path `offlineCache` points to, to run a `yarn install` during the build, producing a usable `node_modules` directory from the downloaded dependencies.814814+815815+Internally, this uses a patched version of Yarn to ensure git dependencies are re-packed and any attempted downloads fail immediately.816816+817817+##### Patching upstream `package.json` or `yarn.lock` files {#javascript-yarnBerry-patching}818818+In case patching the upstream `package.json` or `yarn.lock` is needed, it's important to pass `finalAttrs.patches` to `fetchYarnBerryDeps` as well, so the patched variants are picked up (i.e. `inherit (finalAttrs) patches`.819819+820820+##### Missing hashes in the `yarn.lock` file {#javascript-yarnBerry-missing-hashes}821821+Unfortunately, `yarn.lock` files do not include hashes for optional/platform-specific dependencies. This is [by design](https://github.com/yarnpkg/berry/issues/6759).822822+823823+To compensate for this, the `yarn-berry-fetcher missing-hashes` subcommand can be used to produce all missing hashes. These are usually stored in a `missing-hashes.json` file, which needs to be passed to both the build itself, as well as the `fetchYarnBerryDeps` helper:824824+825825+```nix826826+{827827+ stdenv,828828+ nodejs,829829+ yarn-berry_4,830830+}:831831+832832+let833833+ yarn-berry = yarn-berry_4;834834+in835835+836836+stdenv.mkDerivation (finalAttrs: {837837+ pname = "foo";838838+ version = "0-unstable-1980-01-01";839839+840840+ src = {841841+ #...842842+ };843843+844844+ nativeBuildInputs = [845845+ nodejs846846+ yarn-berry.yarnBerryConfigHook847847+ ];848848+849849+ missingHashes = ./missing-hashes.json;850850+ offlineCache = yarn-berry.fetchYarnBerryDeps {851851+ inherit (finalAttrs) src missingHashes;852852+ hash = "...";853853+ };854854+})855855+```754856755857## Outside Nixpkgs {#javascript-outside-nixpkgs}756858
···2626 write = lib.mkOption {2727 type = lib.types.bool;2828 default = false;2929- description = "Whether to enable writing to the Nix store as a remote store via SSH. Note: the sshServe user is named nix-ssh and is not a trusted-user. nix-ssh should be added to the {option}`nix.settings.trusted-users` option in most use cases, such as allowing remote building of derivations.";2929+ description = "Whether to enable writing to the Nix store as a remote store via SSH. Note: by default, the sshServe user is named nix-ssh and is not a trusted-user. nix-ssh should be added to the {option}`nix.sshServe.trusted` option in most use cases, such as allowing remote building of derivations to anonymous people based on ssh key";3030+ };3131+3232+ trusted = lib.mkOption {3333+ type = lib.types.bool;3434+ default = false;3535+ description = "Whether to add nix-ssh to the nix.settings.trusted-users";3036 };31373238 keys = lib.mkOption {···6458 shell = pkgs.bashInteractive;6559 };6660 users.groups.nix-ssh = { };6161+6262+ nix.settings.trusted-users = lib.mkIf cfg.trusted [ "nix-ssh" ];67636864 services.openssh.enable = true;6965
+1
pkgs/by-name/br/bruno-cli/package.nix
···3838 npm run build --workspace=packages/bruno-common3939 npm run build --workspace=packages/bruno-graphql-docs4040 npm run build --workspace=packages/bruno-query4141+ npm run build --workspace=packages/bruno-requests41424243 npm run sandbox:bundle-libraries --workspace=packages/bruno-js4344
+5-3
pkgs/by-name/br/bruno/package.nix
···17171818buildNpmPackage rec {1919 pname = "bruno";2020- version = "2.0.1";2020+ version = "2.2.0";21212222 src = fetchFromGitHub {2323 owner = "usebruno";2424 repo = "bruno";2525 tag = "v${version}";2626- hash = "sha256-iKwmBkeyKlahzmPCPZ/S8XwIgTK6qD2XHiQkUu2nnZQ=";2626+ hash = "sha256-4SIOLVXVxRSaSmZcje//+o/dyLINDAM2CvLQGEAykq0=";27272828 postFetch = ''2929 ${lib.getExe npm-lockfile-fix} $out/package-lock.json3030 '';3131 };32323333- npmDepsHash = "sha256-t6KZc48nS9hyQZdOS4lVgcMw9RyyK7jEmMjA41s4HaY=";3333+ npmDepsHash = "sha256-W4qF2/AAcygqykB4zcBjb8KhfVaMrj8FLgadalDNF+0=";3434 npmFlags = [ "--legacy-peer-deps" ];35353636 nativeBuildInputs =···92929393 npm run build --workspace=packages/bruno-common9494 npm run build --workspace=packages/bruno-graphql-docs9595+ npm run build --workspace=packages/bruno-converters9596 npm run build --workspace=packages/bruno-app9697 npm run build --workspace=packages/bruno-query9898+ npm run build --workspace=packages/bruno-requests979998100 npm run sandbox:bundle-libraries --workspace=packages/bruno-js99101
···11+{22+ makeSetupHook,33+ yarn-berry-offline,44+ srcOnly,55+ nodejs,66+ diffutils,77+}:88+99+makeSetupHook {1010+ name = "yarn-berry-config-hook";1111+ substitutions = {1212+ # Specify `diff` by abspath to ensure that the user's build1313+ # inputs do not cause us to find the wrong binaries.1414+ diff = "${diffutils}/bin/diff";1515+1616+ yarn_offline = "${yarn-berry-offline}/bin/yarn";1717+1818+ nodeSrc = srcOnly nodejs;1919+ nodeGyp = "${nodejs}/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js";2020+ };2121+ meta = {2222+ description = "Install nodejs dependencies from an offline yarn cache produced by fetchYarnDeps";2323+ };2424+} ./yarn-berry-config-hook.sh
···11+yarnBerryConfigHook() {22+ echo "Executing yarnBerryConfigHook"33+44+ # Use a constant HOME directory55+ export HOME=$(mktemp -d)66+ if [[ -n "$yarnOfflineCache" ]]; then77+ offlineCache="$yarnOfflineCache"88+ fi99+ if [[ -z "$offlineCache" ]]; then1010+ echo yarnBerryConfigHook: No yarnOfflineCache or offlineCache were defined\! >&21111+ exit 21212+ fi1313+1414+ local -r cacheLockfile="$offlineCache/yarn.lock"1515+ local -r srcLockfile="$PWD/yarn.lock"1616+1717+ echo "Validating consistency between $srcLockfile and $cacheLockfile"1818+1919+ if ! @diff@ "$srcLockfile" "$cacheLockfile"; then2020+ # If the diff failed, first double-check that the file exists, so we can2121+ # give a friendlier error msg.2222+ if ! [ -e "$srcLockfile" ]; then2323+ echo2424+ echo "ERROR: Missing yarn.lock from src. Expected to find it at: $srcLockfile"2525+ echo "Hint: You can copy a vendored yarn.lock file via postPatch."2626+ echo2727+2828+ exit 12929+ fi3030+3131+ if ! [ -e "$cacheLockfile" ]; then3232+ echo3333+ echo "ERROR: Missing lockfile from cache. Expected to find it at: $cacheLockfile"3434+ echo3535+3636+ exit 13737+ fi3838+3939+ echo4040+ echo "ERROR: fetchYarnDeps hash is out of date"4141+ echo4242+ echo "The yarn.lock in src is not the same as the in $offlineCache."4343+ echo4444+ echo "To fix the issue:"4545+ echo '1. Use `lib.fakeHash` as the fetchYarnBerryDeps hash value'4646+ echo "2. Build the derivation and wait for it to fail with a hash mismatch"4747+ echo "3. Copy the 'got: sha256-' value back into the fetchYarnBerryDeps hash field"4848+ echo4949+5050+ exit 15151+ fi5252+5353+ if [[ -n "$missingHashes" ]] || [[ -f "$offlineCache/missing-hashes.json" ]]; then5454+ echo "Validating consistency of missing-hashes.json"5555+ if [[ -z "$missingHashes" ]]; then5656+ echo "You must specify missingHashes in your derivation"5757+ exit 15858+ fi5959+ if ! @diff@ "$missingHashes" "$offlineCache/missing-hashes.json"; then6060+ exit 16161+ fi6262+ fi6363+6464+ YARN_IGNORE_PATH=1 @yarn_offline@ config set enableTelemetry false6565+ YARN_IGNORE_PATH=1 @yarn_offline@ config set enableGlobalCache false6666+6767+ # The cache needs to be writable in case yarn needs to re-pack any patch: or git dependencies6868+ rm -rf ./.yarn/cache6969+ mkdir -p ./.yarn7070+ cp -r --reflink=auto $offlineCache/cache ./.yarn/cache7171+ chmod u+w -R ./.yarn/cache7272+ [ -d $offlineCache/checkouts ] && cp -r --reflink=auto $offlineCache/checkouts ./.yarn/checkouts7373+ [ -d $offlineCache/checkouts ] && chmod u+w -R ./.yarn/checkouts7474+7575+ export npm_config_nodedir="@nodeSrc@"7676+ export npm_config_node_gyp="@nodeGyp@"7777+7878+ YARN_IGNORE_PATH=1 @yarn_offline@ install --inline-builds7979+8080+ echo "finished yarnBerryConfigHook"8181+}8282+8383+if [[ -z "${dontYarnBerryInstallDeps-}" ]]; then8484+ postConfigureHooks+=(yarnBerryConfigHook)8585+fi