十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Dagger TypeScript SDK 的 DirectoryAsModuleSourceOpts:sourceRootPath 详解与模块源码加载实战

Dagger TypeScript SDK 的 DirectoryAsModuleSourceOpts:sourceRootPath 详解与模块源码加载实战 Dagger TypeScript SDK 的 DirectoryAsModuleSourceOptssourceRootPath 详解与模块源码加载实战【免费下载链接】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 TypeScript SDK 中Directory对象的asModuleSource()方法及其配套类型DirectoryAsModuleSourceOpts重点讲解可选的sourceRootPath参数它如何指定包含模块配置文件dagger.json的目录子路径以及未设置时模块源码从目录根加载的默认行为。读完本文你将掌握在 Dagger 中通过Directory以编程方式加载本地或 CI 环境中的模块源码、定位多模块仓库中的子模块配置并结合引擎侧源码理解其底层校验与加载链路。类型定义速览DirectoryAsModuleSourceOpts是 Dagger TypeScript SDK 生成客户端中的一个对象类型仅包含一个可选属性。完整的类型定义如下见 sdk/typescript/src/api/client.gen.ts#L1296-L1303export type DirectoryAsModuleSourceOpts { /** * An optional subpath of the directory which contains the modules configuration file. * * If not set, the module source code is loaded from the root of the directory. */ sourceRootPath?: string }/** * An optional subpath of the directory which contains the modules configuration file. * * If not set, the module source code is loaded from the root of the directory. */ export type DirectoryAsModuleSourceOpts { sourceRootPath?: string }核心语义由两句话构成属性类型可选性含义sourceRootPathstring可选目录中一个可选子路径该子路径内包含模块的配置文件dagger.json若未设置则从目录根目录加载模块源码需要说明的是这个类型本身只有一个sourceRootPath属性文档与源码均未定义其他选项与之相近的DirectoryAsWorkspaceOpts则包含cwd选项见 sdk/typescript/src/api/client.gen.ts#L1305-L1310两者不要混淆。sourceRootPath 的典型使用场景sourceRootPath的存在是为了解决一个非常实际的工程问题一个目录尤其是 Git 仓库或大目录中可能嵌套着多个 Dagger 模块每个模块有自己的dagger.json配置目录。当你想加载其中的某一个子模块时直接用整个目录加载会失败或加载到错误的位置此时通过sourceRootPath显式指到模块配置所在的子目录即可。典型场景包括Monorepo 子模块加载仓库根目录不是模块根模块位于services/backend或modules/foo等子目录用sourceRootPath精确指向该子目录目录内容动态生成通过dag.container().from(...).directory(...)或host().directory(...)得到目录后再调用asModuleSource()此时根目录往往只是上下文真正的模块配置在子路径中多模块共享上下文同一个上下文目录下包含多个可独立发布的模块逐个用不同sourceRootPath加载成独立的ModuleSource。在 Directory 上使用 asModuleSource()DirectoryAsModuleSourceOpts由Directory类型上的asModuleSource()方法接收。SDK 中的方法签名如下见 sdk/typescript/src/api/client.gen.ts#L6847-L6856/** * Load the directory as a Dagger module source * param opts.sourceRootPath An optional subpath of the directory which contains the modules configuration file. * * If not set, the module source code is loaded from the root of the directory. */ asModuleSource (opts?: DirectoryAsModuleSourceOpts): ModuleSource { const ctx this._ctx.select(asModuleSource, { ...opts }) return new ModuleSource(ctx) }从实现看asModuleSource()是一个懒加载的图查询构造它将当前Directory的查询上下文select到asModuleSource字段并把opts中的参数即sourceRootPath作为 GraphQL 参数传入返回一个ModuleSource句柄。它不会立即执行任何 IO真正的加载与校验发生在引擎求值该ModuleSource时。示例一从目录根加载模块最简单的情形dagger.json就位于目录根import { connect } from dagger.io/dagger await connect(async (client) { // 假设 ~/my-module 根目录下存在 dagger.json const source client .host() .directory(/home/user/my-module) .asModuleSource() // 不传 opts默认从目录根加载 // 将模块源码安装到当前会话供后续调用 await client.module().install(source) })此时sourceRootPath为undefined引擎侧会将其归一化为.详见下文实现解析。示例二加载嵌套子模块当模块配置位于子目录时import { connect } from dagger.io/dagger await connect(async (client) { const source client .host() .directory(/workspace/monorepo) .asModuleSource({ sourceRootPath: services/backend, // dagger.json 位于该子目录 }) await client.module().install(source) })注意sourceRootPath语义是“模块配置所在的子目录”而不是“源码根目录”。引擎会到目录/services/backend下查找配置文件并在解析dagger.json的root/include等字段后确定最终的源码根sourceSubpath。引擎侧实现参数如何被解析与校验为了让文章不止于 API 表面下面深入 Dagger 引擎源码看sourceRootPath从 GraphQL 参数到模块源实例的完整链路。字段注册asModuleSource 与 asModule在 core/schema/modulesource.go#L79-L95 中Directory类型同时注册了两个语义相同的字段dagql.Fields[*core.Directory]{ dagql.NodeFunc(asModule, s.directoryAsModule). Doc(Load the directory as a Dagger module source). Args( dagql.Arg(sourceRootPath).Doc( An optional subpath of the directory which contains the modules configuration file., If not set, the module source code is loaded from the root of the directory.), ), dagql.NodeFunc(asModuleSource, s.directoryAsModuleSource). WithInput(dagql.PerClientInput). Doc(Load the directory as a Dagger module source). Args( dagql.Arg(sourceRootPath).Doc( An optional subpath of the directory which contains the modules configuration file., If not set, the module source code is loaded from the root of the directory.), ), }.Install(dag)asModuleSource是当前 SDK 生成的 TypeScript 客户端实际使用的入口asModule是别名/旧入口两者参数与文档完全一致因此DirectoryAsModuleSourceOpts.sourceRootPath与这里的dagql.Arg(sourceRootPath)一一对应。directoryAsModuleSource 的加载逻辑核心实现位于 core/schema/modulesource.go#L905-L952。关键行为func (s *moduleSourceSchema) directoryAsModuleSource( ctx context.Context, contextDir dagql.ObjectResult[*core.Directory], args directoryAsModuleSourceArgs, ) (inst dagql.Result[*core.ModuleSource], err error) { sourceRootSubpath : args.SourceRootPath if sourceRootSubpath { sourceRootSubpath . } dirSrc : core.ModuleSource{ ConfigExists: true, ConfigFilename: modules.Filename, SourceRootSubpath: sourceRootSubpath, ContextDirectory: contextDir, Kind: core.ModuleSourceKindDir, DirSrc: core.DirModuleSource{ OriginalContextDir: contextDir, OriginalSourceRootSubpath: args.SourceRootPath, }, } // ... configFilename, found, err : moduleConfigInDir(ctx, core.DirectoryStatFS{Dir: contextDir}, filepath.Join(/, dirSrc.SourceRootSubpath)) if err ! nil { return inst, fmt.Errorf(failed to find dir module config: %w, err) } if !found { if !args.AllowNotExists { return inst, fmt.Errorf(dir module source does not contain a dagger config file) } dirSrc.ConfigExists false return dagql.NewResultForCurrentCall(ctx, dirSrc) } // ... }从这段代码可以得到几条对使用者有实际意义的结论默认值归一化sourceRootPath为空字符串TypeScript 中即undefined时引擎将其归一化为.也就是目录根印证了“未设置则从根目录加载”的文档描述配置文件查找引擎会在sourceRootPath对应的子路径下查找模块配置文件modules.Filename即dagger.json查找范围由 moduleConfigInDir 实现找不到配置会报错如果指定了sourceRootPath但该子路径下没有dagger.json且AllowNotExists未开启加载会失败并返回dir module source does not contain a dagger config file。这也是最容易踩的坑——sourceRootPath必须精确指向包含dagger.json的目录快照路径记录DirModuleSource同时记录OriginalSourceRootSubpath用户传入的原始值可能为空与归一化后的SourceRootSubpath为后续sourceSubpath/originalSubpath查询见 core/schema/modulesource.go#L102-L106提供依据。模块配置的解析与 sourceSubpath找到配置文件后引擎调用s.loadConfiguredModuleSource(ctx, dirSrc)读取dagger.json并解析root、include、exclude等字段从而确定模块真正的源码根sourceSubpath。也就是说sourceRootPath决定配置文件的查找位置默认.dagger.json中的root字段决定源码相对于配置目录的位置ModuleSource.sourceSubpath返回“相对于上下文目录的模块源码目录”路径见 core/schema/modulesource.go#L102-L103。相关参考与延伸阅读类型别名在 TypeScript SDK 参考中的正式条目DirectoryAsModuleSourceOpts本文档Directory类参考其中包含asModuleSource、asModule等方法列表Directory.mdTypeScript SDK 参考索引index.mdSDK 中类型与方法生成的实现sdk/typescript/src/api/client.gen.ts引擎侧 GraphQL 字段注册与加载实现core/schema/modulesource.go模块配置dagger.json的定义与解析core/modules/config.go小结DirectoryAsModuleSourceOpts虽只有一个sourceRootPath可选属性却是把任意Directory转换为 Dagger 模块源码的钥匙。理解它的默认值目录根与查找语义定位dagger.json所在子目录可以帮助你在 monorepo、动态生成目录等场景下精准加载模块源码而引擎侧 directoryAsModuleSource 的实现则揭示了“找不到配置文件即报错”的边界行为值得在实际使用中特别留意。【免费下载链接】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),仅供参考
返回列表