模块配置#
moon 使用模块文件来标识和描述一个模块。旧格式为 moon.mod.json,新格式为 moon.mod。完整的 JSON 模式请查看 moon 的仓库。
对 moon.mod.json 的支持已弃用。新项目应优先使用 moon.mod,并通过 moon fmt 迁移现有 JSON 文件。
moon.mod 的完整语法如下:
moon_mod ::= statement*
statement ::= import | assign | apply
import ::= "import" "{" (import_item ",")* import_item? "}" import_kind?
import_item ::= STRING
assign ::= LIDENT "=" expr
apply ::= LIDENT "(" (argument ",")* argument? ")"
argument ::= LIDENT ":" expr | STRING ":" expr
expr ::= array | object | apply | STRING | INT | "true" | "false"
array ::= "[" (expr ",")* expr? "]"
object ::= "{" (field ",")* field? "}"
名称#
name 字段用于指定模块的名称,它是必需的。
name = "user/example"
{
"name": "user/example"
// ...
}
模块名称可以包含字母、数字、_、- 和 /。
对于发布到 mooncakes.io 的模块,模块名称必须以用户名开头。
版本#
version 字段用于指定模块的版本。
此字段是可选的。对于发布到 mooncakes.io 的模块,版本号必须遵循 语义化版本 2.0.0 规范。
version = "0.1.0"
{
"version": "0.1.0"
}
依赖管理#
模块依赖通过 moon.mod 中的 import 声明。遗留的 moon.mod.json 格式则使用 deps 字段表示相同信息。
它由 moon add 和 moon remove 等命令自动管理。
name = "username/hello"
import {
"moonbitlang/x@0.4.6"
}
{
"name": "username/hello",
"deps": {
"moonbitlang/x": "0.4.6"
}
}
你也可以为模块使用本地依赖。
对于新的 moon.mod 格式,本地依赖配置已被弃用。推荐的本地依赖使用方式是在 moon.work 中配置。
例如,如果你使用 moon.work 管理 user/module1 和 user/module2:
// in moon.work
members = [
"source/to/module1",
"source/to/module2",
]
并且 user/module1 使用 user/module2 作为依赖:
// in source/to/module1/moon.mod
import {
"user/module2@0.1.0"
}
@version 部分会被忽略,user/module2 会从本地源码解析,而不是从 mooncakes.io 解析。
{
"name": "username/hello",
"deps": {
"username/other": {
"path": "../other"
}
}
}
元信息#
README#
readme 字段用于指定模块的 README 文件的路径。
readme = "README.md"
{
"readme": "README.md"
}
仓库#
repository 字段用于指定模块的仓库的 URL。
repository = "link/to/your/repo"
{
"repository": "link/to/your/repo"
}
许可证#
license 字段用于指定模块的许可证。许可证类型必须符合 SPDX 许可证列表。
license = "MIT"
{
"license": "MIT"
}
关键字#
keywords 字段用于指定模块的关键字。
keywords = ["example", "test"]
{
"keywords": ["example", "test"]
}
描述#
description 字段用于指定模块的描述。
description = "This is a description of the module."
{
"description": "This is a description of the module."
}
使用 .moonignore 控制发布文件#
使用 .moonignore 文件从 moon package 和 moon publish 创建的归档中排除文件和目录。每个文件使用 gitignore 风格的模式:
# Generated output
build/
*.log
# Keep this fixture even though other log files are excluded
!fixtures/expected.log
# Keep selected root dotfiles that are excluded by default
!/.gitignore
!/.moonignore
# Keep a hidden directory and everything below it
!/.well-known/
!/.well-known/**
发布时默认遵循 .gitignore 规则。如果某个目录包含 .moonignore,创建归档时将使用其规则代替同一目录中的 .gitignore;同一目录中的这两个文件不会合并。无论文件是否由 Git 跟踪,筛选都只依据这些模式。
不会读取 Git 仓库本地的 .git/info/exclude 和全局忽略配置。只有项目自身包含的忽略文件会影响归档,因此发布相同内容的结果不会依赖用户的 Git 配置。
默认情况下,各层级中名称以 . 开头的文件和目录都会被排除。上面锚定到根目录的示例会将两个忽略文件和 .well-known/ 保留在归档中。重新包含一个目录并不会自动重新包含其内容,因此还需要第二条 .well-known 规则。
包根目录下的 _build/ 始终会被排除,无法通过忽略规则或已弃用的 include 字段重新包含。此固定排除不适用于同名的嵌套目录。例如,!/_build/ 和 !/_build/** 无法恢复包根目录下的 _build/,而 examples/_build/data.bin 不会仅仅因为所在的嵌套目录名为 _build 就被排除。
规则作用于包含忽略文件的目录及其所有后代。父目录继承来的规则仍然有效,而嵌套目录中后出现的匹配规则优先。这也包括用 ! 恢复先前排除的路径、且该路径的父目录仍然可见的规则。开头的 / 将模式锚定到包含忽略文件的目录,末尾的 / 则匹配目录。
使用 moon package --list 检查将要打包的文件。
已弃用的 include 和 exclude 字段#
警告
moon.mod 和 moon.mod.json 中的 include 与 exclude 字段已弃用。新模块和迁移后的模块请使用 .moonignore。
现有清单仍可使用其中任一字段。当存在 include 时,它是完整的允许列表:不会应用 exclude、.gitignore、.moonignore 以及默认的点前缀路径排除规则。可在 include 中使用 ! 模式为允许列表添加例外。对包根目录 _build/ 的固定排除仍然有效。
请勿将这些旧字段与忽略文件混用;应将完整的发布策略迁移到 .moonignore。
首选目标#
preferred_target 字段允许 moon 和语言服务器知道应该使用哪个目标作为默认目标,从而避免在开发针对 Wasm GC 以外的其他后端的项目时需要传递 --target。
请在各模块中设置 preferred_target。工作区级别的 preferred-target 已弃用;moon run 使用所选模块自身的首选目标。
preferred_target = "js"
{
"preferred-target": "js"
}
支持的目标#
supported_targets 字段用于声明该模块打算支持哪些后端。与 preferred_target 不同,它不会为命令选择默认目标。它的作用是把模块的兼容后端范围记录在元数据中。
supported_targets 使用紧凑的目标集合语法:
js表示单个后端+js+wasm-gc表示显式指定一组后端+all-js表示除js之外的所有后端
例如:
supported_targets = "+js+wasm-gc"
{
"supported-targets": "+js+wasm-gc"
}
为了兼容,旧的数组语法仍然可以使用:
supported_targets = ["js", "wasm-gc"]
{
"supported-targets": ["js", "wasm-gc"]
}
preferred_target 和 supported_targets 经常一起使用:
preferred_target表示moon默认应使用哪个后端supported_targets表示模块声明自己支持哪些后端
当某个包也定义了 supported_targets 时,实际生效的后端集合就是模块级声明与包级声明的交集。
如果你想在包内部按文件做条件编译,应改用 moon.pkg / moon.pkg.json 中的 targets。
源目录#
source 字段用于指定模块的源目录。
它必须是相对于模块文件所在目录的子目录路径。
当使用 moon new 命令创建一个模块时,将自动生成一个 src 目录,并且 source 字段的默认值将为 src。
source = "src"
{
"source": "src"
}
如果 source 字段不存在,或其值为空字符串 "",则等同于设置 source = "."。这意味着源目录与模块文件所在目录相同。
source = ""
source = "."
{
"source": ""
}
{
"source": "."
}
null 等同于上述情况:
{
"source": null
}
警告列表#
这用于禁用特定的预设编译器警告编号。
例如,在以下配置中,-2 禁用警告编号 2(未使用的变量)。
warnings = "-2"
{
"warn-list": "-2"
}
如果需要禁用多种警告,可以直接连接起来进行组合。
warnings = "-2-4"
{
"warn-list": "-2-4"
}
如果需要激活某种原来未启用的警告,则使用加号。
warnings = "+31"
{
"warn-list": "+31"
}
你可以使用 moonc check -warn-help 查看预设编译器警告编号列表。在下面的输出中,mnemonic 是警告列表中使用的符号名称,id 是同一警告的数字形式。
$ moonc check -warn-help
Available warnings:
mnemonic description id state
unused_value Unused variable or function. 1 warn
unused_value Unused variable. 2 warn
unused_type_declaration Unused type declaration. 3 warn
missing_priv Unused abstract type. 4 warn
unused_type_variable Unused type variable. 5 warn
unused_constructor Unused constructor. 6 warn
unused_field Unused field or constructor argument. 7 warn
redundant_modifier Redundant modifier. 8 warn
struct_never_constructed Struct never constructed. 9 warn
unused_pattern Unused pattern. 10 warn
partial_match Partial pattern matching. 11 error
unreachable_code Unreachable code. 12 warn
unresolved_type_variable Unresolved type variable. 13 warn
alert or alert_<category> All alerts or alerts with specific category. 14 warn
unused_mut Unused mutability. 15 error
parser_inconsistency Parser inconsistency check. 16 warn
ambiguous_loop_argument Ambiguous usage of loop argument. 17 warn
useless_loop Useless loop expression. 18 warn
deprecated Deprecated API usage. 20 warn
missing_pattern_arguments Some arguments of constructor are omitted in pattern. 21 warn
ambiguous_block Ambiguous block. 22 warn
unused_try Useless try expression. 23 warn
unused_error_type Useless error type. 24 warn
test_unqualified_package Using implicitly imported API in test. 25 off
unused_catch_all Useless catch all. 26 warn
deprecated_syntax Deprecated syntax. 27 warn
todo Todo 28 warn
unused_package Unused package. 29 warn
missing_package_alias Empty package alias. 30 warn
unused_optional_argument Optional argument never supplied. 31 off
unused_default_value Default value of optional argument never used. 32 off
text_segment_excceed Text segment exceed the line or column limits. 33 warn
implicit_use_builtin Implicit use of definitions from `moonbitlang/core/builtin`. 34 warn
reserved_keyword Reserved keyword. 35 warn
block_label_shadowing Block label shadows another label. 36 warn
unused_block_label Unused block label. 37 warn
missing_invariant For-loop is missing an invariant. 38 off
missing_reasoning For-loop is missing a proof_reasoning. 39 off
multiline_string_escape Deprecated escape sequence in multiline string. 40 error
missing_rest_mark Missing `..` in map pattern. 41 warn
invalid_attribute Invalid attribute. 42 warn
unused_attribute Unused attribute. 43 warn
invalid_inline_wasm Invalid inline-wasm. 44 error
unused_rest_mark Useless `..` in pattern 46 warn
missing_definition Unused pub definition because it does not exist in mbti file. 49 warn
method_shadowing Local method shadows upstream method 50 warn
ambiguous_precedence Ambiguous operator precedence 51 warn
unused_loop_variable Loop variable not updated in loop 52 warn
unused_trait_bound Unused trait bound 53 warn
ambiguous_range_direction Ambiguous looping direction for range e1..=e2 54 off
unannotated_ffi Unannotated FFI param type 55 error
missing_pattern_field Missing field in struct pattern 56 warn
missing_pattern_payload Constructor pattern expect payload 57 warn
unaligned_byte_access Unaligned byte access in bits pattern 59 warn
unused_struct_update Unused struct update 60 warn
duplicate_test Duplicate test name 61 warn
invalid_cascade Calling method with non-unit return type via `..` 62 warn
syntax_lint Syntax lint warning 63 warn
unannotated_toplevel_array Unannotated toplevel array 64 warn
prefer_readonly_array Suggest ReadOnlyArray for read-only array literal 65 off
prefer_fixed_array Suggest FixedArray for mutated array literal 66 off
unused_async Useless `async` annotation 67 warn
declaration_unimplemented Declaration is unimplemented 68 warn
declaration_implemented Declaration is already implemented 69 off
deprecated_for_in_method using `iterator()` method for `for .. in` loop. 70 off
core_package_not_imported Packages in `moonbitlang/core` need to be explicitly imported. 71 warn
unqualified_local_using unqualified local using 72 off
unnecessary_annotation unnecessary type annotation 73 off
missing_doc Missing documentation for public definition 74 off
unnecessary_view_op Unnecessary `[:]` view operator 75 off
result_error_return Using `Result[T, E]` where `E` is an error type. 78 off
implicit_impl_as_method `impl` implicitly promoted as method 79 off
regex_match_missing_before Missing `before` binding in `regex match`. 80 warn
regex_match_missing_after Missing `after` binding in `regex match`. 81 warn
ambiguous_braces Ambiguous `{}` braces. 82 warn
type_param_method Calling method of type parameter in a deprecated way. 83 warn
unqualified_record Struct literal in a `let` binding without a type prefix. 84 off
unlabelled_break_in_labelled_loop Unlabelled `break` directly inside a labelled loop. 85 warn
unlabelled_continue_in_labelled_loop Unlabelled `continue` directly inside a labelled loop. 86 warn
guard_inexhaustive `guard` condition is not exhaustive and may panic. 87 warn
guard_redundant_bang Redundant `!` on an exhaustive `guard`. 88 warn
guard_redundant_else Redundant `else` on an exhaustive `guard`. 89 warn
all all warnings
state: warn = enabled, error = promoted to error, off = disabled
note: default alert exceptions: alert_unsafe=off
Rule#
模块级 rule 条目声明一个可复用的预构建命令,模块内的每个 moon.pkg 都可以使用它。模块级 rule 不会自行运行;如果要在构建包之前使用它,需要在 moon.pkg 中添加包级 dev_build 条目。关于包级配置,请参阅 Package Configuration 中的 "Rule and dev_build" 一节。
使用 rule(name: "...", command: "..."),其中 name 标识规则,command 是一个 shell 命令字符串。该命令可以引用 $input 和 $output,它们由使用该 rule 的包级 dev_build 条目提供。一个模块可以声明多个模块级 rule 条目。
rule(name: "tool", command: "tool $input -o $output")
moon.mod.json 不支持此功能。
脚本#
scripts 字段用于定义与模块关联的自定义脚本。
postadd 脚本#
postadd 脚本在模块添加后自动运行。执行时,脚本的当前工作目录(cwd)设置为模块配置文件所在的目录。
options(
scripts: {
"postadd": "python3 build.py",
},
)
{
"scripts": {
"postadd": "python3 build.py"
}
}
[实验性] 预构建配置脚本#
警告
这个功能是极其实验性的,其 API 可能随时发生变化。本文件反映了截至 2025-06-03 的实现。
重要
使用此功能可能会在您的计算机上执行任意代码。请谨慎使用,仅与受信任的依赖项一起使用。
预构建配置脚本用于辅助 native 目标编程。要使用此类脚本,请将其添加到模块配置中:
options(
"--moonbit-unstable-prebuild": "<path/to/build-script>",
)
{
"--moonbit-unstable-prebuild": "<path/to/build-script>"
}
路径是相对于项目根目录的相对路径。脚本可以是 JavaScript 脚本(扩展名为 .js、.cjs、.mjs)使用 node 执行,或者是 Python 脚本(扩展名为 .py)使用 python3 或 python 执行。
输入#
脚本将从标准输入流(stdin)接收一个具有 BuildScriptEnvironment 结构的 JSON:
/** 表示构建脚本接收的环境 */
interface BuildScriptEnvironment {
env: Record<string, string>
paths: Paths
}
interface BuildInfo {
/** 当前构建脚本正在运行的目标信息 */
host: TargetInfo
/** 正在构建的模块的目标信息 */
target: TargetInfo
}
interface TargetInfo {
/** 我们正在使用的实际后端,例如 `wasm32`、`wasmgc`、`js`、`c`、`llvm` */
kind: string // TargetBackend
}
输出#
脚本预计将在其标准输出流(stdout)中打印一个具有 BuildScriptOutput 结构的 JSON 字符串:
interface BuildScriptOutput {
/** 构建变量 */
vars?: Record<string, string>
/** 链接配置 */
link_configs?: LinkConfig[]
}
interface LinkConfig {
/** 要配置的包的名称 */
package: string
/** 需要传播到依赖项的链接标志
*
* 参考:`cargo::rustc-link-arg=FLAG` */
link_flags?: string
/** 需要链接的库,传播到依赖项
*
* 参考:`cargo::rustc-link-lib=LIB` */
link_libs?: string[]
/** 需要在链接期间搜索的路径,传播到依赖项
*
* 参考:`cargo::rustc-link-search=[KIND=]PATH` */
link_search_paths?: string[]
}
构建变量#
您可以在 moon.pkg 的本地链接参数中使用 vars 字段中发出的变量,格式为 ${build.<var_name>}。
例如,如果您的构建脚本输出:
{ "vars": { "CC": "gcc" } }
并且您的 moon.pkg 结构如下:
options(
link: {
"native": {
"cc": "${build.CC}",
},
},
)
它会被转换为
{
"link": {
"native": {
"cc": "gcc"
}
}
}