Go Modules 项目必须配置 .golangci.yml,否则 golangci-lint 会因默认启用弃用 linter、AST 不兼容、依赖解析失败等问题导致卡顿、报错或 CI 中断;最小可用配置需包含 run.timeout、run.modules-download-mode: readonly 和 linters.enable 列表。

Go Modules 项目不配 .golangci.yml 就会出问题
golangci-lint 在 Go Modules 项目里不会自动适配模块语义,它默认回退到启用 golint、typecheck 等已弃用或冗余 linter 的旧配置。后果很直接:运行 golangci-lint run 卡住超过 2 分钟、报 failed to load program: typechecker error、或在 CI 中因 govet 检查失败中断。
根本原因在于:Go Modules 本身不提供 lint 规则,而 golangci-lint v1.54+ 的“默认配置”仍硬编码了与 Go 1.21+ AST 解析不兼容的检查项。Modules 项目依赖树更复杂,没显式配置就等于裸奔。
-
run.modules-download-mode: readonly必须设,否则 lint 过程可能意外改写go.sum - 生成代码(如
pb.go、mock_*.go)必须用skip-dirs或exclude-rules显式排除,否则errcheck会对proto.Unmarshal报错 - 多模块仓库(monorepo)下,
run.cwd和issues.exclude要按子模块路径单独约束,不能只靠根目录一份配置
.golangci.yml 最小可用配置要包含哪三项
以下配置覆盖 90% Go Modules 项目的实际需求,且与 Go 1.21–1.23 兼容:
run:
timeout: 2m
modules-download-mode: readonly
skip-dirs:
- vendor
- testdata
- internal/gen
<p>linters:
enable:</p><ul><li>govet</li><li>errcheck</li><li>staticcheck</li><li>unused</li><li>ineffassign
disable:</li><li>golint</li><li>typecheck</li></ul><p>linters-settings:
staticcheck:
checks: ["all"]
errcheck:
check-type-assertions: true
check-blank: false说明:
立即学习“go语言免费学习笔记(深入)”;
-
staticcheck: checks: ["all"]是显式开启全部检查(含SA1019弃用警告),比默认更严格 -
errcheck.check-blank: false避免对_ = os.Remove()类写法误报 -
golint已归档,官方明确不维护;typecheck与go build冗余,且易在 Modules 下 panic
GoLand 里怎么让不同环境用不同 .golangci.yml
GoLand 本身不支持“按环境切换配置文件”,它只认一个配置路径。所谓“多环境 lint”,其实是靠项目结构隔离,不是靠 IDE 动态加载:
- 在 monorepo 中,每个子模块(如
cmd/api、pkg/storage)应有自己独立的.golangci.yml,并通过run.cwd指向对应目录 - IDE 设置中勾选「使用配置」后,填入的路径必须是绝对路径或相对于项目根的固定路径,无法写成
.golangci.${APP_ENV}.yml这类变量形式 - CI 流水线里可分别执行:
cd cmd/api && golangci-lint run -c .golangci.yml和cd pkg/storage && golangci-lint run -c .golangci.yml
强行想在本地模拟“环境切换”?只能手动改 .golangci.yml 文件内容,或用 shell alias 切换软链接:ln -sf .golangci.dev.yml .golangci.yml —— 但 GoLand 不会自动重载,得重启分析器或手动点击「重新运行检查」。
CI 中跑多环境 lint 容易漏掉的关键点
CI 脚本里写 golangci-lint run 很容易忽略上下文一致性:
- 没加
--fix时,staticcheck报的SA1019(使用弃用 API)不会自动修复,需人工介入 - 没指定
-c参数时,它会在当前工作目录向上找第一个.golangci.yml,如果子模块没配,就会 fallback 到根目录配置,导致规则不一致 - 并行执行多个
golangci-lint实例时,若共用缓存目录(cache-dir默认是$HOME/.cache/golangci-lint),可能互相干扰;建议用cache-dir: ./tmp/golangci-cache隔离 - GoLand 本地看到的警告,CI 里没出现?大概率是 IDE 用了自己的
GOPATH或GOROOT,而 CI 容器里 Go 版本不同,staticcheck的检查行为会有差异
最常被跳过的动作:在 CI 的 lint 步骤前,先运行 go mod download。否则 golangci-lint 可能因模块未下载全而卡死或误报类型错误。


















