下个时代的开发工具-Nix:声明式的运行环境构建器、简单场景下的docker替身

个人的一点拙见 : 声明式范式会成为以后软件工程靠近应用侧主要的开发方式。比较典型的包括Docker,算是一个老前辈,晚一点在介绍。先来一个比较基础的,Nix

在开发的过程中,相信小伙伴们肯定用到一些环境管理的工具,用于维护某个工具的不同版本。当然也可以通过环境变量配置,但切换总是挺麻烦的。例如nvm管理不同的nodejs,miniconda管理不同的python版本,但切换过程中还是挺繁琐的,甚至遇到一些问题,在以前的文章nvm不可用报错`GLIBC_2.27‘‘GLIBCXX_3.4.20‘not Found?+ 使用docker构建多个前端项目实践就介绍了一种情况,以及推荐用docker来解决,但docker也存在一定问题-就是需要虚拟化环境支持,在某些场景下可能就不适用了。

1. 简介

Nix 是一个独特的包管理工具和构建系统,它采用了一种声明式的方法来管理软件包和运行环境。与传统的包管理器(如 aptyumbrew 等)不同,Nix 提供了一种以函数式编程理念为基础的机制,通过精确控制依赖关系和环境配置,确保软件的可重复性、隔离性和可追溯性。

什么是声明式运行环境?

声明式运行环境的核心思想是:用户描述“是什么”而不是“如何实现”。用户只需要定义软件环境的期望状态,Nix 会自动处理如何实现这一状态。这种方式与传统的命令式操作不同,后者要求用户逐步指定每个步骤。

2. Nix 的特点

2.1 声明式配置

Nix 使用声明式配置文件(如 configuration.nixshell.nix)定义系统或项目环境。通过这个文件,用户可以描述需要的软件包、依赖和设置。Nix 会解析并自动创建与配置相符的环境。这样可以极大减少配置出错的风险。

2.2 软件环境隔离

Nix 使用独立的构建环境,确保每个软件包及其依赖的隔离性。每个软件包安装在一个唯一的目录下(通常是 /nix/store),不会相互干扰。这种隔离避免了传统包管理器常见的“依赖地狱”(dependency hell)问题,即不同软件包对同一依赖库的版本冲突问题。

2.3 可重复性和可再现性

Nix 保证了构建过程的可重复性,即同样的配置和依赖会始终生成相同的结果。对于开发者来说,无论是搭建本地开发环境,还是在 CI 系统中进行部署测试,都可以确保在不同机器上生成一致的结果。

2.4 回滚与历史追踪

Nix 支持环境的版本控制功能,允许用户轻松回滚到以前的配置。无论是单个软件包的更新出错,还是系统配置有问题,用户都可以快速恢复到之前的版本。

2.5 多用户安全支持

Nix 设计为多用户友好,每个用户可以独立管理自己的环境,而不干扰系统或其他用户。它确保了每个用户的权限隔离,不必担心用户安装的软件包会影响到全局环境。

3. Nix 的核心优势

Nix 工具的设计和理念解决了传统包管理器的一些核心问题,尤其在复杂开发环境中的一些痛点:

3.1 依赖管理

传统包管理器有时会导致依赖冲突或版本不一致的情况。Nix 的唯一性和隔离机制确保了不同版本的依赖库可以共存,避免了依赖冲突。

3.2 可重复性构建

现代软件开发常常依赖于特定版本的工具链和依赖。Nix 提供了一种稳定的、可再现的构建环境,特别适合对环境要求苛刻的项目,如科研、数据分析或大型应用的持续集成系统。

3.3 灵活性

Nix 支持 Linux、macOS,甚至 Windows(通过 WSL),因此它适用于不同操作系统的开发人员。此外,它支持在多个项目中创建不同的隔离开发环境,使得同一台机器上能够并行开发多个具有不同依赖的项目。

4. 安装与使用

4.1 Nix 安装

在 Linux 和 macOS 上安装 Nix 非常简单。只需运行以下命令:

curl -L https://nixos.org/nix/install | sh

该命令会自动下载并安装 Nix,并将必要的环境变量配置到用户的 shell 中。安装完成后,可以通过重启终端来激活 Nix。

4.2 初始化开发环境

安装完成后,可以通过 nix-shell 来创建和使用隔离的开发环境。我们通过创建一个 shell.nix 文件来定义环境配置:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = [
    pkgs.git
    pkgs.nodejs
  ];
}

在该文件中,定义了两个依赖:gitnodejs。使用 nix-shell 进入环境:

nix-shell

此时,用户的 shell 环境将会包含指定的依赖工具,无需在系统全局安装。

4.3 管理软件包

Nix 可以轻松安装软件包,类似于其他包管理器的工作方式。例如,安装 vim

nix-env -iA nixpkgs.vim

其中 -iA 参数表示直接从 Nix 软件包仓库中安装特定的包。

要查看当前安装的软件包列表,可以使用:

nix-env -q

4.4 升级和回滚

Nix 允许随时升级环境中的软件包:

nix-env --upgrade

如果升级后环境出现问题,可以使用回滚命令恢复到之前的版本:

nix-env --rollback

4.5 使用 NixOS 系统

除了 Nix 包管理器,Nix 还拥有一个基于 Nix 工具的操作系统——NixOS。这是一个完全声明式的 Linux 发行版,用户可以通过配置文件精确描述操作系统的各个组件和服务。

5. Nix 与 NVM、Pyenv、Miniconda 的对比

在开发过程中,很多开发者会使用工具来管理特定编程语言的版本和依赖,如 nvm 用于 Node.js、pyenvminiconda 用于 Python。Nix 虽然是一个通用的包管理器,但在管理多语言开发环境时也具备类似功能。下面,我们对比一下 Nix 与这些工具的异同。

5.1 Nix 与 NVM(Node.js 版本管理)

相同点
  • 版本管理nvm 专注于管理不同版本的 Node.js,而 Nix 也可以通过声明式配置来指定需要的 Node.js 版本。两者都允许用户为不同项目指定不同的 Node.js 版本,从而避免版本冲突。
  • 隔离环境nvm 为每个 Node.js 版本提供了隔离的环境,用户可以在不同项目中使用不同版本的 Node.js,Nix 也具备同样的能力,可以通过 nix-shell 为每个项目创建独立的开发环境。
不同点
  • 通用性nvm 仅用于 Node.js 的版本管理,而 Nix 是通用的包管理器,除了 Node.js,Nix 还能管理各种其他编程语言及其依赖,甚至操作系统级别的工具和库。
  • 声明式 vs 命令式nvm 的配置是命令式的,用户需要手动执行命令来安装和切换 Node.js 版本。而 Nix 采用声明式配置文件(如 shell.nix),用户只需定义所需的 Node.js 版本,Nix 会自动处理其安装和依赖。

5.2 Nix 与 Pyenv、Miniconda(Python 版本管理)

Pyenv 对比
相同点
  • Python 版本管理pyenv 允许用户安装和切换多个 Python 版本。Nix 同样可以管理 Python 及其版本,通过 nix-shell 可以轻松为每个项目提供指定版本的 Python 环境。
  • 隔离环境pyenv 通过虚拟环境(如 pyenv-virtualenv 插件)提供 Python 依赖的隔离。Nix 提供类似的功能,在每个 nix-shell 会话中隔离不同项目的依赖,避免 Python 包冲突。
不同点
  • 通用性pyenv 只能管理 Python 版本,而 Nix 是通用的包管理器,可以同时管理多种语言及其依赖。
  • 声明式配置pyenv 的版本管理需要手动切换,而 Nix 通过声明式文件(如 shell.nix)定义 Python 版本和依赖,提供更自动化的方式,并且无需手动操作即可确保环境一致性。
  • 系统依赖管理pyenv 只关注 Python 语言本身,而 Nix 可以同时管理 Python 及其依赖的系统库(如 C/C++ 库)。
Miniconda 对比
相同点
  • 虚拟环境与依赖管理miniconda 和 Nix 都可以为不同项目创建独立的虚拟环境,安装特定版本的 Python 及依赖包。两者都可以为每个项目创建隔离的运行环境,确保环境的干净和一致性。
  • 跨平台支持miniconda 和 Nix 都支持在不同平台(如 Linux、macOS)上运行,并能跨平台管理软件包和环境。
不同点
  • 包管理模型miniconda 使用的是 conda 包管理系统,而 Nix 使用自己独特的 nixpkgs 仓库。conda 偏向于数据科学和科学计算,提供了很多专门为 Python 用户优化的库。Nix 则是通用的包管理器,涵盖了广泛的软件包和语言工具。
  • 声明式 vs 命令式minicondaconda 的使用是命令式的,用户需要手动创建环境并安装软件包。而 Nix 提供声明式的方式,可以通过配置文件完整定义项目的依赖和环境,使其更加易于自动化和复现。
  • 系统依赖的处理:与 Nix 一样,conda 也能处理某些系统级依赖,但是 Nix 在此方面更加灵活和广泛,支持几乎所有操作系统层面的库和工具。

5.3 总结对比

工具支持语言包管理方式环境隔离声明式配置回滚与版本控制系统依赖管理
Nix多语言声明式
NVMNode.js命令式
PyenvPython命令式是(插件)
MinicondaPython命令式部分支持

从上表可以看出,Nix 的核心优势在于它的通用性声明式配置。无论是对多语言开发环境的支持,还是对于依赖包和系统库的全面管理,Nix 提供了比专用语言管理器(如 nvmpyenv)更加广泛的功能。同时,Nix 的声明式模型确保了环境的一致性和可再现性,使其在复杂项目中具备独特的优势。

5. 结语

Nix 是一个功能强大且灵活的包管理器,它通过声明式的配置、隔离环境和版本控制等功能,为开发者提供了极大的便利和灵活性。无论是在单独管理软件包,还是为项目创建隔离开发环境,Nix 都提供了一种可重复、可靠且高效的解决方案。对于那些希望彻底摆脱依赖地狱和环境不一致问题的开发者,Nix 无疑是一个值得深入研究和使用的工具。

Nix算是docker的另一个简单化选择,当然它也可以通过docker安装和使用。声明式对于前段应该不陌生,那就是HTML,它就是一个声明式的界面定义,由浏览器根据它渲染,每次刷新都保持了很好的一致性。而这种一致性、可复现、易阅读将来肯定会取代很多编程工作,只需要描述一个清晰的需求,具体的实现让runtime去实现 - 满足这个需求即可,而不要教他一步步该怎么做-出了异常怎么恢复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余生H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值