mirror of
https://github.com/ryan4yin/nixos-and-flakes-book
synced 2024-11-23 12:43:08 +00:00
feat: nix develop
This commit is contained in:
parent
e1c0e3d815
commit
8598bb3361
2 changed files with 102 additions and 90 deletions
|
@ -121,21 +121,13 @@ Here is a `flake.nix` that defines a development environment with Node.js 18 ins
|
|||
devShells."${system}".default = let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(self: super: rec {
|
||||
nodejs = super.nodejs-18_x;
|
||||
pnpm = super.nodePackages.pnpm;
|
||||
yarn = (super.yarn.override { inherit nodejs; });
|
||||
})
|
||||
];
|
||||
};
|
||||
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; [
|
||||
node2nix
|
||||
nodejs
|
||||
pnpm
|
||||
yarn
|
||||
nodejs_18
|
||||
nodePackages.pnpm
|
||||
(yarn.override { nodejs = nodejs_18; })
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
|
@ -172,21 +164,13 @@ Here is an example:
|
|||
devShells."${system}".default = let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(self: super: rec {
|
||||
nodejs = super.nodejs-18_x;
|
||||
pnpm = super.nodePackages.pnpm;
|
||||
yarn = (super.yarn.override { inherit nodejs; });
|
||||
})
|
||||
];
|
||||
};
|
||||
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; [
|
||||
node2nix
|
||||
nodejs
|
||||
pnpm
|
||||
yarn
|
||||
nodejs_18
|
||||
nodePackages.pnpm
|
||||
(yarn.override { nodejs = nodejs_18; })
|
||||
nushell
|
||||
];
|
||||
|
||||
|
@ -228,16 +212,10 @@ Example:
|
|||
packages."${system}".dev = let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(self: super: rec {
|
||||
nodejs = super.nodejs_20;
|
||||
pnpm = super.nodePackages.pnpm;
|
||||
})
|
||||
];
|
||||
};
|
||||
packages = with pkgs; [
|
||||
nodejs
|
||||
pnpm
|
||||
nodejs_20
|
||||
nodePackages.pnpm
|
||||
nushell
|
||||
];
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
- [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 shell` 创建开发环境
|
||||
|
||||
在 NixOS 上,最简单的创建开发环境的方法是使用 `nix shell`,它会创建一个含有指定 Nix 包的 shell 环境。
|
||||
|
@ -127,21 +126,13 @@ stdenv.mkDerivation ({
|
|||
devShells."${system}".default = let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(self: super: rec {
|
||||
nodejs = super.nodejs-18_x;
|
||||
pnpm = super.nodePackages.pnpm;
|
||||
yarn = (super.yarn.override { inherit nodejs; });
|
||||
})
|
||||
];
|
||||
};
|
||||
in pkgs.mkShell {
|
||||
# create an environment with nodejs-18_x, pnpm, and yarn
|
||||
packages = with pkgs; [
|
||||
node2nix
|
||||
nodejs
|
||||
pnpm
|
||||
yarn
|
||||
nodejs_18
|
||||
nodePackages.pnpm
|
||||
(yarn.override { nodejs = nodejs_18; })
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
|
@ -154,7 +145,6 @@ stdenv.mkDerivation ({
|
|||
|
||||
建个空文件夹,将上面的配置保存为 `flake.nix`,然后执行 `nix develop`(或者更精确点,可以用 `nix develop .#default`),首先会打印出当前 nodejs 的版本,之后 `node` `pnpm` `yarn` 等命令就都能正常使用了。
|
||||
|
||||
|
||||
## 在开发环境中使用 zsh/fish 等其他 shell
|
||||
|
||||
`pkgs.mkShell` 默认使用 `bash`,但是你也可以通过在 `shellHook` 中添加 `exec <your-shell>` 来使用 `zsh` 或者 `fish` 等其他 shell。
|
||||
|
@ -177,21 +167,13 @@ stdenv.mkDerivation ({
|
|||
devShells."${system}".default = let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(self: super: rec {
|
||||
nodejs = super.nodejs-18_x;
|
||||
pnpm = super.nodePackages.pnpm;
|
||||
yarn = (super.yarn.override { inherit nodejs; });
|
||||
})
|
||||
];
|
||||
};
|
||||
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; [
|
||||
node2nix
|
||||
nodejs
|
||||
pnpm
|
||||
yarn
|
||||
nodejs_18
|
||||
nodePackages.pnpm
|
||||
(yarn.override { nodejs = nodejs_18; })
|
||||
nushell
|
||||
];
|
||||
|
||||
|
@ -232,16 +214,10 @@ stdenv.mkDerivation ({
|
|||
packages."${system}".dev = let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(self: super: rec {
|
||||
nodejs = super.nodejs_20;
|
||||
pnpm = super.nodePackages.pnpm;
|
||||
})
|
||||
];
|
||||
};
|
||||
packages = with pkgs; [
|
||||
nodejs
|
||||
pnpm
|
||||
nodejs_20
|
||||
nodePackages.pnpm
|
||||
nushell
|
||||
];
|
||||
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/setup-hooks/make-wrapper.sh](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/pkgs/build-support/setup-hooks/make-wrapper.sh)
|
||||
|
||||
|
||||
## 进入任何 Nix 包的构建环境
|
||||
|
||||
现在再来看看 `nix develop`,先读下 `nix develop --help` 输出的帮助文档:
|
||||
|
@ -405,37 +409,36 @@ Hello, world!
|
|||
nix build "nixpkgs#ponysay"
|
||||
# 使用构建出来的 ponysay 命令
|
||||
› ./result/bin/ponysay 'hey buddy!'
|
||||
____________
|
||||
____________
|
||||
< hey buddy! >
|
||||
------------
|
||||
\
|
||||
\
|
||||
\
|
||||
▄▄ ▄▄ ▄ ▄
|
||||
▀▄▄▄█▄▄▄▄▄█▄▄▄
|
||||
▀▄███▄▄██▄██▄▄██
|
||||
▄██▄███▄▄██▄▄▄█▄██
|
||||
█▄█▄██▄█████████▄██
|
||||
▄▄█▄█▄▄▄▄▄████████
|
||||
▀▀▀▄█▄█▄█▄▄▄▄▄█████ ▄ ▄
|
||||
▀▄████▄▄▄█▄█▄▄██ ▄▄▄▄▄█▄▄▄
|
||||
█▄██▄▄▄▄███▄▄▄██ ▄▄▄▄▄▄▄▄▄█▄▄
|
||||
▀▄▄██████▄▄▄████ █████████████
|
||||
▀▀▀▀▀█████▄▄ ▄▄▄▄▄▄▄▄▄▄██▄█▄▄▀
|
||||
██▄███▄▄▄▄█▄▄▀ ███▄█▄▄▄█▀
|
||||
█▄██▄▄▄▄▄████ ███████▄██
|
||||
█▄███▄▄█████ ▀███▄█████▄
|
||||
██████▀▄▄▄█▄█ █▄██▄▄█▄█▄
|
||||
███████ ███████ ▀████▄████
|
||||
------------
|
||||
\
|
||||
\
|
||||
\
|
||||
▄▄ ▄▄ ▄ ▄
|
||||
▀▄▄▄█▄▄▄▄▄█▄▄▄
|
||||
▀▄███▄▄██▄██▄▄██
|
||||
▄██▄███▄▄██▄▄▄█▄██
|
||||
█▄█▄██▄█████████▄██
|
||||
▄▄█▄█▄▄▄▄▄████████
|
||||
▀▀▀▄█▄█▄█▄▄▄▄▄█████ ▄ ▄
|
||||
▀▄████▄▄▄█▄█▄▄██ ▄▄▄▄▄█▄▄▄
|
||||
█▄██▄▄▄▄███▄▄▄██ ▄▄▄▄▄▄▄▄▄█▄▄
|
||||
▀▄▄██████▄▄▄████ █████████████
|
||||
▀▀▀▀▀█████▄▄ ▄▄▄▄▄▄▄▄▄▄██▄█▄▄▀
|
||||
██▄███▄▄▄▄█▄▄▀ ███▄█▄▄▄█▀
|
||||
█▄██▄▄▄▄▄████ ███████▄██
|
||||
█▄███▄▄█████ ▀███▄█████▄
|
||||
██████▀▄▄▄█▄█ █▄██▄▄█▄█▄
|
||||
███████ ███████ ▀████▄████
|
||||
▀▀█▄▄▄▀ ▀▀█▄▄▄▀ ▀██▄▄██▀█
|
||||
▀ ▀▀█
|
||||
▀ ▀▀█
|
||||
```
|
||||
|
||||
## 其他命令
|
||||
|
||||
其他还有些 `nix flake init` 之类的命令,请自行查阅 [New Nix Commands][New Nix Commands] 学习研究,这里就不详细介绍了。
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [pkgs.mkShell - nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell)
|
||||
|
|
Loading…
Reference in a new issue