チュートリアル: マルチモジュールワークスペースの使用を開始する

このチュートリアルでは、Go のマルチモジュールワークスペースの基本を紹介します。マルチモジュールワークスペースを使用すると、複数のモジュールで同時にコードを記述していることを Go コマンドに伝え、それらのモジュール内のコードを簡単にビルドして実行できます。

このチュートリアルでは、共有マルチモジュールワークスペース内に 2 つのモジュールを作成し、それらのモジュール間で変更を加え、ビルドでの変更の結果を確認します。

注:他のチュートリアルについては、チュートリアルをご覧ください。

前提条件

  • Go 1.18 以降のインストール。
  • コードを編集するツール。 任意のテキストエディターで問題ありません。
  • コマンドターミナル. Go は Linux および Mac の任意のターミナル、および Windows の PowerShell または cmd でうまく動作します。

このチュートリアルには go1.18 以降が必要です。go.dev/dl のリンクを使用して、Go 1.18 以降の Go をインストールしていることを確認してください。

コード用のモジュールを作成する

まず、記述するコード用のモジュールを作成します。

  1. コマンドプロンプトを開き、ホームディレクトリに移動します。

    LinuxまたはMacの場合

    $ cd
    

    Windowsの場合

    C:\> cd %HOMEPATH%
    

    このチュートリアルの残りの部分では、$がプロンプトとして表示されます。使用するコマンドはWindowsでも機能します。

  2. コマンドプロンプトから、コード用のディレクトリ「workspace」を作成します。

    $ mkdir workspace
    $ cd workspace
    
  3. モジュールを初期化する

    この例では、golang.org/x/example モジュールに依存する新しいモジュール「hello」を作成します。

    hello モジュールを作成する

    $ mkdir hello
    $ cd hello
    $ go mod init example.com/hello
    go: creating new go.mod: module example.com/hello
    

    go get を使用して、golang.org/x/example/hello/reverse パッケージへの依存関係を追加します。

    $ go get golang.org/x/example/hello/reverse
    

    hello ディレクトリに次の内容で hello.go を作成する

    package main
    
    import (
        "fmt"
    
        "golang.org/x/example/hello/reverse"
    )
    
    func main() {
        fmt.Println(reverse.String("Hello"))
    }
    

    次に、hello プログラムを実行する

    $ go run .
    olleH
    

ワークスペースを作成する

このステップでは、モジュールを含むワークスペースを指定するために go.work ファイルを作成します。

ワークスペースを初期化する

workspace ディレクトリで、次を実行する

$ go work init ./hello

go work init コマンドは、go に対して、./hello ディレクトリ内のモジュールを含むワークスペース用の go.work ファイルを作成するように指示します。

go コマンドは、次のようになる go.work ファイルを生成します

go 1.18

use ./hello

go.work ファイルは go.mod と同様の構文を持ちます。

go ディレクティブは、Go に対して、ファイルを解釈する Go のバージョンを伝えます。これは go.mod ファイルの go ディレクティブと似ています。

use ディレクティブは、Go に対して、ビルドを行うときに hello ディレクトリ内のモジュールをメインモジュールとして使用するように伝えます。

したがって、workspace のどのサブディレクトリでもモジュールがアクティブになります。

ワークスペースディレクトリでプログラムを実行する

workspace ディレクトリで、次を実行する

$ go run ./hello
olleH

Go コマンドは、ワークスペース内のすべてのモジュールをメインモジュールとして含めます。これにより、モジュールの外部でもモジュール内のパッケージを参照できます。モジュールまたはワークスペースの外部で go run コマンドを実行すると、go コマンドが使用するモジュールを認識しないため、エラーが発生します。

次に、golang.org/x/example/hello モジュールのローカルコピーをワークスペースに追加します。このモジュールは go.googlesource.com/example Git リポジトリのサブディレクトリに保存されています。次に、String の代わりに使用できる新しい関数を reverse パッケージに追加します。

golang.org/x/example/hello モジュールをダウンロードして変更する

