GoをVSCodeで快適に開発する:golangci-lint + gofumpt テンプレートの作り方
Updated Date: 2026/03/04 23:14
Go言語開発をVSCodeで真面目にやり始めて数ヶ月が経った。Linterのセットアップ・ファイル保存時の自動フォーマット・golangci-lintの競合解消など様々なハマりポイントを乗り越えたので、プロジェクトテンプレートとして公開した。
https://github.com/bon10/go-develop-template
このテンプレートが解決すること
VSCodeでGoを書き始めると、以下の問題によくぶつかる。
- 保存するたびにimport文の順序が変わる(golangci-lintとVSCodeのフォーマッタが競合)
- linterが大量にあって何を有効にすべきか分からない
gofmtだと物足りないがgofumptのセットアップ方法が分かりにくい- golangci-lintのバージョンとGoのバージョンの組み合わせで動かない
このテンプレートはこれらを全部解決済みの状態で使えるようにしてある。
前提環境
- Go 1.20以上
- VSCode + Go拡張機能
- golangci-lint(後述のインストール手順で入れる)
セットアップ手順
1. golangci-lint のインストール
1
2
3
4
5
# macOS
brew install golangci-lint
# Linux / Windows (WSL)
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
インストール後に golangci-lint --version でバージョンが表示されれば成功。
2. VSCode拡張機能の設定
.vscode/settings.json に以下を追加する。これが保存時自動フォーマットの核心部分。
1
2
3
4
5
6
7
8
9
10
11
{
"go.lintTool": "golangci-lint",
"go.lintFlags": ["--fast"],
"go.formatTool": "gofumpt",
"[go]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
}
}
}
3. .golangci.yml の設定
linterの設定は .golangci.yml にまとめる。特に重要なのが gofumpt の module-path の指定。これを忘れるとgolangci-lintとVSCodeでフォーマットが競合してしまう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
linters-settings:
gofumpt:
lang-version: '1.20'
module-path: your-module-name # go.mod の module名を入れる
linters:
enable:
- gofumpt
- golangci-lint
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- typecheck
- unused
disable:
# Go バージョンや他linterと競合するものをここでdisable
- exhaustruct
- gochecknoglobals
module-path にはプロジェクトの go.mod の先頭行 module xxx の xxx を入れる。これがないとgolangci-lintとgoplsでimport文の認識が微妙にズレ、保存/commit のたびに順序が変わる地獄になる。(golangci-lintのドキュメントにちゃんと書いてあるが見落としやすい)
工夫したポイント詳説
Linterとして golangci-lint を採用した理由
golangci-lint は100以上のlinterを内蔵している統合linter。これ1つ入れるだけで errcheck・staticcheck・govet など主要なlinterがまとめて使えるので、個別にインストールする必要がない。
どのlinterが何をチェックするかは以下が網羅的でとても参考になった: golangci-lintを理解する - golangci-lint に搭載されている linter を学ぶ
全linterを有効にすると競合や誤検知が出るので、動かしながらdisableを積み上げていくのが現実的。
gofumpt を採用した理由
標準の gofmt はimportの並び順などを整理してくれるが、ルールが緩め。gofumpt は gofmt の上位互換で、より厳格なルールでフォーマットしてくれる。チーム開発での「フォーマットのブレ」がなくなる。
gofumpt を使うにはLanguage Serverの gopls を立ち上げる必要があり、golangci-lintとの連携にも .golangci.yml への明示的な設定が必要。これを知らないと「保存するたびにファイルが変わる」という謎バグに悩まされる。
よくあるエラーと対処
「import文がコミットのたびに変わる」
→ .golangci.yml の gofumpt.module-path が設定されていない可能性が高い。go.mod のmodule名を確認して設定する。
「golangci-lintが動かない / タイムアウトする」
→ go.lintFlags: ["--fast"] を追加するとlintチェックを軽量化できる。CIでは --fast なしで、ローカルでは --fast ありにするのがおすすめ。
「gofumptがインストールされていないと言われる」
→ go install mvdan.cc/gofumpt@latest でインストール後、gopls を再起動する。
まとめ
GoのVSCode環境構築でハマりやすいポイントは「golangci-lintとgoplsのフォーマッタ競合」に集約される。.golangci.yml に module-path を明示するだけで大半の問題は解決するので、まずここを確認することをおすすめする。
テンプレートをforkして使ってもらえれば、ゼロから設定する手間が省けるはず。