The Go Blog
ワークスペースに慣れる
Go 1.18では、Goにワークスペースモードが追加され、複数のモジュールを同時に操作できるようになりました。
ダウンロードページからGo 1.18を入手できます。リリースノートには、すべての変更点に関する詳細が記載されています。
ワークスペース
Go 1.18のワークスペースを使用すると、各モジュールのgo.modファイルを編集することなく、複数のモジュールを同時に操作できます。ワークスペース内の各モジュールは、依存関係を解決する際にメインモジュールとして扱われます。
以前は、あるモジュールに機能を追加し、それを別のモジュールで使用するには、最初のモジュールの変更を公開するか、依存するモジュールのgo.modファイルをローカルで未公開のモジュール変更用のreplaceディレクティブで編集する必要がありました。エラーなしで公開するためには、最初のモジュールにローカルの変更を公開した後、依存するモジュールのgo.modファイルからreplaceディレクティブを削除する必要がありました。
Goワークスペースでは、ワークスペースディレクトリのルートにあるgo.workファイルを使用して、すべての依存関係を制御します。go.workファイルには、個々のgo.modファイルを上書きするuseおよびreplaceディレクティブが含まれているため、各go.modファイルを個別に編集する必要はありません。
ワークスペースを作成するには、モジュールディレクトリのリストをスペース区切りの引数としてgo work initを実行します。ワークスペースに、作業中のモジュールが含まれている必要はありません。initコマンドは、ワークスペース内のモジュールをリストするgo.workファイルを作成します。引数なしでgo work initを実行すると、空のワークスペースが作成されます。
ワークスペースにモジュールを追加するには、go work use [moddir]を実行するか、go.workファイルを手動で編集します。go work use -r .を実行すると、引数ディレクトリ内のgo.modファイルを持つディレクトリがワークスペースに再帰的に追加されます。ディレクトリにgo.modファイルがない場合、または存在しなくなった場合、そのディレクトリのuseディレクティブはgo.workファイルから削除されます。
go.workファイルの構文はgo.modファイルに似ており、次のディレクティブが含まれています。
go: Goツールチェーンのバージョン。例:go 1.18use: ディスク上のモジュールをワークスペース内のメインモジュールのセットに追加します。引数は、モジュールのgo.modファイルを含むディレクトリへの相対パスです。useディレクティブは、指定されたディレクトリのサブディレクトリ内のモジュールは追加しません。replace:go.modファイル内のreplaceディレクティブと同様に、go.workファイル内のreplaceディレクティブは、モジュールの_特定のバージョン_、またはモジュールの_すべてのバージョン_の内容を、他の場所で見つかった内容に置き換えます。
ワークフロー
ワークスペースは柔軟であり、さまざまなワークフローをサポートします。以下のセクションでは、最も一般的と思われるものの簡単な概要を説明します。
アップストリームモジュールに機能を追加し、自分のモジュールで使用する
-
ワークスペース用のディレクトリを作成します。
-
編集したいアップストリームモジュールをクローンします。
-
アップストリームモジュールのローカルバージョンに機能を追加します。
-
ワークスペースフォルダで
go work init [path-to-upstream-mod-dir]を実行します。 -
アップストリームモジュールに追加された機能を実装するために、自分のモジュールに変更を加えます。
-
ワークスペースフォルダで
go work use [path-to-your-module]を実行します。go work useコマンドは、自分のモジュールへのパスをgo.workファイルに追加します。go 1.18 use ( ./path-to-upstream-mod-dir ./path-to-your-module ) -
アップストリームモジュールに追加された新機能を使用して、自分のモジュールを実行およびテストします。
-
新機能を使用してアップストリームモジュールを公開します。
-
新機能を使用して自分のモジュールを公開します。
同じリポジトリ内の複数の相互依存モジュールを操作する
同じリポジトリ内で複数のモジュールを操作する場合、各モジュールのgo.modファイルでreplaceディレクティブを使用する代わりに、go.workファイルがワークスペースを定義します。
-
ワークスペース用のディレクトリを作成します。
-
編集したいモジュールを含むリポジトリをクローンします。
useディレクティブで各モジュールへの相対パスを指定するため、モジュールがワークスペースフォルダにある必要はありません。 -
ワークスペースディレクトリで
go work init [path-to-module-one] [path-to-module-two]を実行します。例:
example.com/x/toolsモジュール内の他のパッケージに依存するexample.com/x/tools/groundhogを操作しています。リポジトリをクローンし、ワークスペースフォルダで
go work init tools tools/groundhogを実行します。go.workファイルの内容は次のようになります。go 1.18 use ( ./tools ./tools/groundhog )toolsモジュールで行われたローカルの変更は、ワークスペース内のtools/groundhogによって使用されます。
依存関係構成の切り替え
異なる依存関係構成でモジュールをテストするには、別々のgo.workファイルを持つ複数のワークスペースを作成するか、1つのワークスペースを保持し、単一のgo.workファイルで不要なuseディレクティブをコメントアウトすることができます。
複数のワークスペースを作成するには
- 異なる依存関係のニーズに合わせて、別々のディレクトリを作成します。
- 各ワークスペースディレクトリで
go work initを実行します。 go work use [path-to-dependency]を介して、各ディレクトリ内に必要な依存関係を追加します。- 各ワークスペースディレクトリで
go run [path-to-your-module]を実行して、そのgo.workファイルで指定された依存関係を使用します。
同じワークスペース内で異なる依存関係をテストするには、go.workファイルを開き、必要な依存関係を追加またはコメントアウトします。
まだGOPATHを使用していますか?
ワークスペースを使用すると考えが変わるかもしれません。GOPATHユーザーは、GOPATHディレクトリのベースにあるgo.workファイルを使用して依存関係を解決できます。ワークスペースはすべてのGOPATHワークフローを完全に再現することを目的としていませんが、モジュールの利点を提供しつつ、GOPATHの利便性の一部を共有する設定を作成できます。
GOPATHのワークスペースを作成するには
GOPATHディレクトリのルートでgo work initを実行します。- ワークスペースでローカルモジュールまたは特定のバージョンを依存関係として使用するには、
go work use [path-to-module]を実行します。 - モジュールの
go.modファイル内の既存の依存関係を置き換えるには、go work replace [path-to-module]を使用します。 - GOPATHまたは任意のディレクトリ内のすべてのモジュールを追加するには、
go work use -rを実行して、go.modファイルを持つディレクトリをワークスペースに再帰的に追加します。ディレクトリにgo.modファイルがない場合、または存在しなくなった場合、そのディレクトリのuseディレクティブはgo.workファイルから削除されます。
注: ワークスペースに追加したい
go.modファイルのないプロジェクトがある場合は、そのプロジェクトディレクトリに移動し、go mod initを実行してから、go work use [path-to-module]で新しいモジュールをワークスペースに追加してください。
ワークスペースコマンド
go work initとgo work useに加えて、Go 1.18ではワークスペース用に次のコマンドが導入されています。
go work sync:go.workファイルの依存関係を各ワークスペースモジュールのgo.modファイルにプッシュバックします。go work edit: 主にツールやスクリプトで使用するために、go.workを編集するためのコマンドラインインターフェイスを提供します。
モジュール対応ビルドコマンドと一部のgo modサブコマンドは、GOWORK環境変数を調べて、ワークスペースコンテキストにあるかどうかを判断します。
GOWORK変数が.workで終わるファイルへのパスを指定している場合、ワークスペースモードが有効になります。使用されているgo.workファイルを特定するには、go env GOWORKを実行します。goコマンドがワークスペースモードでない場合、出力は空です。
ワークスペースモードが有効になると、go.workファイルが解析され、ワークスペースモードの3つのパラメータ(Goバージョン、ディレクトリのリスト、置換のリスト)が決定されます。
ワークスペースモードで試すいくつかのコマンド(何をするか既に知っていることが前提です!):
go work init
go work sync
go work use
go list
go build
go test
go run
go vet
エディタの操作性の向上
Goの言語サーバーgoplsとVSCode Go拡張機能のアップグレードにより、LSP互換エディタで複数のモジュールを扱う作業がスムーズでやりがいのあるものになったことに特に興奮しています。
参照の検索、コード補完、定義への移動は、ワークスペース内のモジュール間で機能します。goplsのバージョン0.8.1では、go.workファイルに対する診断、補完、書式設定、ホバーが導入されました。これらのgopls機能は、任意のLSP互換エディタで利用できます。
エディタ固有のメモ
- 最新のvscode-goリリースでは、GoステータスバーのQuick Pickメニューを介してワークスペースの
go.workファイルに素早くアクセスできます。

- GoLandはワークスペースをサポートしており、
go.workファイルのシンタックスハイライトとコード補完を追加する予定です。
異なるエディタでgoplsを使用する方法の詳細については、goplsのドキュメントを参照してください。
次は何ですか?
- Go 1.18をダウンロードしてインストールします。
- Goワークスペースチュートリアルでワークスペースを試してみてください。
- ワークスペースで問題が発生した場合、または何か提案したい場合は、課題を提出してください。
- ワークスペースメンテナンスドキュメントを読んでください。
go work init、go work syncなどを含む単一モジュールの外での作業のためのモジュールコマンドを探索してください。
次の記事: ジェネリクスを使用すべき時
前の記事: Goがサプライチェーン攻撃を軽減する方法
ブログインデックス