golangci-lint 配置文件必须命名为 .golangci.yml(大小写与扩展名严格匹配),置于 go.mod 所在目录(module 根);多 module 项目需为每个 module 单独配置,父目录不继承;修改后需手动运行 golangci-lint run 并重启 ide 或刷新缓存。

Go 项目里 golangci-lint 配置文件放哪、怎么生效
不写配置文件,golangci-lint 默认只跑几个基础 linter,基本没用。它默认找项目根目录下的 .golangci.yml(或 .golangci.yaml),找不到就用内置默认规则——这正是很多人配了却没效果的根源。
- 必须叫
.golangci.yml,大小写、扩展名都不能错;放在go.mod所在目录(即 module 根) - 如果项目有多个 module(比如 monorepo),每个 module 都得有自己的
.golangci.yml,父目录的不会自动继承 - 改完配置后要手动运行
golangci-lint run测试,IDE 插件(如 goland)可能缓存旧配置,需重启或手动刷新 - 常见错误:
invalid config file多半是 YAML 缩进错(YAML 对空格敏感)、用了 tab、或者字段拼错,比如把linters-settings写成linter-settings
golangci-lint 开启常用 linter 的最小安全组合
全开所有 linter 不现实:慢、误报多、部分规则和团队习惯冲突。推荐从「静态检查 + 基础风格 + 安全隐患」三层选 5–7 个真正落地的:
- 必开:
govet(Go 官方静态检查)、errcheck(检查未处理 Error)、staticcheck(最实用的通用检查器) - 建议开:
gosec(扫描硬编码密码、sql 注入等安全风险)、revive(可配置的 style 检查,比 deadcode/goconst 更可控) - 慎开:
dupl(代码重复检测,阈值难调,易误报)、lll(行长限制,纯风格问题,优先级低) - 配置示例片段:
linters-settings: gosec: excludes: - "G101" # 禁用硬编码凭据检查(若项目里真有 config 加密 key)
CI 中跑 golangci-lint 卡住或超时怎么办
本地快,CI 里跑不动,90% 是并发和缓存问题。默认 golangci-lint 会启用多核,但 CI 环境常受限于 CPU 或内存,反而更慢甚至 OOM。
- 加
--concurrency=2限制并行数(尤其 github Actions 默认 2 vCPU) - 用
--fast跳过耗时 linter(如goconst、gocyclo),只保留核心检查项 - 务必加
--timeout=2m,避免单次卡死拖垮整个 CI 流程 - 缓存
~/.cache/golangci-lint目录(GitHub Actions 可用actions/cache),否则每次重装依赖+重编译 linter,启动就 30 秒起 - 错误现象:
context deadline exceeded或日志停在loading cache—— 就是没设 timeout 或缓存失效
VS Code 里 golangci-lint 不提示、不标红
不是插件没装,而是 VS Code 的 Go 扩展默认用 gopls,它不读 .golangci.yml。要让 linter 结果进编辑器,得显式对接。
立即学习“go语言免费学习笔记(深入)”;
- 在 VS Code 设置中搜
go.lintTool,改成"golangci-lint" - 确保
go.lintFlags包含["--fast"](否则保存时卡顿) - 关键一步:删掉
go.lintFlags里的--out-format类参数——gopls只认默认 json 格式输出,自定义格式会导致解析失败、静默丢弃结果 - 重启 VS Code 后,打开一个 .go 文件,右下角状态栏应显示
golangci-lint,而不是gopls - 常见假象:终端里
golangci-lint run有报错,但编辑器不标红——八成是go.lintTool还设成"gopls"或路径没配对
配置这事,最难的不是写 YAML,是搞清哪个环节在接管 lint —— 是 IDE?是 pre-commit hook?还是 CI?三者配置不一致,问题就会在不同环境反复出现。别假设“配一次就全局生效”。