golangci-lint 默认跳过 vendor 目录,但若配置中显式设置 skip-dirs: []、disable-all: true 未补 skip-dirs,或路径书写错误(如 ./vendor),则会失效;推荐显式声明 run.skip-dirs: [vendor, testdata, docs]。

golangci-lint 默认就跳过 vendor,但得确认配置没覆盖它
默认行为是自动忽略 vendor/ 目录,前提是没在 .golangci.yml 里显式启用 disable-all: true 或清空 run.skip-dirs。很多人以为要手动加规则才跳过,其实只要不干扰默认逻辑,vendor/ 就不会被扫描。
常见踩坑点:
- 误删了默认的
skip-dirs配置,或写成skip-dirs: [](空数组),这会覆盖默认值,导致 vendor 被重新纳入检查 - 用了
disable-all: true+ 手动enable列表,却忘了补上skip-dirs块,此时默认跳过逻辑失效 - 路径写错,比如写成
- vendor但项目实际是./vendor或src/vendor——golangci-lint只认相对于配置文件所在目录的相对路径,且不支持通配符
明确在 .golangci.yml 中声明 skip-dirs 最稳妥
别依赖“默认”,直接写死更可控。尤其在 CI 或多 module 项目中,显式声明能避免环境差异带来的意外扫描。
推荐写法(放在 .golangci.yml 根层级):
立即学习“go语言免费学习笔记(深入)”;
run:
skip-dirs:
- vendor
- testdata
- docs注意:
-
skip-dirs是路径前缀匹配,vendor会同时跳过vendor/和myapp/vendor/这类嵌套结构(如果存在) - 不要写
./vendor或/vendor,前者多余,后者会被当作绝对路径处理失败 - 如果项目用到了
third_party或deps这类自定义第三方目录,也一并加进去
go list 过滤方式只适用于命令行临时绕过
像 golangci-lint run $(go list ./ | grep -v '/vendor/') 这种写法,本质是把包列表传给 linter,但它有硬伤:
- 无法跳过 vendor 下的测试文件(如
vendor/foo/bar/bar_test.go),而skip-dirs可以整目录屏蔽 - 依赖
go list输出格式稳定,一旦模块路径含vendor字样(如包名真叫myvendorutil),grep -v会误杀 - 不兼容
golangci-lint的缓存机制——每次都要重新 list + grep,失去增量分析优势 - CI 脚本里混用 shell 管道易出错,比如管道中断导致部分包漏检
第三方包不止 vendor,还有 replace 和本地路径依赖
vendor/ 只是第三方代码的一种存放形式。如果你在 go.mod 里用了 replace 指向本地路径(如 replace example.com/lib => ../lib),golangci-lint 仍会扫描 ../lib —— 它不识别 replace 语义,只按实际文件路径检查。
应对方法:
- 把本地 replace 的目录也加进
run.skip-dirs,例如- ../lib(注意是相对于配置文件的位置) - 更推荐做法:在开发阶段用
go.work管理多模块,让../lib成为独立 workspace 成员,然后在各自根目录放独立的.golangci.yml,避免跨目录扫描 - 切勿依赖
//nolint注释压制整个第三方包的告警——那等于放弃对这部分代码的质量把控
真正容易被忽略的是:vendor 目录被跳过,不代表它的构建约束(如 //go:build linux)和类型定义不会影响你本地包的分析结果。staticcheck 等 linter 仍会加载 vendor 中的符号来做类型推导,只是不检查其源码而已。


















