You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Stack中package.yaml与stack.yaml的差异及支持情况的技术问询

我来帮你理清楚package.yaml(hpack格式)和stack.yaml之间的核心差异,这俩确实因为文档零散容易搞混:

核心定位差异

这是最本质的区别:

  • package.yaml是包描述文件,属于hpack生态,用来替代传统的.cabal文件,专门描述单个Haskell包的元数据与构建规则。
  • stack.yaml是构建工具配置文件,是Stack构建工具本身的顶层配置,和hpack无关——哪怕你不用hpack,直接写.cabal文件,也必须有stack.yaml来告诉Stack怎么构建你的项目。
功能与职责划分

package.yaml的职责

它只关心单个包的“内在属性”:

  • 包的基础信息:名称、版本、作者、许可证、描述
  • 依赖管理:声明该包依赖的其他Haskell包(比如base, text)
  • 模块配置:自动生成/手动指定暴露给外部的模块(exposed-modules)、内部模块(other-modules)
  • 编译与构建规则:指定GHC编译选项、语言扩展、组件配置(比如库、可执行文件、测试套件、基准测试)

stack.yaml的职责

它管的是整个项目的“构建环境”与执行规则:

  • 指定GHC版本:通过resolver字段选择Stack快照(比如resolver: lts-20.10),快照会固定所有依赖包的版本
  • 包源配置:添加额外的Hackage镜像或本地包路径
  • 多包项目管理:列出项目包含的所有本地包(比如packages: [., ./sub-package])
  • Stack工具的全局/项目级设置:比如是否开启Docker构建、缓存策略、编译器选项的全局覆盖
语法与特性差异
  • package.yaml基于YAML语法,并且带有hpack专属的便利特性:
    • 自动扫描生成exposed-modules和other-modules列表,不用手动逐个添加模块
    • 支持YAML的锚点(&)与别名(*),减少重复配置(比如统一管理版本号)
    • 支持变量插值与简单逻辑,比如用${version}引用包版本
    • 语法比传统.cabal的DSL更简洁易读
  • stack.yaml虽然也是YAML格式,但它的语法是Stack工具专属的配置规范,没有hpack的这些便利特性,所有配置项都是Stack定义的固定字段,用来控制构建流程。
Stack中的协作方式

当你在Stack项目中使用package.yaml时:

  1. 编写package.yaml后,Stack会自动将其转换成标准的.cabal文件(你可以在项目目录看到生成的.cabal文件)
  2. Stack实际构建时,会读取stack.yaml的配置来确定构建环境,再结合生成的.cabal文件来构建包
  3. 如果是多包项目,每个子包可以有自己的package.yaml,而stack.yaml在根目录统一管理整个项目的构建环境

总结一下:package.yaml聚焦“包是什么”,用hpack的特性简化包描述;stack.yaml聚焦“怎么构建包”,是Stack控制构建流程的核心配置。

内容的提问来源于stack exchange,提问作者hnefatl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 02:28:03