golangci-lint配置必须严格满足文件名(.golangci.yml)、位置(与go.mod同级)、YAML语法(顶格、空格缩进、冒号后空格)及语义(run和linters为必需顶层字段,启用staticcheck/unused等关键linter并禁用golint)才生效。

golangci-lint 配置文件不是“写对就行”,而是必须满足 YAML 语法、字段层级和语义约束,否则工具直接静默忽略或报错退出——最常见的现象是改了 .golangci.yml 却没生效,根本原因往往是缩进错误、键名拼错,或启用了已弃用的 linter。
配置文件名和位置必须严格匹配
工具只认这几个文件名(按优先级顺序):.golangci.yml、.golangci.yaml、.golangci.toml、.golangci.json。实际项目中建议统一用 .golangci.yml,放在项目根目录(即 go.mod 所在目录)。如果放错位置(比如放在 cmd/ 子目录下),golangci-lint run 默认不会向上查找,检查会退回到内置默认规则。
- 运行时可通过
-c显式指定路径,例如:golangci-lint run -c config/.golangci.yml - 不加
-c时,它不会自动扫描父目录;即使当前在子包里执行,也只从当前目录开始找 - 文件名大小写敏感:Linux/macOS 下
.GolangCI.yml或golangci.yml均无效
run 和 linters 是唯二必需的顶层字段
YAML 文件可以极简,但至少得有 run 和 linters 这两个 section。空配置或只写 linters-settings 不会报错,但等效于没配——工具会回退到全量启用默认 linter(约 20+ 个),可能触发大量误报。
-
run至少要设timeout(如timeout: 2m),避免 CI 中因大项目卡死 -
linters必须显式声明enable列表,哪怕只启一个:enable: [govet] - 不要写
enable-all: true—— 它会启用所有 100+ linter,包括实验性、高误报率的,CI 极易失败 - 禁用某个 linter 要用
disable,而不是删掉它;否则下次升级 golangci-lint 后可能被默认启用
常见 linter 的启用陷阱
不是所有 linter 都适合开箱即用。有些已废弃,有些依赖额外环境,有些默认行为与团队规范冲突。
-
golint已归档,2021 年起官方明确不推荐,配置里出现会报 warning;应换用revive(需单独安装并加入linters.enable) -
goconst对字符串重复敏感,但常把日志模板、SQL 片段误判为“硬编码”,建议关闭或调高阈值:linters-settings.goconst.min-len: 4 -
errcheck检查未处理错误,但fmt.Println等无副作用调用会被误报;可用exclude-rules过滤:- linter: errcheck pattern: "fmt.Print.*" -
gofmt和goimports属于格式类 linter,不报 error/warning,只在加--fix时生效;若只想检查不修复,它们实际不输出任何 issue
跳过文件和目录不能只靠 skip-dirs
skip-dirs 只跳过整个目录,对单个生成文件(如 pb.go、mock_*.go)无效。真正健壮的做法是组合使用:
-
skip-dirs用于vendor、testdata、docs等整目录排除 -
skip-files用正则匹配文件名,例如:- ".*_test\.go$"(跳过所有 test 文件) -
exclude-rules按 issue 内容过滤,比如屏蔽 protobuf 生成代码里的unused报告:- linter: unused pattern: "xxx_pb\.go" - 注意:正则需用双引号包裹,且 Go 正则引擎不支持
d,要用[0-9]
最易被忽略的是 modules-download-mode: readonly —— 如果项目用 Go Modules 且依赖私有仓库,不设这个,golangci-lint 在 CI 中可能因权限问题拉不到模块而 panic,而不是优雅报错。它不是可选项,而是稳定运行的隐性前提。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











