模块系统
本文档收敛 Dujie 的模块、导入导出、路径规则和入口相关约束。
模块
- 一个源文件就是一个模块
- 模块身份由文件路径决定
- 当前唯一合法源文件扩展名是
.dj
第一阶段不引入额外的模块声明语法。
导入
import 只用于导入其他模块已导出的顶层符号。
当前支持的形态:
import { foo, bar } from "./utils.dj"
import { foo as my_foo } from "./utils.dj"
导入源
当前支持两类导入源:
本地相对路径
注册表模块
本地相对路径
例如:
import { button } from "../components/button.dj"
规则:
- 必须是静态字符串
- 必须显式写扩展名
- 按当前文件所在目录做相对解析
注册表导入
例如:
import { button } from "registry:ui/button.dj"
规则:
- 必须是静态字符串
- 必须显式写扩展名
- 不走本地相对路径解析
- 版本、缓存、锁定等规则交给注册表和构建系统处理
当前不支持
- 动态导入
import *- 默认导入
- 混合默认导入与具名导入
- 根路径别名
- 目录索引魔法
- 自动补全扩展名
导出
当前仅支持导出顶层:
funcstruct
例如:
export func add(x: int, y: int) -> int {
x + y
}
export struct Person {
name: string,
}
当前不支持:
- 导出局部变量
- 导出表达式结果
export { foo, bar }export * from ...
可见性
- 不写
export的顶层符号默认模块私有 - 其他模块只能访问被
export的符号 - 模块内部可直接访问本模块私有顶层符号
名称规则
- 导入名称进入当前模块顶层命名空间
- 导入后名称冲突是编译错误
- 可以使用
as改名避开冲突
路径解析错误
以下情况属于编译错误:
- 导入路径非法
- 导入路径无法解析
- 同一路径不能唯一解析
- 循环导入
main 与模块入口
main 是入口相关的保留名字,但模块是否被当作应用入口,由构建或运行系统决定,不由 export 决定。
模块级约束:
main必须是模块顶层func- 一个模块内最多只能有一个
main main不需要exportmain不能与其他顶层符号重名main不能是泛型函数- 普通库模块可以没有
main
语言层不再单独限制 main 的参数形状:
- 只要参数声明本身符合 Dujie 普通函数规则即可
- 位置参数、具名参数、
opt<T>参数、默认值都可以用于main
main 的渲染语义和入口适配规则见《渲染内建》。