模块配置#

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 addmoon 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/module1user/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 packagemoon 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 检查将要打包的文件。

已弃用的 includeexclude 字段#

警告

moon.modmoon.mod.json 中的 includeexclude 字段已弃用。新模块和迁移后的模块请使用 .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_targetsupported_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)使用 python3python 执行。

输入#

脚本将从标准输入流(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 结构如下:

moon.pkg#
options(
  link: {
    "native": {
      "cc": "${build.CC}",
    },
  },
)

它会被转换为

{
  "link": {
    "native": {
      "cc": "gcc"
    }
  }
}