gomodonly 不存在,它是对 Go 模块默认行为的误解;Go 自 1.11 起默认启用模块模式,仅通过 go.mod/go.sum 解析依赖,真正的只读需靠文件权限、校验机制(go mod verify)和流程管控。

gomodonly 不是 Go 官方支持的编译选项,也不存在于 go build、go run 或任何 Go 工具链命令中。它既不是 flag,也不是环境变量,更不是 go.mod 的配置项。
如果你在某处看到 gomodonly,大概率是混淆了以下几种情况之一:
为什么搜不到 gomodonly?它根本不存在
Go 模块系统(自 1.11 起)默认启用,且没有“只读模块模式”这种开关。官方从未提供过类似 gomodonly 的 flag 或构建约束。
-
go build默认就只使用go.mod和go.sum解析依赖,不读取GOPATH下的源码(除非显式关闭模块模式:GO111MODULE=off) - 所谓“只读”,实际体现为:
go mod download下载后存入$GOPATH/pkg/mod,该目录默认不被修改;go mod tidy或go get才会变更go.mod/go.sum - 若你希望禁止任何模块写操作(如禁止
go mod edit、go get),只能靠外部手段:文件权限(chmod -w go.mod go.sum)、CI 环境变量拦截、或 wrapper 脚本检查命令参数
容易误认为是 gomodonly 的真实机制
真正起“只读依赖”作用的是以下行为,而非某个 magic flag:
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
-
GO111MODULE=on(默认) +go build:完全忽略$GOPATH/src,仅按go.mod解析,效果上“只读模块” -
go mod verify:校验go.sum是否与下载包匹配,失败则报错,防止篡改 —— 这才是真正的只读校验环节 -
go list -m all输出所有模块版本,但不修改任何文件,常被当“只读查看”用 - 某些 IDE 或 linter 插件(如 gopls)在配置中可能有
"experimental.useGomodOnly"类似字段,但这属于工具私有配置,非 Go 本身行为
想让依赖真正只读?这样做才有效
如果目标是防止意外修改依赖声明或引入新版本,关键不是找一个不存在的 flag,而是控制操作入口:
- CI/CD 中设
chmod -w go.mod go.sum,后续go mod tidy会直接失败 - 用
go mod download -json预加载依赖到本地缓存,再设GOPROXY=direct+GOSUMDB=off(慎用,绕过校验) - 在
go.mod顶部加注释说明:“DO NOT EDIT – managed by automation”,配合 pre-commit hook 拦截非法修改 - 避免使用
go get更新依赖;统一用go mod edit -require+go mod tidy,并确保后者在受控环境中执行
gomodonly 是个幻觉。Go 的模块只读性来自设计默认(不用 GOPATH)、校验机制(go.sum)和操作习惯(不随意 go get),而不是靠一个开关打开。最容易被忽略的点是:即使你“以为”启用了只读模式,只要 go.mod 文件可写,go mod tidy 就仍能改它——真正的只读,得从文件权限和流程卡点做起。

















