导入含Git子模块依赖的Golang包时JSON文件读取失败求助
解决Go项目中Git子模块依赖未随包导入的问题
问题本质
Git子模块是Git层面的依赖管理机制,而Go的go mod是模块层面的,两者互不兼容。当repoC通过go get导入repoB时,只会拉取repoB本身的代码,不会自动拉取repoB关联的Git子模块(repoA),导致repoB的transformer.go找不到json/country.json文件。
可行解决方案
方案1:将JSON文件嵌入Go代码(推荐)
使用Go 1.16+的//go:embed指令,把JSON文件直接嵌入到repoB的二进制文件中,彻底消除对外部文件的依赖。
步骤:
- 在repoB的
transformer.go中修改代码:
package transformer import ( _ "embed" "encoding/json" ) // 直接嵌入JSON文件(路径为repoB内的相对路径,可将repoA的country.json复制到对应目录) //go:embed json/country.json var countryJSON []byte var countryMap map[string]int // 初始化时解析JSON生成查找表 func init() { if err := json.Unmarshal(countryJSON, &countryMap); err != nil { panic("解析country.json失败: " + err.Error()) } } // GetCountryID 根据国家名获取对应ID func GetCountryID(country string) (int, bool) { id, exists := countryMap[country] return id, exists }
- 如果要保留repoA作为单独仓库,可将repoA转为Go模块,在repoB中通过
go get引入,然后嵌入repoA模块内的JSON文件:
//go:embed github.com/your-username/repoA/json/country.json var countryJSON []byte
方案2:将repoA转为Go模块引入
把repoA作为独立的Go模块,让repoB通过go mod依赖它,而非Git子模块:
- 在repoA根目录执行:
go mod init github.com/your-username/repoA
- 在repoB根目录执行:
go get github.com/your-username/repoA
- 修改repoB的
transformer.go,从repoA的模块路径读取文件(配合embed使用更稳定)。
方案3:强制repoC拉取子模块(不推荐)
如果必须保留Git子模块,需让repoC在拉取repoB时同步拉取子模块:
- 克隆repoB时加参数:
git clone --recurse-submodules github.com/your-username/repoB
- 已克隆的话执行:
git submodule update --init --recursive
注意:这种方法依赖Git操作,Go build时需确保文件路径正确,不同环境容易出现路径不一致问题,维护成本高。
内容的提问来源于stack exchange,提问作者mandar-kulkarni
相关产品推荐
相关产品推荐

