fetchPnpmDeps,pnpmConfigHook: move to top-level attribute
move pnpm.{fetchDeps,configHook} to fetchPnpmDeps and pnpmConfigHook
respectively. Also adds aliases to the former package-level attributes.
Additionally, pnpmConfigHook does not propagate pnpm anymore, to make
changing pnpm versions easier.
This brings pnpm in line with the other Node.js/JavaScript tooling in
nixpkgs.
This doesn't cause any rebuilds.
Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
This commit is contained in:
@@ -327,16 +327,17 @@ See `node2nix` [docs](https://github.com/svanderburg/node2nix) for more info.
|
||||
|
||||
### pnpm {#javascript-pnpm}
|
||||
|
||||
Pnpm is available as the top-level package `pnpm`. Additionally, there are variants pinned to certain major versions, like `pnpm_8` and `pnpm_9`, which support different sets of lock file versions.
|
||||
pnpm is available as the top-level package `pnpm`. Additionally, there are variants pinned to certain major versions, like `pnpm_8`, `pnpm_9` and `pnpm_10`, which support different sets of lock file versions.
|
||||
|
||||
When packaging an application that includes a `pnpm-lock.yaml`, you need to fetch the pnpm store for that project using a fixed-output-derivation. The functions `pnpm_8.fetchDeps` and `pnpm_9.fetchDeps` can create this pnpm store derivation. In conjunction, the setup hooks `pnpm_8.configHook` and `pnpm_9.configHook` will prepare the build environment to install the pre-fetched dependencies store. Here is an example for a package that contains `package.json` and a `pnpm-lock.yaml` files using the above `pnpm_` attributes:
|
||||
When packaging an application that includes a `pnpm-lock.yaml`, you need to fetch the pnpm store for that project using a fixed-output-derivation. The function `fetchPnpmDeps` can create this pnpm store derivation. In conjunction, the setup hook `pnpmConfigHook` will prepare the build environment to install the pre-fetched dependencies store. Here is an example for a package that contains `package.json` and a `pnpm-lock.yaml` files using the fetcher and setup hook above:
|
||||
|
||||
```nix
|
||||
{
|
||||
stdenv,
|
||||
fetchPnpmDeps,
|
||||
nodejs,
|
||||
# This is pinned as { pnpm = pnpm_9; }
|
||||
pnpm,
|
||||
pnpmConfigHook,
|
||||
stdenv,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
@@ -348,11 +349,12 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
nodejs
|
||||
pnpm.configHook
|
||||
nodejs # in case scripts are run outside of a pnpm call
|
||||
pnpmConfigHook
|
||||
pnpm # At least required by pnpmConfigHook, if not other (custom) phases
|
||||
];
|
||||
|
||||
pnpmDeps = pnpm.fetchDeps {
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
inherit (finalAttrs) pname version src;
|
||||
fetcherVersion = 3;
|
||||
hash = "...";
|
||||
@@ -360,33 +362,68 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
})
|
||||
```
|
||||
|
||||
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.
|
||||
It is highly recommended to use a pinned version of pnpm (i.e., `pnpm_9` or `pnpm_10`), 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. To do so, you can pass the `pnpm` argument to `fetchPnpmDeps` and override the `pnpm` arg in `pnpmConfigHook`. Here are the changes in the example above to use a pinned pnpm version:
|
||||
|
||||
<!-- TODO: Does splicing still work when overriding in nativeBuildInputs here? -->
|
||||
|
||||
```diff
|
||||
{
|
||||
fetchPnpmDeps,
|
||||
nodejs,
|
||||
- pnpm,
|
||||
+ pnpm_10,
|
||||
pnpmConfigHook,
|
||||
stdenv,
|
||||
}:
|
||||
+let
|
||||
+ # Optionally override pnpm to use a custom nodejs version
|
||||
+ # Make sure that the same nodejs version is referenced in nativeBuildInputs
|
||||
+ # pnpm = pnpm_10.override { nodejs = nodejs_20; };
|
||||
+in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "foo";
|
||||
version = "0-unstable-1980-01-01";
|
||||
|
||||
src = {
|
||||
#...
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
nodejs # in case scripts are run outside of a pnpm call
|
||||
pnpmConfigHook
|
||||
- pnpm # At least required by pnpmConfigHook, if not other (custom) phases
|
||||
+ pnpm_10 # At least required by pnpmConfigHook, if not other (custom) phases
|
||||
];
|
||||
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
inherit (finalAttrs) pname version src;
|
||||
+ pnpm = pnpm_10;
|
||||
fetcherVersion = 3;
|
||||
hash = "...";
|
||||
};
|
||||
})
|
||||
```
|
||||
|
||||
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:
|
||||
`pnpmConfigHook` 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 = {
|
||||
{
|
||||
# ...
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
# ...
|
||||
inherit (finalAttrs) pnpmInstallFlags;
|
||||
};
|
||||
|
||||
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`.
|
||||
If the pnpm project is in a subdirectory, you can just define `sourceRoot` or `setSourceRoot` for `fetchPnpmDeps`.
|
||||
If `sourceRoot` is different between the parent derivation and `fetchPnpmDeps`, you will have to set `pnpmRoot` to effectively be the same location as it is in `fetchPnpmDeps`.
|
||||
|
||||
Assuming the following directory structure, we can define `sourceRoot` and `pnpmRoot` as follows:
|
||||
|
||||
@@ -402,7 +439,7 @@ Assuming the following directory structure, we can define `sourceRoot` and `pnpm
|
||||
```nix
|
||||
{
|
||||
# ...
|
||||
pnpmDeps = pnpm.fetchDeps {
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
# ...
|
||||
sourceRoot = "${finalAttrs.src.name}/frontend";
|
||||
};
|
||||
@@ -414,7 +451,7 @@ Assuming the following directory structure, we can define `sourceRoot` and `pnpm
|
||||
|
||||
#### 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,
|
||||
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 `fetchPnpmDeps` call,
|
||||
which will make PNPM only install dependencies for those workspace packages.
|
||||
|
||||
For example:
|
||||
@@ -423,14 +460,14 @@ For example:
|
||||
{
|
||||
# ...
|
||||
pnpmWorkspaces = [ "@astrojs/language-server" ];
|
||||
pnpmDeps = pnpm.fetchDeps {
|
||||
inherit (finalAttrs) pnpmWorkspaces;
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
#...
|
||||
inherit (finalAttrs) pnpmWorkspaces;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The above would make `pnpm.fetchDeps` call only install dependencies for the `@astrojs/language-server` workspace package.
|
||||
The above would make `fetchPnpmDeps` 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:
|
||||
@@ -457,23 +494,23 @@ set `prePnpmInstall` to the right commands to run. For example:
|
||||
prePnpmInstall = ''
|
||||
pnpm config set dedupe-peer-dependents false
|
||||
'';
|
||||
pnpmDeps = pnpm.fetchDeps {
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
inherit (finalAttrs) prePnpmInstall;
|
||||
# ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
In this example, `prePnpmInstall` will be run by both `pnpm.configHook` and by the `pnpm.fetchDeps` builder.
|
||||
In this example, `prePnpmInstall` will be run by both `pnpmConfigHook` and by the `fetchPnpmDeps` builder.
|
||||
|
||||
#### PNPM `fetcherVersion` {#javascript-pnpm-fetcherVersion}
|
||||
#### pnpm `fetcherVersion` {#javascript-pnpm-fetcherVersion}
|
||||
|
||||
This is the version of the output of `pnpm.fetchDeps`, if you haven't set it already, you can use `1` with your current hash:
|
||||
This is the version of the output of `fetchPnpmDeps`, if you haven't set it already, you can use `1` with your current hash:
|
||||
|
||||
```nix
|
||||
{
|
||||
# ...
|
||||
pnpmDeps = pnpm.fetchDeps {
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
# ...
|
||||
fetcherVersion = 1;
|
||||
hash = "..."; # you can use your already set hash here
|
||||
@@ -486,7 +523,7 @@ After upgrading to a newer `fetcherVersion`, you need to regenerate the hash:
|
||||
```nix
|
||||
{
|
||||
# ...
|
||||
pnpmDeps = pnpm.fetchDeps {
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
# ...
|
||||
fetcherVersion = 2;
|
||||
hash = "..."; # clear this hash and generate a new one
|
||||
@@ -494,7 +531,7 @@ After upgrading to a newer `fetcherVersion`, you need to regenerate the hash:
|
||||
}
|
||||
```
|
||||
|
||||
This variable ensures that we can make changes to the output of `pnpm.fetchDeps` without breaking existing hashes.
|
||||
This variable ensures that we can make changes to the output of `fetchPnpmDeps` without breaking existing hashes.
|
||||
Changes can include workarounds or bug fixes to existing PNPM issues.
|
||||
|
||||
##### Version history {#javascript-pnpm-fetcherVersion-versionHistory}
|
||||
|
||||
Reference in New Issue
Block a user