如何將 /etc/nixos/configuration.nix 拆分為單獨的模組?
假設我有一個非常簡單的NixOS 配置文件:
{ config, pkgs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ]; # SOME STUFF environment.systemPackages = with pkgs; [ emacs gitFull ]; # SOME STUFF }
我知道 NixOS 實現了一個模組系統,一個模組就是一個
.nix
文件。每個.nix
文件都應該包含任何有效的Nix 表達式(例如函式或集合)。這意味著 NixOS 配置文件/etc/nixos/configuration.nix
本身就是一個模組,包含一個 Nix 表達式。我也知道要使另一個模組中的 Nix 表達式對我正在使用的模組可見,我可以使用內置
import
函式。我想將系統包的聲明(包含
emacs
and的列表gitFull
)拆分為 filepackages.nix
。如何將 NixOS 配置文件拆分為單獨的模組?
尼克斯表達式
Nix 表達式就像任何程式語言表達式:任何計算結果為值或函式的東西。在這種情況下,值也可以是列表或集合。由於 Nix 模組(副檔名為 的文件
.nix
)可以包含任何 Nix 表達式,您會期望 NixOS 配置文件 (/etc/nixos/configuration.nix
) 包含單個 Nix 表達式作為其文件內容。NixOS 配置文件包含以下形式的 Nix 表達式:
{config, pkgs, ...}: { /* various configuration options */ }
如果你仔細看,你會發現它是一個函式,因為函式遵循形式
pattern: form
。您還可以看到它是一個接受集合併返回集合的函式。例如,如果你有一個 functionf = {x, y}: {a = x + y;}
,那麼你可以呼叫它 asf {x=1; y=2;}
並取回一個 set{a=3;}
。所以這意味著當你呼叫時
nixos-rebuild switch
,一些東西會呼叫 NixOS 配置文件中的函式,其中的集合必須包含屬性config
和pkgs
.進口
在 的範例中
./hardware-configuration.nix
,將包列表提取到單獨的模組中的簡單方法packages.nix
是將environment.systemPackages
選項取出並放入./packages.nix
選項imports
中。你/etc/nixos/configuration.nix
會看起來像:{ config, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix # Include the package list. ./packages.nix ]; # SOME STUFF # SOME STUFF }
你
/etc/nixos/packages.nix
會看起來像:{ pkgs, ... }: { environment.systemPackages = with pkgs; [ emacs gitFull ]; }
這是如何運作的?當您執行
nixos-rebuild switch
時,評估 Nix 表達式並決定安裝包等的過程會呼叫configuration.nix
一組屬性,其中一些屬性是config
和pkgs
。它在返回的集合中找到屬性
imports
,因此它評估模組中imports
包含相同參數(config
、、pkgs
等)的每個 Nix 表達式。你必須有
pkgs
一個函式的參數(或者,從技術上講,一個集合的屬性,它本身就是一個參數)packages.nix
,因為從 Nix 語言的角度來看,該過程可能會或可能不會使用集合呼叫函式包含pkgs
. 如果沒有,您在執行時會引用什麼屬性with pkgs
?您還必須有省略號,因為該函式可能會使用其他屬性呼叫,而不僅僅是
pkgs
.
pkgs
為什麼裡面沒有configuration.nix
?你可以擁有它,但如果你不在文件中的任何地方引用它,你可以放心地省略它,因為省略號無論如何都會包含它們。通過呼叫外部函式更新屬性
另一種方法是創建一個函式,該函式返回具有某個屬性的集合,以及您將放入的該屬性的值
environment.systemPackages
。這是你的configuration.nix
:{ config, pkgs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ]; # SOME STUFF environment.systemPackages = import ./packages.nix pkgs; # SOME STUFF }
你的
packages.nix
:pkgs: with pkgs; [ emacs gitFull ]
import ./packages.nix pkgs
意思是:載入並返回 Nix 表達式./packages.nix
,因為它是一個函式,所以用一個參數呼叫它pkgs
。with pkgs; [ emacs gitFull ]
是一個with-expression,它將分號之前的表達式的範圍帶到分號之後的表達式。沒有它,它會是[ pkgs.emacs pkgs.gitFull ]
。