Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yarnInstallHook: init #328544

Merged
merged 5 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions doc/languages-frameworks/javascript.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ Yarn based projects use a `yarn.lock` file instead of a `package-lock.json` to p

- `yarnConfigHook`: Fetches the dependencies from the offline cache and installs them into `node_modules`.
- `yarnBuildHook`: Runs `yarn build` or a specified `yarn` command that builds the project.
- `yarnInstallHook`: Runs `yarn install --production` to prune dependencies and installs the project into `$out`.
lelgenio marked this conversation as resolved.
Show resolved Hide resolved

An example usage of the above attributes is:

Expand Down Expand Up @@ -501,9 +502,9 @@ stdenv.mkDerivation (finalAttrs: {
nativeBuildInputs = [
yarnConfigHook
yarnBuildHook
yarnInstallHook
# Needed for executing package.json scripts
nodejs
npmHooks.npmInstallHook
];

meta = {
Expand All @@ -512,8 +513,6 @@ stdenv.mkDerivation (finalAttrs: {
})
```

Note that there is no setup hook for installing yarn based packages - `npmHooks.npmInstallHook` should fit most cases, but sometimes you may need to override the `installPhase` completely.

#### `yarnConfigHook` arguments {#javascript-yarnconfighook}

By 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`.
Expand All @@ -525,9 +524,15 @@ This script by default runs `yarn --offline build`, and it relies upon the proje
- `yarnBuildScript`: Sets a different `yarn --offline` subcommand (defaults to `build`).
- `yarnBuildFlags`: Single string list of additional flags to pass the above command, or a Nix list of such additional flags.

#### `yarnInstallHook` arguments {#javascript-yarninstallhook}

To 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:

- `yarnKeepDevDeps`: Disables the removal of devDependencies from `node_modules` before installation.

### yarn2nix {#javascript-yarn2nix}

WARNING: The `yarn2nix` functions have been deprecated in favor of the new `yarnConfigHook` and `yarnBuildHook`. 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).
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).

#### Preparation {#javascript-yarn2nix-preparation}

Expand Down
17 changes: 17 additions & 0 deletions pkgs/build-support/node/fetch-yarn-deps/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
stdenv,
lib,
makeWrapper,
installShellFiles,
nodejsInstallManuals,
nodejsInstallExecutables,
coreutils,
nix-prefetch-git,
fetchurl,
jq,
nodejs,
nodejs-slim,
prefetch-yarn-deps,
fixup-yarn-lock,
Expand Down Expand Up @@ -175,4 +180,16 @@ in
description = "Run yarn build in buildPhase";
};
} ./yarn-build-hook.sh;

yarnInstallHook = makeSetupHook {
name = "yarn-install-hook";
propagatedBuildInputs = [
yarn
nodejsInstallManuals
nodejsInstallExecutables
];
substitutions = {
jq = lib.getExe jq;
};
} ./yarn-install-hook.sh;
}
79 changes: 79 additions & 0 deletions pkgs/build-support/node/fetch-yarn-deps/yarn-install-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# shellcheck shell=bash

yarnInstallHook() {
echo "Executing yarnInstallHook"

runHook preInstall

local -r packageOut="$out/lib/node_modules/$(@jq@ --raw-output '.name' ./package.json)"
mkdir -p "$packageOut"

local -ar yarnArgs=(
--ignore-engines
--ignore-platform
--ignore-scripts
--no-progress
--non-interactive
--offline
)

local -r tmpDir="$(mktemp -d yarnInstallHook.XXXXXX)"

# yarn pack does not work at all with bundleDependencies.
# Since we are imediately unpacking, we can just remove them from package.json
# This will NOT be fixed in yarn v1: https://github.com/yarnpkg/yarn/issues/6794
mv ./package.json "$tmpDir/package.json.orig"
# Note: two spellings are accepted, 'bundleDependencies' and 'bundledDependencies'
@jq@ 'del(.bundleDependencies)|del(.bundledDependencies)' "$tmpDir/package.json.orig" > ./package.json

# TODO: figure out a way to avoid redundant compress/decompress steps
yarn pack \
--filename "$tmpDir/yarn-pack.tgz" \
"${yarnArgs[@]}"

tar xzf "$tmpDir/yarn-pack.tgz" \
-C "$packageOut" \
--strip-components 1 \
package/

mv "$tmpDir/package.json.orig" ./package.json

nodejsInstallExecutables ./package.json

nodejsInstallManuals ./package.json

local -r nodeModulesPath="$packageOut/node_modules"

if [ ! -d "$nodeModulesPath" ]; then
if [ -z "${yarnKeepDevDeps-}" ]; then
# Yarn has a 'prune' command, but it's only a stub that directs you to use install
if ! yarn install \
--frozen-lockfile \
--force \
--production=true \
"${yarnArgs[@]}"
then
echo
echo
echo "ERROR: yarn prune step failed"
echo
echo 'If yarn tried to download additional dependencies above, try setting `yarnKeepDevDeps = true`.'
echo

exit 1
fi
fi

find node_modules -maxdepth 1 -type d -empty -delete

cp -r node_modules "$nodeModulesPath"
fi

runHook postInstall

echo "Finished yarnInstallHook"
}

if [ -z "${dontYarnInstall-}" ] && [ -z "${installPhase-}" ]; then
doronbehar marked this conversation as resolved.
Show resolved Hide resolved
installPhase=yarnInstallHook
fi
Loading
Loading