golangci-lint 不提供自动生成默认配置文件的功能;它仅在运行时加载 .golangci.yml,无配置时启用约20+内置linter但不导出YAML,--print-config 输出的是合并后生效配置而非可编辑模板,最稳妥方式是手写最小可用配置。

golangci-lint 不提供自动生成默认 .golangci.yml 的命令,它只在运行时按需加载配置文件;没有配置文件时,它会启用内置的默认 linter 列表(约 20+ 个),但这个默认集无法直接导出为 YAML。
为什么 run --print-config 不等于“生成配置”
很多人误以为 golangci-lint run --print-config 能输出可直接用的配置文件,其实它打印的是「当前生效的完整合并配置」——包括内置默认值 + 项目中已存在的 .golangci.yml + 命令行参数覆盖。如果项目根目录压根没有配置文件,--print-config 仍会输出一大段内容,但其中大量字段是空值或 null,不能直接当模板用。
- 它会包含你没显式配置、但 golangci-lint 内部设了默认值的字段(比如
run.timeout默认是1m,但不会写进输出) - 很多 linter 的子配置(如
gocyclo.min-complexity)在未手动设置时根本不出现在输出里 - 输出中混有内部调试字段(如
internal、presets展开结果),直接复制粘贴会导致解析失败
最靠谱的初始化方式:手写最小可用配置
别依赖生成,直接从一个精简、明确、可维护的起点开始。以下内容可直接保存为项目根目录下的 .golangci.yml:
run:
timeout: 3m
concurrency: 4
skip-dirs:
- vendor
- testdata
- mocks
<p>linters:
enable:</p>
- govet
- errcheck
- staticcheck
- unused
- ineffassign
- gosimple disable:
- golint # 已弃用,必须关掉
- typecheck # go build 已覆盖,冗余
linters-settings: govet: enable-all: true disable:
- fieldalignment # 通常不必要,且易误报
staticcheck:
checks: ["all"] # 启用 staticcheck 全部检查
- 这个配置禁用了过时/低价值 linter(
golint、typecheck),避免噪音 -
skip-dirs明确排除常见非源码目录,防止扫描卡死或误报 -
govet.enable-all: true是关键:默认 govet 只开几个基础检查,开全才真正有用 - 所有字段都是真实生效项,无冗余、无隐藏依赖
- 这个配置禁用了过时/低价值 linter(
容易被忽略的路径和权限问题
即使配置文件内容正确,golangci-lint 也可能静默跳过它:
- 文件名必须是
.golangci.yml(不是golangci.yaml、golang-ci.yml或其他变体) - 必须放在项目根目录(即
go.mod所在目录),否则工具找不到 - 确保文件编码是 UTF-8 无 BOM;Windows 上用记事本另存可能引入 BOM,导致解析失败
- 如果项目用了 Go Modules,但
go.mod不在当前目录,golangci-lint可能降级为 GOPATH 模式,导致配置不生效
验证是否真正在用你的配置:加一行非法 YAML(比如 xxx: : :),再运行 golangci-lint run —— 如果报 YAML 解析错误,说明配置已被加载;如果没报错,说明它根本没读到这个文件。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