このステップでは、golang.org/x/example/hello モジュールを含む Git リポジトリのコピーをダウンロードし、ワークスペースに追加し、hello プログラムから使用する新しい関数を追加します。

  1. リポジトリをクローンする

    ワークスペースディレクトリから、git コマンドを実行してリポジトリをクローンする

    $ git clone https://go.googlesource.com/example
    Cloning into 'example'...
    remote: Total 165 (delta 27), reused 165 (delta 27)
    Receiving objects: 100% (165/165), 434.18 KiB | 1022.00 KiB/s, done.
    Resolving deltas: 100% (27/27), done.
    
  2. ワークスペースにモジュールを追加する

    Git リポジトリは ./example にチェックアウトされました。golang.org/x/example/hello モジュールのソースコードは ./example/hello にあります。これをワークスペースに追加する

    $ go work use ./example/hello
    

    go work use コマンドは、新しいモジュールを go.work ファイルに追加します。次のようになります

    go 1.18
    
    use (
        ./hello
        ./example/hello
    )
    

    ワークスペースには、example.com/hello モジュールと golang.org/x/example/hello モジュールが含まれるようになりました。後者は golang.org/x/example/hello/reverse パッケージを提供します。

    これにより、go get コマンドでダウンロードしたモジュールキャッシュ内のパッケージのバージョンではなく、reverse パッケージのコピーに記述する新しいコードを使用できるようになります。

  3. 新しい関数を追加する。

    golang.org/x/example/hello/reverse パッケージに、数値を反転する新しい関数を追加します。

    workspace/example/hello/reverse ディレクトリに、次の内容を含む int.go という名前の新しいファイルを作成する

    package reverse
    
    import "strconv"
    
    // Int returns the decimal reversal of the integer i.
    func Int(i int) int {
        i, _ = strconv.Atoi(String(strconv.Itoa(i)))
        return i
    }
    
  4. 関数を使用するように hello プログラムを変更する。

    workspace/hello/hello.go の内容を次の内容に変更する

    package main
    
    import (
        "fmt"
    
        "golang.org/x/example/hello/reverse"
    )
    
    func main() {
        fmt.Println(reverse.String("Hello"), reverse.Int(24601))
    }
    

ワークスペースでコードを実行する

ワークスペースディレクトリから、次を実行する

$ go run ./hello
olleH 10642

Go コマンドは、コマンドラインで指定された example.com/hello モジュールを go.work ファイルで指定された hello ディレクトリ内で見つけ、同様に go.work ファイルを使用して golang.org/x/example/hello/reverse インポートを解決します。

go.work は、複数のモジュールをまたいで作業するために replace ディレクティブを追加する代わりに使用できます。

2 つのモジュールが同じワークスペースにあるため、一方のモジュールに変更を加え、それをもう一方のモジュールで使用するのは簡単です。

次のステップ

さて、これらのモジュールを適切にリリースするには、golang.org/x/example/hello モジュールを、たとえば v0.1.0 でリリースする必要があります。これは通常、モジュールのバージョン管理リポジトリのコミットにタグを付けることによって行われます。詳細については、モジュールリリースワークフローのドキュメントを参照してください。リリースが完了したら、hello/go.mod で golang.org/x/example/hello モジュールの要件を増やすことができます。

cd hello
go get golang.org/x/example/hello@v0.1.0

そうすることで、go コマンドはワークスペース外のモジュールを適切に解決できます。

ワークスペースについてさらに学ぶ

go コマンドには、チュートリアルで以前に見た go work init に加えて、ワークスペースを操作するためのいくつかのサブコマンドがあります。

  • go work use [-r] [dir] は、dir が存在する場合、dir 用の use ディレクティブを go.work ファイルに追加し、引数ディレクトリが存在しない場合は use ディレクトリを削除します。-r フラグは、dir のサブディレクトリを再帰的に調べます。
  • go work edit は、go mod edit と同様に go.work ファイルを編集します。
  • go work sync は、ワークスペースのビルドリストからワークスペースの各モジュールに依存関係を同期します。

ワークスペースと go.work ファイルの詳細については、Go Modules Reference の「Workspaces」を参照してください。