【问题标题】:Avoid writing "replace" for recursive dependency for local modules避免为本地模块的递归依赖编写“替换”
【发布时间】:2021-09-01 13:15:12
【问题描述】:

我正在尝试从 GOPATH 切换到 Go 模块。我有许多可执行文件使用的本地模块,出于安全原因,我无法将它们联机。

当模块“d”依赖三个包:“a”、“b”、“c”时,我需要在go.mod中“替换”:

replace m.y/a => /my/a
replace m.y/b => /my/b
replace m.y/c => /my/c

可执行文件导入包“d”时,并不直接导入a/b/c,但还是需要go.mod中的“replace a,b,c”:

replace m.y/a => /my/a
replace m.y/b => /my/b
replace m.y/c => /my/c

replace m.y/d => /my/d

这是设计使然还是我用错了?既然 a/b/c 已经在 d 的 go.mod 中了,为什么我必须为每个使用 d 的可执行文件重新编写它们?

go 模块是否支持从另一个 go.mod 导入?或者是否可以一次又一次地不写“替换a/b/c”?

【问题讨论】:

  • 如果不将替换放在导入“d”的模块中会发生什么?
  • 它是by design that only the main package can process replace directives。如果您的模块依赖项本身需要本地替换才能运行,它们就会被破坏。
  • @HymnsForDisco 如果删除可执行文件的 go.mod 中的“replace a/b/c”,则运行失败,例如“go: d requires a...”,它将尝试获取它们通过http获取请求,失败。
  • 我还建议仔细研究这些是否真的应该是四个独立的模块。

标签: go go-modules


【解决方案1】:

replace 不应该用于修复您的源代码。它用于修复您的构建配置,通常是临时的或仅用于开发环境。

如果您的包的导入字符串已永久更改,您需要更新导入它们的源代码。这就是为什么要避免重命名包或模块的原因之一。

【讨论】:

    【解决方案2】:

    这是设计使然。每https://golang.org/ref/mod#go-mod-file-replace

    replace 指令仅适用于主模块的go.mod 文件,在其他模块中被忽略。详情请见Minimal version selection

    如果您有一组紧密耦合的包,即使在本地或私有服务器上也无法发布,那么它们可能应该是单个模块 (module m.y) 的一部分,而不是拆分成单独的模块 (@987654326 @、module m.y/b 等)。

    另一方面,如果您可以在私有服务器上发布它们,那么您可以使用.netrc 文件为go 命令和GOPRIVATE 环境提供凭据变量来指示它不要在公共校验和数据库中查找校验和。详情请参阅https://golang.org/ref/mod#private-modules

    【讨论】:

      猜你喜欢
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多