Home Explore Blog CI



nixpkgs

8th chunk of `doc/languages-frameworks/javascript.section.md`
aa15def1c1705610e3e34048984fc58080b0a59145e197b20000000100000fe9
NOTE: It is highly recommended to use a pinned version of pnpm (i.e. `pnpm_8` or `pnpm_9`), to increase future reproducibility. It might also be required to use an older version, if the package needs support for a certain lock file version.

In case you are patching `package.json` or `pnpm-lock.yaml`, make sure to pass `finalAttrs.patches` to the function as well (i.e. `inherit (finalAttrs) patches`.

`pnpm.configHook` supports adding additional `pnpm install` flags via `pnpmInstallFlags` which can be set to a Nix string array:

```nix
{
  pnpm,
}:

stdenv.mkDerivation (finalAttrs: {
  pname = "foo";
  version = "0-unstable-1980-01-01";

  src = {
    # ...
  };

  pnpmInstallFlags = [ "--shamefully-hoist" ];

  pnpmDeps = pnpm.fetchDeps {
    inherit (finalAttrs) pnpmInstallFlags;
  };
})
```

#### Dealing with `sourceRoot` {#javascript-pnpm-sourceRoot}

If the pnpm project is in a subdirectory, you can just define `sourceRoot` or `setSourceRoot` for `fetchDeps`.
If `sourceRoot` is different between the parent derivation and `fetchDeps`, you will have to set `pnpmRoot` to effectively be the same location as it is in `fetchDeps`.

Assuming the following directory structure, we can define `sourceRoot` and `pnpmRoot` as follows:

```
.
├── frontend
│   ├── ...
│   ├── package.json
│   └── pnpm-lock.yaml
└── ...
```

```nix
{
  # ...
  pnpmDeps = pnpm.fetchDeps {
    # ...
    sourceRoot = "${finalAttrs.src.name}/frontend";
  };

  # by default the working directory is the extracted source
  pnpmRoot = "frontend";
}
```

#### PNPM Workspaces {#javascript-pnpm-workspaces}

If you need to use a PNPM workspace for your project, then set `pnpmWorkspaces = [ "<workspace project name 1>" "<workspace project name 2>" ]`, etc, in your `pnpm.fetchDeps` call,
which will make PNPM only install dependencies for those workspace packages.

For example:

```nix
{
  # ...
  pnpmWorkspaces = [ "@astrojs/language-server" ];
  pnpmDeps = pnpm.fetchDeps {
    inherit (finalAttrs) pnpmWorkspaces;
    #...
  };
}
```

The above would make `pnpm.fetchDeps` call only install dependencies for the `@astrojs/language-server` workspace package.
Note that you do not need to set `sourceRoot` to make this work.

Usually in such cases, you'd want to use `pnpm --filter=<pnpm workspace name> build` to build your project, as `npmHooks.npmBuildHook` probably won't work. A `buildPhase` based on the following example will probably fit most workspace projects:

```nix
{
  buildPhase = ''
    runHook preBuild

    pnpm --filter=@astrojs/language-server build

    runHook postBuild
  '';
}
```

#### Additional PNPM Commands and settings {#javascript-pnpm-extraCommands}

If you require setting an additional PNPM configuration setting (such as `dedupe-peer-dependents` or similar),
set `prePnpmInstall` to the right commands to run. For example:

```nix
{
  prePnpmInstall = ''
    pnpm config set dedupe-peer-dependants false
  '';
  pnpmDeps = pnpm.fetchDeps {
    inherit (finalAttrs) prePnpmInstall;
    # ...
  };
}
```

In this example, `prePnpmInstall` will be run by both `pnpm.configHook` and by the `pnpm.fetchDeps` builder.


### Yarn {#javascript-yarn}

Yarn based projects use a `yarn.lock` file instead of a `package-lock.json` to pin dependencies.

To package yarn-based applications, you need to distinguish by the version pointers in the `yarn.lock` file. See the following sections.

#### Yarn v1 {#javascript-yarn-v1}

Yarn v1 lockfiles contain a comment `# yarn lockfile v1` at the beginning of the file.

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:

- `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`.

Title: PNPM Configuration and Commands, Yarn v1
Summary
This section delves further into PNPM, detailing how to handle subdirectories with `sourceRoot` and `pnpmRoot`, and how to use PNPM workspaces with `pnpmWorkspaces` for installing dependencies for specific workspace packages, including a build example using `pnpm --filter`. It also explains the `prePnpmInstall` setting for adding additional PNPM configuration commands. The section then transitions to Yarn v1, explaining the use of `fetchYarnDeps`, `yarnConfigHook`, `yarnBuildHook`, and `yarnInstallHook` for managing dependencies and building Yarn v1 projects.