今天从 GitHub 克隆了一个别人的 Golang Markdown 项目,[作了些修改](https://github.com/yuin/goldmark/issues/130),想使用自己的版本,发现不行,因为模块的路径不对,导致导入出错。 原来的模块路径和文件(go.mod): - `github.com/yuin/goldmark` ```- module github.com/yuin/goldmark go 1.13 ``` 克隆后的模块路径和文件: - `github.com/movsb/goldmark` ```- module github.com/yuin/goldmark go 1.13 ``` 只是路径变了,go.mod 里面的内容是不变的。 同样,代码里面使用的当前项目的子模块的引用路径肯定也没变。这样一定会导致各种引用混乱。所以当前 Go 语言为什么没有引入导入相对路径的模块?🤔 尝试在测试项目里面使用我自己的克隆版本: ```go package main import "github.com/movsb/goldmark" func main() { goldmark.New() } ``` 发现会报错: ```bash $ go run main.go go: github.com/movsb/goldmark: github.com/movsb/goldmark@v1.1.30: parsing go.mod: module declares its path as: github.com/yuin/goldmark but was required as: github.com/movsb/goldmark ``` 所以,怎么办?不可能把人家的路径全部给改了吧? 突然想到了 `replace` 指令。 以前为了引入一个在本地正在开发的模块,经常 `replace` 路径为本地路径: ```- replace github.com/movsb/taorm => /Users/tao/code/taorm ``` 实际上 replace 也可以用来替换掉非本地的模块路径。 代码里面导入**原来**的仓库路径: ```go package main import "github.com/yuin/goldmark" func main() { goldmark.New() } ``` `go.mod` 里面 replace 掉。require 原来的,replace 成自己的: ```- module github.com/movsb/test require github.com/yuin/goldmark v1.1.30 replace github.com/yuin/goldmark => github.com/movsb/goldmark v1.1.30 go 1.13 ``` 如果要更新版本,可以把 `v1.1.30` 换成新版本,或者 git 的提交号(commit-id),然后在终端执行: ```bash go mod download github.com/movsb/goldmark@版本号或提交号 ``` 注意前端的版本号是用空格分开的,命令中的版本号是用`@`分开的。 参考: - [ When should I use the replace directive?](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) - [go modules的replace使用, 解决fork的项目import问题](https://studygolang.com/articles/23008)