ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Dagger TypeScript SDK 中 CurrentModule 类详解:模块运行时注入的反射式模块 API

2026/9/17 17:07:17 拓冰建站 浏览量
Dagger TypeScript SDK 中 CurrentModule 类详解:模块运行时注入的反射式模块 API Dagger TypeScript SDK 中 CurrentModule 类详解模块运行时注入的反射式模块 API【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger本文为 Dagger 0.21 版 TypeScript SDK 参考文档中CurrentModule类的深度解读。CurrentModule是引擎在模块函数执行时注入的「反射式模块 API」用于在运行时自省当前正在执行的模块读取模块名与依赖、获取源码与生成文件目录、访问临时工作区文件。读完本文你将完整掌握该类的全部方法与参数含义并能对照 TypeScript 客户端生成代码与引擎侧 Go 实现理解每个方法背后的字段解析、缓存键推导与路径安全边界。类定位BaseClient 之上的运行时反射 APICurrentModule类的官方定义为「Reflective module API provided to functions at runtime」——即在模块函数运行时提供给函数的反射式模块 API。从源码看它继承自 SDK 的BaseClient基类/** * Reflective module API provided to functions at runtime. */ export class CurrentModule extends BaseClient { private readonly _id?: ID undefined private readonly _name?: string undefined // ... }见 client.gen.ts继承BaseClient意味着它具备与其他 SDK 对象如Directory、File、Module_一致的惰性求值语义每个方法只是通过this._ctx.select(...)在 GraphQL 查询上下文中追加一个字段选择真正的数据在await时才由引擎返回。这也解释了为什么dependencies()、id()、name()是async的而source()、workdir()等方法只是同步返回一个尚未执行的Directory对象。构造函数仅内部使用参考文档声明的构造签名为new CurrentModule(ctx?,_id?,_name?):CurrentModuleConstructor is used for internal usage only, do not create object from it.ctx?ContextGraphQL 查询上下文_id?模块对象的ID若已知可传入以短路id()的远程查询_name?模块名若已知可传入以短路name()的远程查询。从源码可以确认其惰性短路逻辑例如id()方法id async (): PromiseID { if (this._id) { return this._id } const ctx this._ctx.select(id) const response: AwaitedID await ctx.execute() return response }见 client.gen.ts文档明确提示该构造器仅供内部使用、不应由用户手动创建实例在真实使用场景中这个对象由 Dagger 引擎在模块函数调用时注入例如通过模块函数的dagger参数访问currentModule开发者无需关心其构造细节。方法逐一解析name() 与 id()模块身份方法签名说明name()Promisestring当前正在执行的模块的名称id()PromiseID该 CurrentModule 的唯一标识符name()同样带_name短路逻辑id()返回的ID是 DAG 对象标识可用于跨引用比较模块实例是否一致。dependencies()模块依赖列表dependencies():PromiseModule_[]返回当前模块的依赖模块Module_对象数组。引擎侧实现位于 module.go它遍历mod.Module.Self().Deps.Mods()只保留能解析出具体Module实例的依赖并显式跳过内建的CoreModcore 模块不算业务依赖。这一点值得注意——如果你的模块依赖的是核心模块它不会出现在该列表中。source()加载进引擎的模块源码目录source():Directory返回包含模块源码以及可能已生成的代码的目录。引擎侧实现比表面含义更复杂见 module.go先取出模块源目录的generatedContextDirectory生成文件目录将该生成目录以/为路径 overlay 到模块的ContextDirectory上再从结果中选取源子路径优先SourceSubpath否则回退到SourceRootSubpath。也就是说source()返回的是「原始上下文 生成代码覆盖」后的视图这正是文档注释中「plus any generated code that may have been created」的实现来源。generatedContextDirectory()生成物目录generatedContextDirectory():Directory返回「在模块源上下文目录之上生成的文件和目录」。引擎侧module.go直接对模块的Source目录选择generatedContextDirectory字段与source()复用同一数据源便于在模块内部区分「哪些内容是 SDK 生成/注入的」。generators()模块定义的生成器Experimentalgenerators(opts?):GeneratorGroupExperimental— Return all generators defined by the module参数类型CurrentModuleGeneratorsOpts见 client.gen.ts字段类型说明include?string[]只包含匹配给定模式的生成器引擎侧currentModuleGenerators见 module.go将include模式数组透传给core.NewGeneratorGroup与UpGroup的模式过滤机制类似。注意该方法标记为experimentalAPI 可能随版本演进。workdir()临时工作区目录workdir(path,opts?):Directory加载模块临时工作目录scratch working directory下的一个目录包含模块函数执行期间对该目录所做的任何变更。pathstring要访问的目录位置如.opts?CurrentModuleWorkdirOpts见 client.gen.ts字段类型说明exclude?string[]排除匹配给定模式的产物如[node_modules/, .git*]include?string[]只包含匹配给定模式的产物如[app/, package.*]gitignore?boolean是否应用目录内.gitignore过滤规则引擎侧实现有两点值得强调见 module.go路径越界防护if !filepath.IsLocal(args.Path) { return ..., workdir path %q escapes workdir }——传入的path必须相对本地化任何../逃逸都会被直接拒绝底层数据源是主机目录合法路径会被拼接sdk.RuntimeWorkdirPath前缀然后经host.directory以exclude/include/gitignore三个参数读取。因此workdir()读取的是引擎会话在宿主机上的运行时工作目录天然反映函数执行过程中的实时写入。workdirFile()临时工作区文件workdirFile(path):File加载模块临时工作目录下的一个文件语义与workdir()完全一致只是返回File对象。参数path为文件位置如README.md。引擎侧同样执行filepath.IsLocal校验后拼接RuntimeWorkdirPath经host.file读取见 module.go因此同样受「不允许逃逸工作目录」的约束。引擎侧解析机制currentModule 的缓存键推导TypeScript 客户端只是把字段选择发给引擎真正的「当前模块是谁」由引擎推导。在 module.go 中currentModule以dagql.FuncWithDynamicInputs(currentModule, s.currentModule, s.currentModuleCacheKey)注册——即它带动态输入并自定义缓存键currentModuleCacheKeymodule.go若调用上下文未显式携带ImplementationScopedMod则从父对象Query读取CurrentModule经core.ImplementationScopedModule转换为「实现作用域」模块并把其 ID 写回请求参数currentModulemodule.go加载该作用域模块并包装为*core.CurrentModule返回。从源码结构看这一机制保证了 DAG 缓存的正确性currentModule的缓存键与其实际指向的模块实现绑定模块代码变化会自然导致缓存失效而相同模块的重复调用可命中缓存。速查表方法参数返回说明name()—Promisestring当前执行模块的名称id()—PromiseID模块唯一标识dependencies()—PromiseModule_[]模块依赖不含 core 模块source()—Directory源码目录含生成代码覆盖generatedContextDirectory()—Directory生成文件与目录generators(opts?)include?: string[]GeneratorGroup模块定义的生成器实验性workdir(path, opts?)path: stringexclude/include/gitignoreDirectory临时工作区目录防路径逃逸workdirFile(path)path: stringFile临时工作区文件防路径逃逸小结与实践要点CurrentModule是「引擎注入、内部构造」的反射对象不要手动new CurrentModule(...)直接消费运行时注入的实例即可。source()与generatedContextDirectory()共同揭示了 SDK 代码生成的落盘位置workdir()/workdirFile()则是函数执行期读写临时文件的正式入口且受filepath.IsLocal严格约束无法读取工作区之外的宿主路径。dependencies()有意过滤 core 模块判断「是否还有外部依赖」时不必为其特判。涉及实验性 API 的generators()在跨版本使用时应留意 SDK 版本行为。关键参考路径TypeScript 客户端实现 client.gen.ts、引擎字段解析 module.go、参数类型定义 client.gen.ts。【免费下载链接】daggerAutomation engine to build, test and ship any codebase. Runs locally, in CI, or directly in the cloud项目地址: https://gitcode.com/GitHub_Trending/da/dagger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考