如何在MacOS的Nix Home-Manager中规范设置自定义软件包版本?
在Home-Manager中自定义Nix软件包版本的惯用方法
你的实现是否正确?
你当前通过导入特定rev的nixpkgs来获取对应版本pnpm的方法是有效的,但存在可优化的点:
- 完整导入整个nixpkgs实例会额外增加构建时间和缓存开销
- 独立的nixpkgs实例可能和主配置中
pkgs的依赖环境不一致,存在潜在兼容性问题
更优雅的替代方案
方案1:直接覆盖pnpm的版本属性
如果仅需特定版本的pnpm,无需导入整个nixpkgs,直接通过overrideAttrs修改现有pnpm包的版本和源码即可:
{ config, pkgs, ... }: let pnpm94 = pkgs.pnpm.overrideAttrs (oldAttrs: rec { version = "9.4.0"; src = pkgs.fetchFromGitHub { owner = "pnpm"; repo = "pnpm"; rev = "v${version}"; # 哈希值可通过`nix-prefetch-github pnpm pnpm --rev v9.4.0`获取 sha256 = "0000000000000000000000000000000000000000000000000000"; }; }); in { home.packages = [ pnpm94 # 其他软件包 ]; }
方案2:从特定nixpkgs rev中单独导入pnpm定义
如果依赖nixpkgs中特定rev的pnpm构建逻辑,可只导入pnpm的包定义文件,而非整个nixpkgs,减少不必要开销:
{ config, pkgs, ... }: let nixpkgsRev = pkgs.fetchFromGitHub { owner = "NixOS"; repo = "nixpkgs"; rev = "c3392ad349a5227f4a3464dce87bcc5046692fce"; sha256 = "1klhr7mrfhrzcqfzngk268jspikbivkxg96x2wncjv1ik3zb8i75"; }; # 复用主pkgs的依赖环境,仅导入pnpm的包定义 pnpm94 = pkgs.callPackage "${nixpkgsRev}/pkgs/tools/package-management/pnpm" {}; in { home.packages = [ pnpm94 # 其他软件包 ]; }
方案3:使用nixpkgs.pin(适用于多包版本锁定)
如果需要锁定多个软件包的版本,推荐用nixpkgs.pin管理特定版本的nixpkgs实例,同时复用主pkgs的系统配置:
{ config, pkgs, ... }: let pinnedNixpkgs = pkgs.nixpkgs.pin { rev = "c3392ad349a5227f4a3464dce87bcc5046692fce"; sha256 = "1klhr7mrfhrzcqfzngk268jspikbivkxg96x2wncjv1ik3zb8i75"; }; pnpm94 = pinnedNixpkgs.packages.${pkgs.system}.pnpm; in { home.packages = [ pnpm94 # 其他软件包 ]; }
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

