- 开发工具
- CLI
【免费下载链接】devenv
Fast, Declarative, Reproducible, and Composable Developer Environments using Nix
导读
Gleam 是一门运行在 Erlang 虚拟机(BEAM)之上的强类型函数式语言。在 devenv 项目中,通过languages.gleam模块,你可以在 Nix 声明式环境中一键获得完整、可复现的 Gleam 开发工具链。本文基于 Gleam 语言文档 与 模块实现,系统讲解该模块的两个核心配置项languages.gleam.enable与languages.gleam.package的用法、默认值与底层行为,并给出可直接复制运行的完整示例。
模块概览:一个选项组,两个配置项
devenv 将每种语言的支持封装为languages.<name>.*形式的选项。Gleam 模块位于 src/modules/languages/gleam.nix,对外暴露两个选项:
| 选项 | 类型 | 默认值 | 作用 |
|---|---|---|---|
languages.gleam.enable | boolean | false | 是否启用 Gleam 开发工具 |
languages.gleam.package | package | pkgs.gleam | 指定要使用的 Gleam 包(可覆盖为指定版本) |
这两个选项是本文的核心,下面逐一展开。
开启 Gleam 支持:languages.gleam.enable
languages.gleam.enable是一个布尔开关,用于控制是否将 Gleam 开发工具纳入当前 devenv 环境。
- 类型:
boolean - 默认值:
false - 示例值:
true
从源码实现看(src/modules/languages/gleam.nix#L18-L24),当enable = true时,模块会执行两件事:
config = lib.mkIf cfg.enable { languages.erlang.enable = true; packages = [ cfg.package ]; };- 自动启用 Erlang 支持(
languages.erlang.enable = true):Gleam 编译产物运行在 BEAM 虚拟机上,需要 Erlang/OTP 运行时才能执行,因此模块会隐式拉起 Erlang 环境,保证gleam run产出的字节码可以直接运行。 - 把
cfg.package加入packages:即把选定的 Gleam 包安装进 shell,使gleam、gleam build、gleam test、gleam format等命令直接可用。
如果你在 devenv 之外还单独配置了languages.erlang.enable,两者并不冲突,模块层面的叠加是幂等的。
选择 Gleam 版本:languages.gleam.package
languages.gleam.package用于指定环境内安装的 Gleam 包来源。
- 类型:
package - 默认值**:
pkgs.gleam(即当前 nixpkgs 快照中的 Gleam 版本)
源码中的定义(src/modules/languages/gleam.nix#L10-L15):
package = lib.mkOption { type = lib.types.package; default = pkgs.gleam; description = "The Gleam package to use."; defaultText = lib.literalExpression "pkgs.gleam"; };为什么需要覆盖 package?三个常见场景:
- 锁定版本:默认跟随 nixpkgs,想固定到特定 Gleam 版本(例如项目要求 1.x 的某个小版本)时,可以从 nixpkgs 或其他源取指定版本;
- 使用自定义构建:例如带特殊编译选项或补丁的本地 Gleam 构建产物;
- 统一工具链版本:让 CI 与本地 shell 使用完全一致的 Gleam 版本,保证可复现性。
覆盖示例(将 Gleam 替换为自定义包):
{ pkgs, ... }: { languages.gleam.enable = true; languages.gleam.package = pkgs.gleam.overrideAttrs (old: { # 例如:打上本地补丁或调整构建参数 patches = (old.patches or []) ++ [ ./gleam-custom.patch ]; }); }需要注意的是,覆盖package不会关闭 Erlang 依赖的自动启用——只要enable = true,Erlang 运行时依然会被带上。
完整可运行示例
仓库的 examples/gleam 目录提供了一个最小可运行示例,直接说明了实际用法。
devenv.nix:
{ pkgs, ... }: { # https://devenv.sh/languages/ languages.gleam.enable = true; enterShell = '' gleam --version ''; # See full reference at https://devenv.sh/reference/options/ }配套的 devenv.yaml 声明了输入源:
inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable使用方法(在包含上述两个文件的目录下):
devenv shell # 进入带 gleam 的开发者 shell gleam --version # 验证 Gleam 已就绪 gleam new my_app # 初始化新项目 cd my_app && gleam runenterShell会在每次进入环境时打印gleam --version,用于即时确认工具链生效。由于 Erlang 被自动启用,gleam run启动 BEAM 进程时不会再提示缺少运行时。
底层实现要点:为什么开启 Gleam 必须同时开启 Erlang
结合 devenv-core 的模块求值流程,languages.*各模块的config最终会被合并进顶层选项再求值。Gleam 模块的关键设计在于lib.mkIf cfg.enable条件块内部直接声明languages.erlang.enable = true,这是一种"语言依赖语言"的模块间联动——从源码结构看,它保证了 BEAM 运行时与 Gleam 编译器永远同时出现,省去了用户手动配置 Erlang 的步骤,也避免了两者版本不匹配导致的运行时错误。
对比同目录下的 Erlang 模块(src/modules/languages/erlang.nix),可以看到 Erlang 模块会额外处理rebar3的编译版本对齐问题;而 Gleam 模块保持极简,仅声明包本身,其余依赖交由 Erlang 模块负责。
小结
| 你想做的事 | 配置写法 |
|---|---|
| 启用 Gleam 工具链 | languages.gleam.enable = true; |
| 使用指定版本的 Gleam | languages.gleam.package = <某个 package 表达式>; |
| 同时获得可运行的 BEAM 环境 | 无需额外配置,enable = true自动完成 |
只需记住一个开关和一个包选项,你就能在 devenv 中得到完整、可复现、跨机器一致的 Gleam 开发环境。更多语言模块的同类用法,可参考 supported-languages 示例 与 语言配置总览(如存在);若需查看该模块的全部选项定义,可阅读 模块源码。
- 开发工具
- CLI
【免费下载链接】devenv
Fast, Declarative, Reproducible, and Composable Developer Environments using Nix
相关推荐
5步构建医疗信息化系统:OpenEMR开源电子病历实战指南
5步构建医疗信息化系统:OpenEMR开源电子病历实战指南 OpenEMR作为全球最受欢迎的开源电子健康记录系统,为医疗机构提供了完整的企业级医疗信息管理解决方
开发工具CLIdevenv 中配置 Lean 4 开发环境:languages.lean4 模块详解
devenv 中配置 Lean 4 开发环境:languages.lean4 模块详解 本指南介绍如何在 Nix 驱动的开发者环境 devenv 中启用 Lea
开发工具CLIgrpc-gateway 怎么给 runtime.ServeMux 添加自定义 HTTP 路由?
grpc gateway 怎么给 runtime.ServeMux 添加自定义 HTTP 路由? 当你基于 grpc gateway 搭建网关后,某些 HTTP
开发工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考