golangci-lint 默认离线运行,静默失败多因配置未生效:.golangci.yml 必须与 go.mod 同级、仅用空格缩进;需禁用 typecheck 和 modules-download-mode,显式启用 staticcheck 并设 checks: ["all"],移除已归档的 golint。

golangci-lint 本地运行无需“离线模式”开关——它默认就是离线工作的,但配置错误会导致它静默失败或误连网络。 它不依赖远程服务,所有检查都在本地完成;所谓“离线问题”,90% 是因配置未加载、模块下载触发、或误启了需联网的 linter(如 gomodguard 的某些规则)。
为什么 run 没输出?大概率配置根本没生效
golangci-lint 只认一个路径和名字:.golangci.yml 必须与 go.mod 同级。放在 src/ 下、写成 .golangci.yaml、或用 Tab 缩进,都会导致它安静跳过配置,退回到默认启用列表(含已归档的 golint)。此时你改了 staticcheck 设置也毫无反应。
- 运行
golangci-lint run --debug,看输出里Config:行是否指向你预期的文件路径 - 确认当前目录下有
go.mod,且.golangci.yml就在它旁边 - 用
yamlfmt或在线 YAML 验证器检查缩进——只允许空格,不能有 Tab
禁止任何网络行为:关掉 modules-download-mode 和可疑 linter
默认情况下,golangci-lint run 可能尝试解析依赖并触发 go mod download,尤其当配置缺失或 typecheck 被启用时。这不是“联网检查”,而是卡在模块拉取上,表现像假死或超时。
- 在
.golangci.yml的run段强制设为:modules-download-mode: readonly - 禁用
typecheck(它和go build冗余,且在 Go 1.21+ 下易 panic):linters.disable: ["typecheck"] - 移除或禁用明确需联网的 linter,例如
gomodguard(除非你真需要校验 module proxy 策略)
本地运行必须显式启用 staticcheck 才有意义
默认启用的 linter(如 govet、errcheck)只能捕获基础问题;staticcheck 才能发现 time.Now().Unix() > 0 这类恒真判断、循环中滥用 time.After(SA1021)、调用已弃用 API(SA1019)等高危问题。不启用它,本地 run 几乎等于白跑。
- 在
.golangci.yml中加:linters.enable: ["staticcheck"] - 再补上:
linters-settings.staticcheck.checks: ["all"],否则 SA1019 等关键规则仍关闭 - 别留
golint:它已归档,不支持泛型,且和revive规则重叠误报高
真正容易被忽略的是:golangci-lint 不会警告你“配置失效”,它只会沉默地用默认规则跑——而默认规则在 Go Modules 项目里大概率包含冲突项。务必用 --debug 确认配置路径,再用 run ./... 加具体包路径测试输出是否真实出现。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











