できない.dev

Go の go.mod の replace でローカルモジュールが参照できない

replace の右辺がローカルパスのとき、参照先に go.mod が無い・バージョンを書いてしまう・相対パスの基準がズレる、のいずれかで効かないことが多い。
go.mod を用意し、ローカル参照ではバージョンを省くと解決する。

#go#go-mod#modules#replace#local-module

公開:

要約

replace は、あるモジュールの内容を別のパス(別モジュールやローカルディレクトリ)へ置き換えるディレクティブです。

ローカル開発で隣のディレクトリを参照したいのに効かない場合、原因はほぼ「参照先に go.mod が無い」「ローカル参照なのにバージョンを書いた」「相対パスの基準ズレ」の 3 つです。

ローカルパス(./../ 始まり)を右辺に書くときは、その先にモジュールルート(go.mod)が必要で、バージョンは省きます。

よくある原因

  1. 参照先に go.mod が無く、置き換え対象がモジュールとして認識されない。
  2. ローカルパス参照に v1.0.0 のようなバージョンを付けている。
  3. ../foo の基準が、編集している go.mod の場所と食い違っている。

解決策

1. 参照先に go.mod を用意する

cd ../foo
go mod init example.com/foo

ローカルパスの右辺は「go.mod を含むディレクトリ」である必要があります。

2. replace をローカルパスで書く(バージョンなし)

require example.com/foo v0.0.0
 
replace example.com/foo => ../foo

コマンドで追記しても同じです。

go mod edit -replace=example.com/foo=../foo

ローカルパス参照のときは右辺にバージョンを書かないのがポイントです。

3. 反映を確認する

go mod tidy
go list -m all

go list -m all の出力で対象が => ../foo に置き換わっていれば成功です。
公式の Go Modules Reference の replace 節も参照してください。

この記事は役立ちましたか?