@expo/expo-modules-macros-plugin 是世博会模块 API 后面的 Swift 编译器插件。 它执行宏 expo-modules-core 声明,所以一个模块作者会写出平版斯威夫特声明,插件会合成将声明绑定在JavaScript上的代码.
与源扫描器CLI相同的可执行文件双相.
安装
此软件包并非要直接安装 。 属于 expo-modules-core因此,每个博览会项目 已经拥有它。 已发布的软件包包含一个预建的通用(arm64 + x86 64) macOS 二进制 apple/ExpoModulesMacros-tool,所以消费者从不自己建造插件.
宏
@ExpoModule(_ name: String? = nil, classes: [Any.Type] = [])在课堂上。 将类变成模块:绑定其@JS成员进入模块的JavaScript对象并从参数中解析模块名,倒回类名. 也综合了继承下来的一切Module用来提供,所以模块类可以携带任何超级,或者没有.@JS(_ jsName: String? = nil, _ options: JSOptions...)在模块成员或共享对象上。 标记用于导出的一个函数、属性或初始化器.@ExpoModule财务报告和审定财务报表@SharedObject将每个被标记的成员直接绑入JavaScript对象,并用参数解码,调用和结果编码成内线,因此没有动态的每调用路径. JS名称默认为斯威夫特名称;通过一个字符串来覆盖它. 宏还检查每一个跨出边界的类型都是可转换的,沿它所行走的方向,因此在作者自己的声明上报告一个坏的类型,而不是附加的类型. 这个.concurrent选项移动async机身从JavaScript线上脱出,同时仍然在它上解码和编码.@Event(_ name: String? = nil, sync: Bool = false)在函数类型上var。将属性扩展为释放事件的关闭,因此调用属性将其发送给JavaScript,以关闭参数作为有效载荷。 JS 名称默认为属性名称,并带有on剥了.sync: true发出内线而不是同步.@SharedObject(_ name: String? = nil)编号SharedObject子类。 收集课程@JS成员进入一个模块会通过@ExpoModule(classes:)。 。 。 .@Record()记录类型。 将每一个非静态的,非私有的,非计算存储的属性作为字段处理,没有每个字段的包装,并合成成员的初始化器,两个方向的转换器,以及Record遵从. 必要性被推断:默认值使字段具有可选性,可选类型使其无效和可选性.@Union()在每一案件都具有一个相关价值的矿井上。 模式类型脚本联盟。 将转换分为两个方向,每个有效载荷类型的一个打入器,以及JavaScriptDecodable财务报告和审定财务报表JavaScriptEncodable符合规定。 解码被命令:第一例有效载荷解码取胜,因此更具体的案件先出.
这在模块里是什么样子的:
import ExpoModulesCore
@ExpoModule(classes: [Cache.self])
public final class MyModule {
@JS
func greet(name: String) -> String {
"Hi, \(name)"
}
@JS("doWork")
func performWork() async throws { ... }
@Event
var onProgress: (ProgressEvent) -> Void
}
@SharedObject
final class Cache: SharedObject {
@JS
init(name: String) { ... }
@JS
func get(_ key: String) -> String? { ... }
}
关于每个宏生命的作者文件,载于以下表 expo-modules-core输入 ios/Core/ExpoModulesMacros.swift。该存储库保存执行文件.
扫描仪
Swift编译器发射一个没有参数的可执行插件,并且会将插件协议比作stdin,因此二进制将任何参数作为扫描器引用处理:
ExpoModulesMacros-tool <subcommand> [options] <path> [<path> ...]
subcommands:
scan-modules fast scan for top-level @ExpoModule types (autolinking)
scan-exports deep scan of the full JS-exported surface (type generation)
options (scan-modules only):
--platform <os> evaluate '#if os(...)' against this platform
--define <flag> treat a conditional compilation flag as set; repeatable
每条路都是一条 .swift 文件或目录, 递归扫描 .swift 文档。 两个子命令都打印出 JSON 报告到 stdout, 每个都带有自己的 schemaVersion 这样消费者就可以在信任它之前先检查一下它的形状。 这两个版本是独立的:命令服务于不同的消费者并因不同的原因而改变.
类型脚本包
节点消费者可以通过这个包调用扫描仪,而不是定位二进制并自行炮击:
import { scanModules, scanExports } from '@expo/expo-modules-macros-plugin';
const { modules, warnings } = await scanModules(['ios/'], { defines: ['DEBUG'] });
const { exports } = await scanExports(['ios/']);
二进制是被编译的可执行文件,所以每次调用仍然会产生一个过程. 包装者拥有的是消费者会重复的部分:解决运出二进制,构建参数,解析JSON,检查 schemaVersion,然后将一个非零退出变为一个 ScannerError。结果类型是手写的 Swift 镜像 Codable 类型,即版本检查卫兵防漂移.
插件如何到达编译器
expo-modules-core 以 #externalMacro(module: "ExpoModulesMacros", type: …)期间 pod install, (中文(简体) ), expo-modules-autolinking 从核心软件包和附件中解决此软件包
-Xfrontend -load-plugin-executable -Xfrontend <plugin>/apple/ExpoModulesMacros-tool#ExpoModulesMacros
改为 OTHER_SWIFT_FLAGS 页:1 ExpoModulesCore每一个依赖于它的舱, 和他们的测试规格。 Expo的 SPM 预建在生成时会传递相同的旗帜 Package.swift,因此两个系统都装入相同的二进制.
模块和类型名称 #externalMacro 必须与 apple/Sources/ExpoModulesMacros/Plugin.swift。 。 。 .
发展
需要 macOS 13 或 更新,以及带有 Swift 6.2 的工具链,这意味着 Xcode 26 或 更新.
cd apple
swift build
swift test
npm run build 运行 apple/build.js,用于构建 arm64 和 x86 64 的释放二进制,将切片合并为 apple/ExpoModulesMacros-tool 与 lipo,剥去它, 并验证两个片存在。 SwiftPM只为主机架构构建宏工具,因此x86 64切片通过运行罗塞塔下的工具链来生产;脚本在缺少时会安装罗塞塔. 由此产生的二进制是致力于存储器.
释放
这个 发布 工作流程是手动的workflow_dispatch)并取出放行类型. 它撞倒了版本,构建了通用二进制,并通过OIDC信任的出版发布到npm. 承诺,标记和 GitHub 发布仅在发布成功后才被创建出,因此一个失败的构建让分支未受影响.
捐款
贡献是非常受欢迎的! 请参考本报告所述准则 贡献指南。 。 。 .