基于 MoonBit 0.9 版本实现,本文系统说明 moon.mod、moon.pkg 和 moon.work 的职责、关系、区别、支持的配置项、兼容写法,以及常见错误与排查方式。本文以 moonbitlang/moon 仓库中的真实实现为依据,目标是给出一份面向实际使用、尽量与当前行为一致的中文参考说明。
Moon 当前涉及三类项目清单:
- 模块清单
moon.modmoon.mod.json
- 包清单
moon.pkgmoon.pkg.json
- 工作区清单
moon.work
它们对应三个不同层级:
| 文件 | 层级 | 作用 |
|---|---|---|
moon.mod / moon.mod.json | module | 描述模块身份、模块依赖、源码根目录、模块级默认配置 |
moon.pkg / moon.pkg.json | package | 描述单个包的导入、构建、测试、target 支持等 |
moon.work | workspace | 描述多个模块组成的工作区 |
最重要的区别是:
- module 是依赖解析单位
- package 是编译单位
- workspace 是多个 module 的组织单位
基本关系
module 与 package 的关系
一个 module 可以包含多个 package。
module 根目录由以下文件之一标识:
moon.modmoon.mod.json
package 目录由以下文件之一标识:
moon.pkgmoon.pkg.json
module 负责:
- 模块名与模块版本
- 模块级依赖
- 包扫描根目录(
source) - 模块级 target 默认值
- 发布元信息
package 负责:
- 当前包导入哪些包
- 当前包是否是入口包(
is-main) - 测试导入
- 条件编译
- pre-build
- package 级
supported-targets
workspace 与 module 的关系
workspace 用 moon.work 表示,用于把多个 module 组织在一起。
它不替代 module,而是建立在多个 module 之上。
常见布局如下:
repo/
moon.work
app/
moon.mod.json
src/
moon.pkg.json
lib/
moon.mod.json
src/
moon.pkg.json
这里:
repo/是 workspace 根app/和lib/是两个独立 module- 每个 module 各自有自己的 package 结构
moon.mod 与 moon.mod.json
共同职责
moon.mod 和 moon.mod.json 都表示模块清单。
它们用于描述:
nameversiondepsbin-depssourcepreferred-targetsupported-targets- 发布元信息
- 模块脚本
- 模块级规则
当前实现中的读取顺序
当前实现中,如果同一目录同时存在:
moon.modmoon.mod.json
则会优先读取 moon.mod。
如果没有 moon.mod,才会读取 moon.mod.json。
因此:
不要在同一个 module 目录下同时维护这两个文件。
两者的主要区别
moon.mod.json
这是完整 JSON 格式,字段最完整,最适合作为主配置格式。
moon.mod
这是 DSL 格式。
它并不是“可以随意替代 moon.mod.json 的完整自由写法”,当前实现中它只支持一部分顶层键,并且许多配置依赖兼容映射。
因此:
复杂模块配置推荐优先使用
moon.mod.json。
moon.mod.json 支持的主要字段
以下字段可以从当前实现中的 MoonModJSON 和 schema 直接确认。
必填字段
name
模块名,必填。
{
"name": "chenbimo/demo"
}
推荐使用两段式命名:
用户名/模块名
例如:
moonbitlang/corechenbimo/demo
常用字段
version
模块版本。
{
"name": "chenbimo/demo",
"version": "0.1.0"
}
按 semver 解析。
deps
模块依赖。
当前实现中,deps 支持以下几类值:
registry 简写
{
"deps": {
"moonbitlang/x": "0.1.0"
}
}
registry 对象写法
{
"deps": {
"moonbitlang/x": {
"version": "0.1.0"
}
}
}
本地路径依赖
{
"deps": {
"chenbimo/lib": {
"path": "../lib"
}
}
}
git 依赖
{
"deps": {
"chenbimo/lib": {
"git": "https://github.com/chenbimo/lib.git",
"branch": "main",
"version": "0.1.0"
}
}
}
就当前核对到的 schema 而言,git dependency 明确包含:
gitbranchversion至少在这份实现证据中,没有直接确认
tag/rev是 manifest 字段。
bin-deps
模块级二进制依赖。
{
"bin-deps": {
"moonbitlang/formatter": {
"version": "0.1.0",
"bin_pkg": ["moonbitlang/formatter"]
}
}
}
它与普通 deps 的区别是:
deps用于代码依赖bin-deps用于工具/可执行依赖
另外,bin-deps 只针对输入/root module 处理,不按普通依赖那样传递传播。
source
包扫描根目录。
{
"name": "chenbimo/demo",
"source": "src"
}
含义:
- Moon 从
src/开始递归寻找moon.pkg/moon.pkg.json - package 路径相对于
source计算 source本身不计入 package 的逻辑路径
如果不写,默认值等价于:
"."
当前实现还要求:
source不能是绝对路径source不能包含非法字符< > : " | ? *
preferred-target
模块级默认偏好 target。
{
"preferred-target": "wasm-gc"
}
当前可确认的合法值:
wasmwasm-gcjsnativellvm
它表示“默认偏好后端”,不表示“只允许这个后端”。
supported-targets
模块级支持的 target 集合。
{
"supported-targets": "js"
}
也兼容旧数组语法:
{
"supported-targets": ["js", "native"]
}
当前实现/文档明确支持的词项包括:
jswasmwasm-gcnativellvmall
推荐使用字符串表达式,例如:
"js""all-js""js+wasm-gc"
发布相关字段
以下字段在 schema 中明确存在:
descriptionlicensekeywordsrepositoryreadmeincludeexclude
示例:
{
"name": "chenbimo/demo",
"version": "0.1.0",
"description": "A demo MoonBit module",
"license": "Apache-2.0",
"repository": "https://github.com/chenbimo/demo",
"readme": "README.md",
"keywords": ["moonbit", "demo"]
}
scripts
模块脚本配置。
当前实现中,至少能明确确认一个被实际消费的脚本键:
postadd
例如:
{
"scripts": {
"postadd": "python3 tools/postadd.py"
}
}
rule
模块级规则。
{
"rule": [
{
"name": "gen",
"command": "python3 tools/gen.py"
}
]
}
约束:
rule.name不能重复
实验字段
当前实现中还存在实验字段:
--moonbit-unstable-prebuild
它是实验性能力,不应当视作稳定公共接口。
moon.mod(DSL)支持的内容
这一节是最需要注意的部分。
当前实现中允许的顶层键
moon.mod 当前实现接受的顶层键只有:
importoptionswarningsnameversionrulesupported_targets
这意味着:
不是所有
moon.mod.json字段都可以直接写在moon.mod顶层。
最适合用 moon.mod 的场景
moon.mod 更适合:
- 声明模块名
- 声明版本
- 声明少量 registry 依赖
- 写
supported_targets - 写
warnings - 写
rule
如果你需要更完整、更稳定的字段支持,建议直接使用:
moon.mod.json
moon.mod 中的 import
这是 moon.mod 中最重要、也最受限制的部分。
当前实现中:
moon.mod的import只支持带版本号的 registry dependency。
也就是说,它的语义必须是:
模块名@版本
例如:
moonbitlang/x@0.1.0
当前实现明确不支持:
- 本地路径依赖
- git 依赖
- 无版本 registry dependency
- 结构化 dependency object
因此,如果你需要写:
pathgit- 更复杂的 dependency object
请直接使用:
moon.mod.json
options
options 是 DSL 的兼容入口。
实现会把 options 中的对象内容并入最终模块 JSON。
因此,从实现机制上说,一些不能直接写在 moon.mod 顶层的字段,可能通过 options 间接表达,例如:
sourcedescriptionlicenserepositoryreadmekeywordsincludeexcludepreferred-targetscriptsdepsbin-deps
但是这里要强调:
这属于兼容路径,不是最推荐的主写法。
如果你的模块已经需要这些字段,通常更推荐改用:
moon.mod.json
warnings 与 warn-list
在 DSL 中写的是:
warnings
最终会映射到 JSON 字段:
warn-list
对应关系如下:
| DSL | JSON |
|---|---|
warnings | warn-list |
supported_targets 与 supported-targets
在 DSL 中写的是:
supported_targets
最终会映射到 JSON 字段:
supported-targets
对应关系如下:
| DSL | JSON |
|---|---|
supported_targets | supported-targets |
rule
rule 是 moon.mod 顶层原生支持的复杂字段之一,而且允许重复出现。
不过:
- 可以有多条
rule - 但
rule.name不能重复
关于 DSL 的具体标点语法
当前实现已经明确限制了:
- 允许哪些顶层键
import的语义限制options/warnings/supported_targets的兼容作用
但如果讨论到:
- 括号长什么样
- 对象字面量的具体写法
- 某个分隔符是否唯一正确
这类“DSL 外观”问题,在这次核对中没有拿到足够直接、完整的官方样例来给出唯一模板。
因此本文采取更保守的做法:
- 确认语义
- 不把某种具体标点形式写死成“唯一合法格式”
如果你追求最低歧义,仍然建议优先使用:
moon.mod.json
moon.pkg 与 moon.pkg.json
它们的职责
moon.pkg / moon.pkg.json 描述单个 package 的构建与导入行为。
常见职责包括:
- import 哪些 package
- 是否是入口包(
is-main) - whitebox / blackbox test import
- package 级
supported-targets pre-build- 条件编译
targets linknative-stubvirtualsub-packagewarn-list
package 与 module 的分工
module 级(moon.mod*)
负责:
- 模块名
- 模块版本
- 模块依赖
source- 发布信息
- 模块级默认 target / 支持 target
package 级(moon.pkg*)
负责:
- 当前包 import 谁
- 当前包是否是
is-main - 测试导入
- pre-build
- target 约束
- link / native-stub / virtual 等包级行为
moon.pkg.json 的常见字段
根据当前 schema,可确认的常见字段包括:
importwbtest-importtest-importtest-import-allis-mainsupported-targetspre-buildtargetslinknative-stubvirtualsub-packagewarn-listnameoverridesmax-concurrent-testsproof-enabledregex-backend
最小示例
{
"is-main": true
}
带导入的示例
{
"is-main": true,
"import": ["moonbitlang/x"]
}
表示:
- 这是一个 main package
- 它导入了
moonbitlang/x
package 级 supported-targets
package 也可以限制自己的 target 支持集合:
{
"supported-targets": "js"
}
如果 module 也定义了 supported-targets,实际效果是:
- package 支持集 ∩ module 支持集
pre-build
package 可以声明生成步骤,例如:
{
"pre-build": [
{
"input": ["assets/a.txt"],
"output": ["generated/a.mbt"],
"command": "tool"
}
]
}
moon.work
作用
moon.work 用于描述工作区。
它把多个 module 放在一起,使部分命令可以在工作区范围内运行。
它不负责 package 细节,也不替代 module manifest。
当前实现明确支持的字段
当前可以明确确认 moon.work 支持:
memberspreferred_target
示例:
members = ["./app", "./lib"]
preferred_target = "wasm-gc"
members
members 列出当前工作区包含的 module 路径。
这些路径相对于 workspace 根目录解释。
preferred_target
工作区级默认 target。
当 module 本身没有设置 preferred-target 时,workspace 的 preferred_target 可以作为默认后备。
三者如何协同工作
单模块项目
单模块项目通常只需要:
- 一个
moon.mod.json - 若干个
moon.pkg.json
多模块仓库
多模块仓库通常是:
- 每个 module 各自维护自己的
moon.mod.json - 仓库根维护一个
moon.work
哪些命令是 workspace 级?
当前实现中,以下命令可以在 workspace 范围内运行:
moon buildmoon checkmoon testmoon fmtmoon info
哪些命令更偏 module 级?
以下命令更偏向针对单个 module:
moon addmoon removemoon treemoon packagemoon publishmoon docmoon prove
即使在 workspace 下,它们通常也需要一个明确的目标 module。
推荐写法与兼容写法
文件格式层面
推荐
moon.mod.jsonmoon.pkg.jsonmoon.work
兼容
moon.modmoon.pkg
字段名层面
| 推荐/标准字段 | DSL/兼容字段 |
|---|---|
supported-targets | supported_targets |
warn-list | warnings |
options
options 是 DSL 兼容入口。
它能工作,但不是最推荐的主配置方式。
只要你已经依赖 options 写较多复杂字段,通常就意味着更适合改用:
moon.mod.json
关于 moon.mod 中的依赖写法
这是最关键的一条:
moon.mod的import只支持带版本号的 registry dependency。
如果你需要:
- path dependency
- git dependency
- 结构化 dependency object
请直接用:
moon.mod.json
常见错误与排查
以下错误或错误类型可以直接从当前实现中确认。
moon.mod 顶层键不允许
现象
在 moon.mod 顶层写了不支持的键,例如直接写某些 JSON 字段。
典型报错
Unexpected key '...' found in moon.mod.
说明
当前实现中,moon.mod 顶层只接受:
importoptionswarningsnameversionrulesupported_targets
处理建议
- 简单字段保留在 DSL 顶层
- 复杂字段改用
moon.mod.json
moon.mod 顶层重复键
典型报错
Duplicate key '...' found in moon.mod.
说明
除了 rule 以外,moon.mod 顶层不允许重复键。
rule 名字重复
典型报错
Duplicate rule name '...' found in moon.mod.
处理建议
确保每条 rule.name 唯一。
moon.mod 的 import 写了不受支持的依赖
典型报错
moon.mod only supports versioned registry dependencies in import, found '...'moon.mod does not support local dependency '...' in import; use workspace configuration in moon.work insteadmoon.mod only supports registry dependencies in import, found structured dependency '...'
说明
moon.mod 的 import 只支持:
模块名@版本
处理建议
- path / git / 复杂依赖 → 改用
moon.mod.json
source 非法
典型报错类型
source should not contain invalid chars ...source not a subdirectory of the parent directory
说明
当前实现要求:
source不能是绝对路径- 不能包含非法字符
< > : " | ? *
处理建议
- 使用相对路径
- 推荐写法如:
"src"、"packages"、"."
name 为空
典型报错
`name` should not be empty
处理建议
确保 module manifest 中始终有合法的 name。
preferred-target 非法
典型报错类型
`preferred-backend` is not a valid backend
当前可确认的合法值
wasmwasm-gcjsnativellvm
supported-targets 格式错误
典型报错类型
`supported_targets` bad format
处理建议
确认值符合当前支持语法,例如:
"js""all-js"["js", "native"]
并优先使用字符串表达式。
推荐实践
新项目推荐方案
单模块项目
推荐使用:
moon.mod.jsonmoon.pkg.json
多模块仓库
推荐使用:
- 每个 module 使用
moon.mod.json - 仓库根使用
moon.work
什么时候可以继续用 moon.mod?
当你的 module 配置非常简单,例如只需要:
nameversion- 少量简单 registry 依赖
supported_targetswarningsrule
这时可以使用 moon.mod。
什么时候建议直接改用 moon.mod.json?
只要你需要以下任意一个功能,就建议改用 moon.mod.json:
source- path dependency
- git dependency
bin-depsscripts- 发布元信息
preferred-target- 更稳定、更清晰的模块配置方式
最小示例
单模块项目
moon.mod.json
{
"name": "chenbimo/demo",
"version": "0.1.0",
"source": "src"
}
src/moon.pkg.json
{
"is-main": true
}
带依赖的模块
moon.mod.json
{
"name": "chenbimo/demo",
"version": "0.1.0",
"source": "src",
"deps": {
"moonbitlang/x": "0.1.0"
},
"preferred-target": "wasm-gc",
"supported-targets": "all"
}
src/moon.pkg.json
{
"is-main": true,
"import": ["moonbitlang/x"]
}
多模块工作区
moon.work
members = ["./app", "./lib"]
preferred_target = "wasm-gc"
app/moon.mod.json
{
"name": "chenbimo/app",
"version": "0.1.0",
"source": "src",
"deps": {
"chenbimo/lib": {
"path": "../lib"
}
}
}
lib/moon.mod.json
{
"name": "chenbimo/lib",
"version": "0.1.0",
"source": "src"
}
结论
如果只记住最核心的内容,可以记住下面四点:
moon.mod*管 modulemoon.pkg*管 packagemoon.work管 workspace- 复杂配置优先用 JSON manifest
更具体一点:
moon.mod是 DSL/兼容路径,可用于简单场景moon.mod.json是更完整、更稳定的模块清单格式moon.mod中的import只支持带版本号的 registry dependencymoon.work当前只负责组织多个 module,并提供工作区级默认 target
如果你希望获得:
- 最稳定的行为
- 最清晰的字段语义
- 最少的兼容映射困扰
推荐采用:
moon.mod.json+moon.pkg.json+moon.work
速查表
| 文件 | 层级 | 主要职责 | 推荐程度 |
|---|---|---|---|
moon.mod | module | DSL 模块清单,适合简单场景 | 兼容可用 |
moon.mod.json | module | 完整模块清单 | 推荐 |
moon.pkg | package | DSL 包清单 | 兼容可用 |
moon.pkg.json | package | 完整包清单 | 推荐 |
moon.work | workspace | 工作区清单 | 推荐 |