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).
##### Preparation {#javascript-yarn2nix-preparation}
You 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.
If the downloaded files contain the `package.json` and `yarn.lock` files they can be used like this:
```nix
{
offlineCache = fetchYarnDeps {
yarnLock = src + "/yarn.lock";
hash = "....";
};
}
```
##### mkYarnPackage {#javascript-yarn2nix-mkYarnPackage}
`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.
It's important to use the `--offline` flag. For example if you script is `"build": "something"` in `package.json` use:
```nix
{
nativeBuildInputs = [
writableTmpDirAsHomeHook
];
buildPhase = ''
runHook preBuild
yarn --offline build
runHook postBuild
'';
}
```
The `distPhase` is packing the package's dependencies in a tarball using `yarn pack`. You can disable it using:
```nix
{
doDist = false;
}
```
The configure phase can sometimes fail because it makes many assumptions which may not always apply. One common override is:
```nix
{
configurePhase = ''
runHook preConfigure
ln -s $node_modules node_modules
runHook postConfigure
'';
}
```
or if you need a writeable node_modules directory:
```nix
{
configurePhase = ''
runHook preConfigure
cp -r $node_modules node_modules
chmod +w node_modules
runHook postConfigure
'';
}
```
##### mkYarnModules {#javascript-yarn2nix-mkYarnModules}
This will generate a derivation including the `node_modules` directory.
If you have to build a derivation for an integrated web framework (rails, phoenix..), this is probably the easiest way.
#### Overriding dependency behavior {#javascript-mkYarnPackage-overriding-dependencies}
In the `mkYarnPackage` record the property `pkgConfig` can be used to override packages when you encounter problems building.
For instance, say your package is throwing errors when trying to invoke node-sass:
```
ENOENT: no such file or directory, scandir '/build/source/node_modules/node-sass/vendor'
```
To fix this we will specify different versions of build inputs to use, as well as some post install steps to get the software built the way we want:
```nix
mkYarnPackage rec {
pkgConfig = {
node-sass = {
buildInputs = with final; [
python
libsass
pkg-config
];
postInstall = ''
LIBSASS_EXT=auto yarn --offline run build
rm build/config.gypi
'';
};
};
}
```
##### Pitfalls {#javascript-yarn2nix-pitfalls}
- 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)
- Having trouble with `node-gyp`? Try adding these lines to the `yarnPreBuild` steps:
```nix
{
yarnPreBuild = ''
mkdir -p $HOME/.node-gyp/${nodejs.version}
echo 9 > $HOME/.node-gyp/${nodejs.version}/installVersion
ln -sfv ${nodejs}/include $HOME/.node-gyp/${nodejs.version}
export npm_config_nodedir=${nodejs}
'';
}
```
- The `echo 9` steps comes from this answer: <https://stackoverflow.com/a/49139496>
- Exporting the headers in `npm_config_nodedir` comes from this issue: <https://github.com/nodejs/node-gyp/issues/1191#issuecomment-301243919>
- `offlineCache` (described [above](#javascript-yarn2nix-preparation)) must be specified to avoid [Import From Derivation](#ssec-import-from-derivation) (IFD) when used inside Nixpkgs.