• Go Modules 即将支持忽略机制!
  • 发布于 23小时前
  • 18 热度
    0 评论
Go 的模块依赖管理(Go modules),虽然已经推出了许多年。但一直存在着许多问题点和可以提高的空间。今天给大家带来分享的是 Go1.25 中将会对此做的一个较为实用的功能特性说明。

问题背景
在多语言的项目中,使用 Go modules 或相关工具链(例如:gopls)时会有一些令人头疼的问题点。
如下问题点:
1.在大型的多语言项目中(如:包含 node_modules、Bazel 构建输出等目录),使用命令如 go list ./..., go test, go vet 时,Go 工具链会遍历所有目录,即使很多目录与 Go 无关,导致执行缓慢。
2.gopls 在这些项目中索引无关目录,造成 CPU 和内存高耗,影响 IDE 性能。
3.如果被忽略的目录中带有示例 .go 文件,go mod tidy 会意外将它们纳入模块依赖,破坏模块一致性。
在大型的多语言项目中都稍显劣势。因为一旦出现类似的场景,gopls 通常会占用 VSCode 中的大量 CPU 资源。同时我的印象中 GoLand 建立索引就比较费时间。

社区自救
另辟蹊径
Go 社区中的组件,例如:goimports 已有各种临时方案。例如:在目录中放空 go.mod,使用工具特定 ignore 设置,如 gopls.directoryFilters 或 .goimportsignore)。但这些方法不统一且不易共享管理,且会造成 Go 模块依赖管理的生态碎片化,是不太好的。

借助标准(都被拒绝)
Go 社区在 issues 中其实讨论过多种方案。毕竟首先利用现有功能特性,有助于快速解决问题。但很可惜都被拒绝了。
具体如下:
1、使用 go.mod 文件指定要忽略的目录:
一开始被拒绝了,后面反水了。理由是因为 go.mod 并非像 NodeJS 中的 package.json 那样通用的配置文件。

2、使用单独的 .goignore 文件:
被拒绝。理由是这与 Rob 希望避免新增点文件的意愿相悖,尽管与其他工具(如 .dockerignore、.gitignore、.bazelignore 等)保持一致,但仍存在顾虑。担心增加新的顶级配置文件违背 Go 社区传统。

Go1.25 新特性:在 go.mod 中新增 ignore 指令
在 Go1.25 新特性中,将会正式支持在 go.mod 文件中使用 ignore 指令引用目录,来忽略某些目录。

例子介绍
示例的 go.mod 代码如下:
ignore (
  ./node_modules
  ./bazel‑out
  build_cache
)
支持两种路径语法:
./directory_name:模块根目录下的特定路径。例如:ignore ./foo/bar。
directory_name(无需使用 ./):模块内部任意位置的匹配目录名称及其子目录。例如:ignore foo。
注意事项
1、版本的要求上,在 go1.25 开始生效,会借助到 go.mod 中的 go 行版本进行识别。并会确保满足 Go 之前的兼容性保障措施。
2、另外在该 ignore 指令中,有些内容物需要特别注意:
   2.1被忽略的目录在构建和分析过程中被视作以 _ 或 . 开头的隐藏文件夹:
    .不会匹配 ./... 等包通配符。
     .gopls 和其他基于 go list 的工具将跳过扫描这些目录。
  2.2 即使忽略目录中的内容仍会被包含进模块压缩包(zip)中,以避免校验和、代理一致性问题。
总结
这个新的提案已经确定将在 Go1.25 释出,官方文档也已经修改。后续我们将可以在 go.mod 文件中通过 ignore 指令管理不需扫描或构建的目录。新版本发布后,将有效帮助到一些大型和多语言项目中的 Go 开发者。尤其是正在处理多语言或有大量自动生成目录的 Go 仓库,值得在 go.mod 中尝试添加 ignore 指令。有可能有意想不到的性能提高。
用户评论