模块配置#

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 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."
}

包含和排除#

includeexclude 字段用于在发布过程中包含或排除特定的目录或文件。

它遵循 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-targetsupported-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)使用 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"
    }
  }
}