模块配置#
moon 使用模块文件来标识和描述一个模块。旧格式为 moon.mod.json,新格式为 moon.mod。完整的 JSON 模式请查看 moon 的仓库。
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"
}
依赖管理#
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."
}
包含和排除#
include 和 exclude 字段用于在发布过程中包含或排除特定的目录或文件。
它遵循 gitignore 语法,并且包含的内容会覆盖排除的内容。例如,以下配置将包含 build/assets 但排除 build 目录中的其他内容。
options(
exclude: ["build"],
"include": ["build/assets"],
)
{
"exclude": ["build"],
"include": ["build/assets"]
}
你可以使用 moon package --list 来验证打包结果是否符合预期。
首选目标#
preferred-target 字段允许 moon 和语言服务器知道应该使用哪个目标作为默认目标,从而避免在开发针对 Wasm GC 以外的其他后端的项目时需要传递 --target。
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", "native"]
}
preferred-target 和 supported-targets 经常一起使用:
preferred-target表示moon默认应使用哪个后端supported-targets表示模块声明自己支持哪些后端
当某个包也定义了 supported-targets 时,实际生效的后端集合就是模块级声明与包级声明的交集。
如果你想在包内部按文件做条件编译,应改用 moon.pkg / moon.pkg.json 中的 targets。
源目录#
source 字段用于指定模块的源目录。
它必须是 moon.mod.json 文件所在目录的子目录,并且必须是相对路径。
当使用 moon new 命令创建一个模块时,将自动生成一个 src 目录,并且 source 字段的默认值将为 src。
options(
source: "src"
)
{
"source": "src"
}
如果 source 字段不存在,或其值为空字符串 "",则等同于设置 "source": "."。这意味着源目录与 moon.mod.json 文件所在目录相同。
options(
"source": ""
)
options(
"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
loop_label_shadowing Loop label shadows another label. 36 warn
unused_loop_label Unused loop 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
invalid_mbti Invalid mbti file 47 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
A 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)设置为 moon.mod.json 文件所在的目录。
options(
scripts: {
"postadd": "python3 build.py",
},
)
{
"scripts": {
"postadd": "python3 build.py"
}
}
[实验性] 预构建配置脚本#
警告
这个功能是极其实验性的,其 API 可能随时发生变化。本文件反映了截至 2025-06-03 的实现。
重要
使用此功能可能会在您的计算机上执行任意代码。请谨慎使用,仅与受信任的依赖项一起使用。
pre-build 配置脚本的添加是为了帮助本地目标编程。要使用此脚本,请在您的 moon.mod.json 中添加您的脚本:
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"
}
}
}