Wing 语言本地模块导入实战:`bring “./file.w“` 语法、编译产物与 Hangar 测试快照验证
编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载本文围绕 Wing 语言The Wing Programming Language本仓库为 wing 的镜像仓库的本地模块导入机制展开以仓库测试套件 Hangar 生成的 bring_local.test.w_test_sim.md 快照为核心线索结合测试源码 bring_local.test.w 与对应编译快照 bring_local.test.w_compile_tf-aws.md讲解如何在 Wing 中通过bring引入同项目内的.w文件模块、跨文件复用 class/struct/enum/interface 等类型并剖析wing test在 sim 平台上的执行与快照生成原理。读完本文你将掌握 Wing 本地模块的导入语法、可见性规则、extern与子模块的使用方式以及如何阅读和验证 Hangar 测试快照。一、快照文档是什么一条测试通过记录bring_local.test.w_test_sim.md是 Hangar 测试工具链为tests/valid/bring_local.test.w生成的sim 平台测试快照其正文只有一段stdout.logpass ─ bring_local.test.wsim » root/Default/test:add data to store pass ─ bring_local.test.wsim » root/Default/test:greet Tests 2 passed (2) Snapshots 1 skipped Test Files 1 passed (1) Duration DURATION这短短几行输出揭示了三个关键信息文件命名规范*.test.w是 Wing 的入口测试文件详见 generated_test_targets.ts 中的isEntrypointFile判定*.test.w、*.main.w、main.w均被视为入口文件只有入口文件才允许包含test块_test_sim表示测试目标为sim模拟器平台与此对应的编译目标为_compile_tf-aws。测试用例该文件定义了test:add data to store与test:greet两个用例root/Default/是 Wing 应用树application tree中测试资源std.Test在模拟器中的构造路径。结果摘要Tests 2 passed (2)表明两个测试全部通过Snapshots 1 skipped说明该快照未做其他快照比对Duration DURATION是 Hangar 在生成快照时对运行时长的脱敏占位符。二、测试源码全景本地模块导入的典型用法快照背后的被测程序是 bring_local.test.w其开头集中展示了 Wing 本地模块导入的几种形态bring ./store.w as file1; bring ./subdir/subfile.w as file2; bring ./subdir/empty.w as file3; bring math; bring expect;bring ./store.w as file1;以相对路径导入同目录下的.w文件并以file1作为命名空间别名。这是 Wing 本地模块导入的核心语法路径相对于当前文件解析扩展名.w可以省略。bring ./subdir/subfile.w as file2;支持导入子目录中的文件说明模块可以是任意层级的相对路径。bring ./subdir/empty.w as file3;即使目标文件是空文件empty.w 内容为空也能正常导入空模块是合法模块。bring math;、bring expect;导入内置标准库模块math、expect不需要路径。依据官方语言参考 05-language-reference.md 的 Module System 章节bring表达式只允许出现在文件顶部、任何其他代码之前注释除外并且是 Wing 中唯一允许跨文件导入函数、类与变量的语法。本地文件导入的具体写法为bring ./my-module.w as myModule;同时支持以目录为模块导入——模块将包含该目录下所有文件中公开的类型子目录则按对应名称暴露bring ./my-module as myModule; new myModule.submodule.MyClass(); // 来自 ./my-module/submodule/my-class.w三、跨文件复用class、struct、enum、interface 与同名类bring_local.test.w的剩余部分逐一验证了本地模块导入后可以复用的类型3.1 实例化其他文件的类let store new file1.Store(); let q new file2.Q(); expect.equal(file2.Q.preflightGreet(foo), Hello foo);file1.Store来自 store.w 中定义的pub class Store其构造器内部创建了一个cloud.Bucket并通过cloud.OnDeploy在部署时写入初始化数据file2.Q来自 subfile.w静态方法preflightGreet由extern实现。3.2 其他文件的 struct、enum、interfacelet s file1.Point { x: 1, y: 2 }; // struct let c file1.Color.BLUE; // enum assert(c ! file1.Color.RED); class Triangle impl file1.Shape { // interface pub area(): num { return 1; } }对应地store.w 用pub声明了enum ColorRED/GREEN/BLUE、struct Pointx: num; y: num;和interface Shapearea(): num;。这里验证了本地模块可以完整导出枚举、结构体与接口且接口可以被入口文件中的类实现——这是 Wing 类型系统中模块间交互的重要能力。3.3 同名类的隔离// classes can have the same name as classes in other modules class Util {}store.w 中同样定义了pub class Util而入口文件也定义了class Util。由于模块以命名空间file1隔离二者互不冲突。编译快照印证了这一点bring_local.test.w_compile_tf-aws.md 中入口文件的Util定义在preflight.cjs内而 store.w 的Util则位于独立的preflight.store-2.cjs产物中。3.4 extern用 TypeScript 实现本地模块方法file2.Q所在的 subfile.w 展示了extern修饰符的用法bring math; pub class Q { pub extern ./util.ts static inflight greet(name: str): str; pub extern ./util.ts static preflightGreet(name: str): str; }extern javascript module path可挂载到类的方法声明上指示该方法由相对路径的 JavaScript/TypeScript 模块实现语言参考见 05-language-reference.md。实现文件 util.ts 通过util.extern类型声明保证与 Wing 侧签名一致import type extern from ./util.extern; export const greet: extern[greet] async (name) { return Hello name; } export const preflightGreet: extern[preflightGreet] (name) { return Hello name; }编译快照中的 inflight.Q-2.cjs 显示该方法最终被编译为require(../../../subdir/util.ts)greet的调用即运行时通过 Node 的require加载外部 TS 模块。四、测试用例与编译产物从 Wing 源码到可执行代码4.1 两个测试用例test add data to store { store.store(foo); } test greet { expect.equal(file2.Q.greet(bar), Hello bar); }add data to store在 inflight 环境调用store.store(foo)将数据写入 Store 内部的 Bucket。greet调用file2.Q.greet(bar)extern 实现的 inflight 静态方法并用expect.equal断言结果为Hello bar。4.2 inflight 闭包的编译结果测试块会被编译为 inflight 闭包见编译快照中的 inflight.$Closure1-3.cjs 与 inflight.$Closure2-3.cjsmodule.exports function({ $store }) { class $Closure1 { async handle() { (await $store.store(foo)); } } return $Closure1; }module.exports function({ $expect_Util, $file2_Q }) { class $Closure2 { async handle() { (await $expect_Util.equal((await $file2_Q.greet(bar)), Hello bar)); } } return $Closure2; }闭包以工厂函数接收 lift 上来的对象引用$store、$file2_Q、$expect_Util体现了 Wing 的lift 机制——preflight 对象被显式提升到 inflight 作用域后才能在运行时访问。4.3 Store 类及其 AWS 资源preflight.store-2.cjs 是 store.w 的编译产物Store构造器内部new cloud.Bucket()与cloud.OnDeploy均被实例化为真实构造树节点。而 main.tf.json 则展示了 tf-aws 目标下的 Terraform JSON 产物——一个aws_s3_bucketStore 的 Bucket、一个aws_lambda_functionOnDeploy 的部署函数runtimenodejs20.x、架构arm64、超时 60 秒以及配套的 IAM 角色、CloudWatch 日志组等资源。这说明即使测试本身运行在 sim 平台Wing 仍然能为同一源码产出完整的云基础设施定义。4.4 入口文件的 preflight 组装preflight.cjs 展示了本地模块在编译产物中的加载方式const file1 $helpers.bringJs(${__dirname}/preflight.store-2.cjs, $preflightTypesMap); const file2 $helpers.bringJs(${__dirname}/preflight.subfile-3.cjs, $preflightTypesMap); const file3 $helpers.bringJs(${__dirname}/preflight.empty-1.cjs, $preflightTypesMap);每个被bring的本地.w文件都会被编译为独立的preflight.name-n.cjs模块再通过 SDK 的bringJs帮助函数加载。其实现位于 packages/winglang/sdk/src/helpers.ts除了执行require还会把被导入模块的$preflightTypesMap合并进当前模块的类型映射从而让编译器生成的类型解析如globalThis.$ClassFactory.new(examples-valid.Store, file1.Store, this, Store)在运行时可用。这正是本地模块导入在运行时层面的落地方式。五、快照如何生成Hangar 的测试流水线bring_local.test.w_test_sim.md由工具链 Hangar 自动生成相关源码位于 generated_test_targets.ts测试快照testTestL86-L122以[sim]为平台、[test]为参数运行wing test将WING_HIDE_CONTAINER_LOGS1注入环境把 stdout 写入fileMap[stdout.log]再调用createMarkdownSnapshot生成*_test_sim.md。这就是本文开头那段 stdout 快照的来源。编译快照compileTestL12-L84以[tf-aws]为平台运行wing compile收集target/name.tfaws/.wing目录下匹配preflight.、inflight.、extern/、proc、.Struct.js前缀的文件以及main.tf.json统一生成*_compile_tf-aws.md。快照还包含禁止绝对路径 require的校验L69-L71确保产物可移植。因此test_corpus下同一测试名对应的_test_sim.md与_compile_tf-aws.md是一对互补证据前者证明行为正确性后者证明基础设施产物符合预期。六、本地模块导入的更多形态归一化、目录与别名除了bring_local.test.w仓库中还有一组围绕bring的专项测试可作为扩展阅读路径归一化bring_local_normalization.test.w 验证同一个文件通过不同相对路径如./subdir/bar.w与./bar.w、./baz.w与../baz.w导入时Wing 能正确解析为同一个模块不会产生重复定义。目录导入bring_local_dir.test.w 验证bring ./subdir2 as subdir;的目录级导入——目录下所有文件公开类型平铺子目录类型通过subdir.inner.Widget访问。命名别名bring_alias.test.w 验证内置模块也可用as起别名bring fs as stdFs;同一模块多次以不同别名导入不冲突。七、小结与上手路径从快照bring_local.test.w_test_sim.md出发可以完整还原 Wing 本地模块导入的闭环语法bring ./path/to/file.w as ns;导入相对路径模块bring dir;导入目录bring mod;导入内置库详见 语言参考 · Module System。可见性被导入文件中的类型须以pub声明如 store.w 中的pub class / pub enum / pub struct / pub interface导入后经命名空间隔离访问同名类互不干扰。编译与运行每个本地模块编译为独立preflight.*.cjs经 bringJs 加载并合并类型映射extern方法在运行时通过require调用外部 JS/TS 实现。验证wing testsim 平台与wing compiletf-aws 平台由 Hangar 自动执行并产出 Markdown 快照作为行为与产物的回归基准。如果你想在本地复现这一验证过程可在安装 Wing CLI 后于tests/valid目录执行wing test bring_local.test.wsim 运行与wing compile bring_local.test.w -t tf-aws生成 Terraform 产物再对照 bring_local.test.w_test_sim.md 与 bring_local.test.w_compile_tf-aws.md 两份快照核对输出。赞分享编程语言编译器云原生语言运行时【免费下载链接】wingA programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡项目地址https://gitcode.com/gh_mirrors/wi/wing点击查看免费下载相关推荐Wing 语言「bring 非入口模块并继承其类」能力解析从 hangar 快照测试到编译产物验证Wing 语言「bring 非入口模块并继承其类」能力解析从 hangar 快照测试到编译产物验证 导读 本文围绕 Wing 开源仓库中一份 hangar 快编程语言编译器云原生语言运行时Wing 语言 expect 标准库断言 API 全解析从 hangar 快照看编译产物与测试验证Wing 语言 expect 标准库断言 API 全解析从 hangar 快照看编译产物与测试验证 本文围绕 Wing 开源仓库中的 expect 标准库模块编程语言编译器云原生语言运行时Wing 语言本地模块 bring 机制深度解析以 bring_local 测试编译产物为切入点Wing 语言本地模块 bring 机制深度解析以 bring_local 测试编译产物为切入点 本篇技术指南围绕 Wing 语言Winglang的 本地编程语言编译器云原生语言运行时上一篇ulw-plan CLEAR 意图路径解析oh-my-openagent 中如何以最少提问产出决策完备的工作计划下一篇90DaysOfDevOps 实战在 Windows 上配置 Go 开发环境并完成 Hello WorldDay 8创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考