Go Modules项目必须显式配置.golangci.yml,否则golangci-lint会回退到启用已归档的golint、冗余的typecheck等过时linter,默认配置在Go 1.21+下易触发typechecker error、panic或超时卡死。

为什么不能直接用默认配置
Go Modules 项目里不写 .golangci.yml,等于没配——golangci-lint 会退回到启用 golint(已归档)、typecheck(与 go build 冗余)等过时 linter 的默认集。这些在 go 1.21+ 下极易触发 failed to load program: typechecker error 或卡死超 2 分钟。
-
golint已被官方弃用,AST 解析兼容性差,CI 中常 panic -
typecheck和go vet功能重叠,且在多模块下易因导入解析失败中断 - 默认不设
timeout,大型项目可能无限 hang 住 - 输出格式是带颜色的终端文本,CI 工具完全无法解析
最简可用配置长什么样
以下内容可直接保存为项目根目录的 .golangci.yml,无冗余、无陷阱,覆盖基础质量门禁:
run:
timeout: 2m
modules-download-mode: readonly
skip-dirs:
- vendor
- testdata
- internal/gen
- mocks
<p>linters:
enable:</p>
- govet
- errcheck
- staticcheck
- unused
- gosimple
- ineffassign disable:
- golint
- typecheck
output: formats:
- format: github-actions path: stdout print-issued-lines: true
issues: max-issues-per-linter: 0 max-same-issues: 0
-
skip-dirs必须显式列出生成代码目录(如internal/gen),否则errcheck会对proto.Unmarshal报未处理错误 -
github-actions格式让 GitHub CI 能自动生成行级注释,本地跑也可以用colored-line-number -
max-issues-per-linter: 0禁用截断,避免staticcheck查出 51 条就只报前 50 条
多模块项目怎么避免配置失效
单个 .golangci.yml 放根目录,对 services/auth 或 libs/logging 这类子模块完全无效——golangci-lint 默认只读当前工作目录下的配置,且不支持路径通配继承。
- 每个含
go.mod的子目录下都得放一份.golangci.yml -
run.cwd必须设为.(相对当前模块根),否则会跨模块扫描 -
issues.exclude路径要写绝对子模块路径,例如services/auth/internal/gen/.*,不能写internal/gen/.* - 子模块配置中
go:版本建议显式声明(如go: "1.21"),避免因 GOPATH 模式误判
CI 中自动修复要格外小心
--fix 参数只应在本地 pre-commit 或 IDE 中启用;CI 流水线里加 --fix 是反模式。
-
--fix只对部分 linter 生效(如gofumpt、revive),多数静态分析器不支持修复 - CI 中自动改代码会污染提交历史,破坏 PR 的可审查性
- 若真需修复,应走
pre-commithook +git add -u && git commit --amend流程,而非让 CI 动手 - GitHub Actions 中若要用
--fix,必须搭配if: github.event_name == 'pull_request'和人工 approve,否则易引发意外变更
最小化不是删到只剩一个 linter,而是删掉所有「默认开着但实际有害」的项;真正容易被忽略的是:模块边界必须靠配置显式声明,而不是靠工具猜。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











