Go Modules 项目必须显式配置同级 .golangci.yml,否则回退过时内置配置;需设 run.modules-download-mode: readonly、启用 staticcheck/unused 等核心 linter 并禁用 golint,子模块须 cd 进入后运行并显式指定配置。

Go Modules 项目必须显式配置 .golangci.yml
不配就等于没开——golangci-lint 在 Go Modules 项目中默认回退到过时的内置配置,会启用 golint(已归档)、typecheck(与 go build 冗余)等 linter,导致误报、卡死、甚至在 Go 1.21+ 下 panic。它不会自动识别 go.mod 并适配模块语义。
- 检查当前目录是否真有
go.mod:运行go list -m,输出应为模块路径,而非command-line-arguments - 配置文件名必须是
.golangci.yml(点开头 +yml小写),且与go.mod同级;.golangci.yaml或放在src/下均无效 - 多 module 仓库(monorepo)中,每个子模块目录都需独立放置一份
.golangci.yml,根目录配置不继承
run.modules-download-mode: readonly 是必需项
Modules 项目依赖解析更重,若 lint 过程意外触发 go mod download,可能修改 go.sum 或拉取非预期版本,破坏可重现构建。该配置强制跳过任何写操作,只读解析依赖树。
- CI 中尤其关键:避免因 GOPROXY 不稳定或网络抖动导致
golangci-lint run卡住或失败 - 配合
run.timeout: 2m使用,防止 staticcheck 等需要完整类型信息的 linter 因依赖未 resolve 而无限等待 - 不要用
run.skip-dirs: ["vendor"]代替——vendor模式与 Modules 冲突,Modules 项目本就不该有 vendor 目录
启用 staticcheck、unused 等核心 linter,禁用 golint
默认只开 govet 和 errcheck,根本查不出泛型误用、弃用 API(SA1019)、恒真判断(SA4006)等真实问题。必须显式启用真正暴露缺陷的检查器,并关掉已废弃工具。
- 最小有效组合:
enable: [govet, errcheck, staticcheck, unused, gosimple] - 必须
disable: ["golint"](注意引号和大小写),golint已归档,继续启用只会增加误报和维护负担 -
staticcheck的checks: ["all"]要显式写,否则默认不开启 SA1019 等关键规则 - 别碰
dupl(重复代码)和lll(行长),它们阈值难调、易误报,不适合卡 CI
子模块中运行必须 cd 进入再执行
不能从父目录用 golangci-lint run ./submodule——这会让工具把子模块当普通目录处理,不触发模块感知逻辑,直接报 no Go files 或 cannot find module。
- 正确做法:先
cd submodule,再golangci-lint run(自动找同级.golangci.yml) - 若想复用父级配置,加
-c ../.golangci.yml,但需确保该配置不含路径敏感项(如skip-dirs中的相对路径) - 子模块内
go.mod必须合法(含module github.com/xxx/yyy),且当前 shell 需设GO111MODULE=on和可用GOPROXY
配置生效最常被忽略的一点:CI 脚本里必须显式传参 --config=.golangci.yml,不能依赖自动发现——很多流水线因这一步漏掉,结果跑的是默认弃用集,问题一路漏到上线。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











