mirror of
https://github.com/ryan4yin/nixos-and-flakes-book.git
synced 2025-06-22 13:01:25 +02:00
feat: nix develop
This commit is contained in:
parent
e1c0e3d815
commit
8598bb3361
@ -121,21 +121,13 @@ Here is a `flake.nix` that defines a development environment with Node.js 18 ins
|
|||||||
devShells."${system}".default = let
|
devShells."${system}".default = let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
|
||||||
(self: super: rec {
|
|
||||||
nodejs = super.nodejs-18_x;
|
|
||||||
pnpm = super.nodePackages.pnpm;
|
|
||||||
yarn = (super.yarn.override { inherit nodejs; });
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
in pkgs.mkShell {
|
in pkgs.mkShell {
|
||||||
# create an environment with nodejs-18_x, pnpm, and yarn
|
# create an environment with nodejs_18, pnpm, and yarn
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
node2nix
|
nodejs_18
|
||||||
nodejs
|
nodePackages.pnpm
|
||||||
pnpm
|
(yarn.override { nodejs = nodejs_18; })
|
||||||
yarn
|
|
||||||
];
|
];
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
@ -172,21 +164,13 @@ Here is an example:
|
|||||||
devShells."${system}".default = let
|
devShells."${system}".default = let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
|
||||||
(self: super: rec {
|
|
||||||
nodejs = super.nodejs-18_x;
|
|
||||||
pnpm = super.nodePackages.pnpm;
|
|
||||||
yarn = (super.yarn.override { inherit nodejs; });
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
in pkgs.mkShell {
|
in pkgs.mkShell {
|
||||||
# create an environment with nodejs-18_x, pnpm, and yarn
|
# create an environment with nodejs_18, pnpm, and yarn
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
node2nix
|
nodejs_18
|
||||||
nodejs
|
nodePackages.pnpm
|
||||||
pnpm
|
(yarn.override { nodejs = nodejs_18; })
|
||||||
yarn
|
|
||||||
nushell
|
nushell
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -228,16 +212,10 @@ Example:
|
|||||||
packages."${system}".dev = let
|
packages."${system}".dev = let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
|
||||||
(self: super: rec {
|
|
||||||
nodejs = super.nodejs_20;
|
|
||||||
pnpm = super.nodePackages.pnpm;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
nodejs
|
nodejs_20
|
||||||
pnpm
|
nodePackages.pnpm
|
||||||
nushell
|
nushell
|
||||||
];
|
];
|
||||||
in pkgs.runCommand "dev-shell" {
|
in pkgs.runCommand "dev-shell" {
|
||||||
@ -256,6 +234,37 @@ Example:
|
|||||||
|
|
||||||
Then execute `nix run .#dev`, you will enter a nushell session, where you can use the `node` `pnpm` command normally, and the node version is 20.
|
Then execute `nix run .#dev`, you will enter a nushell session, where you can use the `node` `pnpm` command normally, and the node version is 20.
|
||||||
|
|
||||||
|
The wrapper generated in this way is an executable file, which does not actually depend on the `nix run` or `nix shell` command.
|
||||||
|
|
||||||
|
For example, we can directly install this wrapper through NixOS's `environment.systemPackages`, and then execute it directly:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{pkgs, lib, ...}{
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
# Install the wrapper into the system
|
||||||
|
(let
|
||||||
|
packages = with pkgs; [
|
||||||
|
nodejs_20
|
||||||
|
nodePackages.pnpm
|
||||||
|
nushell
|
||||||
|
];
|
||||||
|
in pkgs.runCommand "dev-shell" {
|
||||||
|
# Dependencies that should exist in the runtime environment
|
||||||
|
buildInputs = packages;
|
||||||
|
# Dependencies that should only exist in the build environment
|
||||||
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/bin/
|
||||||
|
ln -s ${pkgs.nushell}/bin/nu $out/bin/dev-shell
|
||||||
|
wrapProgram $out/bin/dev-shell --prefix PATH : ${pkgs.lib.makeBinPath packages}
|
||||||
|
'';)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the above configuration to any NixOS Module, then deploy it with `sudo nixos-rebuild switch`, and you can enter the development environment directly with the `dev-shell` command, which is the special feature of `pkgs.runCommand` compared to `pkgs.mkShell`.
|
||||||
|
|
||||||
Related source code:
|
Related source code:
|
||||||
|
|
||||||
- [pkgs/build-support/trivial-builders/default.nix - runCommand](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/pkgs/build-support/trivial-builders/default.nix#L21-L49)
|
- [pkgs/build-support/trivial-builders/default.nix - runCommand](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/pkgs/build-support/trivial-builders/default.nix#L21-L49)
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
在本章中我们先学习一下 Nix Flakes 开发环境的实现原理,后面的章节再按使用场景介绍一些更具体的内容。
|
在本章中我们先学习一下 Nix Flakes 开发环境的实现原理,后面的章节再按使用场景介绍一些更具体的内容。
|
||||||
|
|
||||||
|
|
||||||
## 通过 `nix shell` 创建开发环境
|
## 通过 `nix shell` 创建开发环境
|
||||||
|
|
||||||
在 NixOS 上,最简单的创建开发环境的方法是使用 `nix shell`,它会创建一个含有指定 Nix 包的 shell 环境。
|
在 NixOS 上,最简单的创建开发环境的方法是使用 `nix shell`,它会创建一个含有指定 Nix 包的 shell 环境。
|
||||||
@ -127,21 +126,13 @@ stdenv.mkDerivation ({
|
|||||||
devShells."${system}".default = let
|
devShells."${system}".default = let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
|
||||||
(self: super: rec {
|
|
||||||
nodejs = super.nodejs-18_x;
|
|
||||||
pnpm = super.nodePackages.pnpm;
|
|
||||||
yarn = (super.yarn.override { inherit nodejs; });
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
in pkgs.mkShell {
|
in pkgs.mkShell {
|
||||||
# create an environment with nodejs-18_x, pnpm, and yarn
|
# create an environment with nodejs-18_x, pnpm, and yarn
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
node2nix
|
nodejs_18
|
||||||
nodejs
|
nodePackages.pnpm
|
||||||
pnpm
|
(yarn.override { nodejs = nodejs_18; })
|
||||||
yarn
|
|
||||||
];
|
];
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
@ -154,7 +145,6 @@ stdenv.mkDerivation ({
|
|||||||
|
|
||||||
建个空文件夹,将上面的配置保存为 `flake.nix`,然后执行 `nix develop`(或者更精确点,可以用 `nix develop .#default`),首先会打印出当前 nodejs 的版本,之后 `node` `pnpm` `yarn` 等命令就都能正常使用了。
|
建个空文件夹,将上面的配置保存为 `flake.nix`,然后执行 `nix develop`(或者更精确点,可以用 `nix develop .#default`),首先会打印出当前 nodejs 的版本,之后 `node` `pnpm` `yarn` 等命令就都能正常使用了。
|
||||||
|
|
||||||
|
|
||||||
## 在开发环境中使用 zsh/fish 等其他 shell
|
## 在开发环境中使用 zsh/fish 等其他 shell
|
||||||
|
|
||||||
`pkgs.mkShell` 默认使用 `bash`,但是你也可以通过在 `shellHook` 中添加 `exec <your-shell>` 来使用 `zsh` 或者 `fish` 等其他 shell。
|
`pkgs.mkShell` 默认使用 `bash`,但是你也可以通过在 `shellHook` 中添加 `exec <your-shell>` 来使用 `zsh` 或者 `fish` 等其他 shell。
|
||||||
@ -177,21 +167,13 @@ stdenv.mkDerivation ({
|
|||||||
devShells."${system}".default = let
|
devShells."${system}".default = let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
|
||||||
(self: super: rec {
|
|
||||||
nodejs = super.nodejs-18_x;
|
|
||||||
pnpm = super.nodePackages.pnpm;
|
|
||||||
yarn = (super.yarn.override { inherit nodejs; });
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
in pkgs.mkShell {
|
in pkgs.mkShell {
|
||||||
# create an environment with nodejs-18_x, pnpm, and yarn
|
# create an environment with nodejs_18, pnpm, and yarn
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
node2nix
|
nodejs_18
|
||||||
nodejs
|
nodePackages.pnpm
|
||||||
pnpm
|
(yarn.override { nodejs = nodejs_18; })
|
||||||
yarn
|
|
||||||
nushell
|
nushell
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -232,16 +214,10 @@ stdenv.mkDerivation ({
|
|||||||
packages."${system}".dev = let
|
packages."${system}".dev = let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
|
||||||
(self: super: rec {
|
|
||||||
nodejs = super.nodejs_20;
|
|
||||||
pnpm = super.nodePackages.pnpm;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
nodejs
|
nodejs_20
|
||||||
pnpm
|
nodePackages.pnpm
|
||||||
nushell
|
nushell
|
||||||
];
|
];
|
||||||
in pkgs.runCommand "dev-shell" {
|
in pkgs.runCommand "dev-shell" {
|
||||||
@ -258,14 +234,42 @@ stdenv.mkDerivation ({
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
然后执行 `nix run .#dev`,就能进入一个 nushell session,可以在其中正常使用 `node` `pnpm` 命令,且 node 版本为 20.
|
然后执行 `nix run .#dev`,就能进入一个 nushell session,可以在其中正常使用 `node` `pnpm` 命令.
|
||||||
|
|
||||||
|
这种方式生成的 wrapper 是一个可执行文件,它实际不依赖 `nix run` 命令,比如说我们可以直接通过 NixOS 的 `environment.systemPackages` 来安装这个 wrapper,然后直接执行它:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{pkgs, lib, ...}{
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
# 将 dev-shell 安装到系统环境中
|
||||||
|
(let
|
||||||
|
packages = with pkgs; [
|
||||||
|
nodejs_20
|
||||||
|
nodePackages.pnpm
|
||||||
|
nushell
|
||||||
|
];
|
||||||
|
in pkgs.runCommand "dev-shell" {
|
||||||
|
# Dependencies that should exist in the runtime environment
|
||||||
|
buildInputs = packages;
|
||||||
|
# Dependencies that should only exist in the build environment
|
||||||
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
} ''
|
||||||
|
mkdir -p $out/bin/
|
||||||
|
ln -s ${pkgs.nushell}/bin/nu $out/bin/dev-shell
|
||||||
|
wrapProgram $out/bin/dev-shell --prefix PATH : ${pkgs.lib.makeBinPath packages}
|
||||||
|
'';)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
将上述配置添加到任一 NixOS Module 中,再通过 `sudo nixos-rebuild switch` 部署后,就能直接通过 `dev-shell` 命令进入到该开发环境,这就是 `pkgs.runCommand` 相比 `pkgs.mkShell` 的特别之处。
|
||||||
|
|
||||||
相关源代码:
|
相关源代码:
|
||||||
|
|
||||||
- [pkgs/build-support/trivial-builders/default.nix - runCommand](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/pkgs/build-support/trivial-builders/default.nix#L21-L49)
|
- [pkgs/build-support/trivial-builders/default.nix - runCommand](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/pkgs/build-support/trivial-builders/default.nix#L21-L49)
|
||||||
- [pkgs/build-support/setup-hooks/make-wrapper.sh](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/pkgs/build-support/setup-hooks/make-wrapper.sh)
|
- [pkgs/build-support/setup-hooks/make-wrapper.sh](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/pkgs/build-support/setup-hooks/make-wrapper.sh)
|
||||||
|
|
||||||
|
|
||||||
## 进入任何 Nix 包的构建环境
|
## 进入任何 Nix 包的构建环境
|
||||||
|
|
||||||
现在再来看看 `nix develop`,先读下 `nix develop --help` 输出的帮助文档:
|
现在再来看看 `nix develop`,先读下 `nix develop --help` 输出的帮助文档:
|
||||||
@ -435,7 +439,6 @@ nix build "nixpkgs#ponysay"
|
|||||||
|
|
||||||
其他还有些 `nix flake init` 之类的命令,请自行查阅 [New Nix Commands][New Nix Commands] 学习研究,这里就不详细介绍了。
|
其他还有些 `nix flake init` 之类的命令,请自行查阅 [New Nix Commands][New Nix Commands] 学习研究,这里就不详细介绍了。
|
||||||
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [pkgs.mkShell - nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell)
|
- [pkgs.mkShell - nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user