美文网首页
关于go mod的on,off,auto下引入外部包读取顺序的探

关于go mod的on,off,auto下引入外部包读取顺序的探

作者: 10xjzheng | 来源:发表于2021-09-06 20:30 被阅读0次

    1.前言

    网上的文章鱼龙混杂,且都只是给结论,你根本不知道谁说的是对的,谁是错的,为了得到可信的结论,于是有了这篇文章,所谓——实践出真知。

    2.实验过程

    前期准备

    • 在GOPAHT外部建立目录 my-app:
      midir my-app

    • 进入my-app,编写程序, vim main.go:

    package main
    
    import "github.com/astaxie/beego"
    
    func main() {
        beego.Run()
    }
    
    

    1. GO111MODULE="on":

    1.1 不在$GOPATH/src目录下

    • 开启GO MOD:
    go env -w GO111MODULE="on"
    

    • 生成go.mod :
    go mod init my-app
    
    image.png
    • 执行 go mod tidy,自动下载包到$GOPATH/pkg/mod:

      image.png
    • vim $GOPATH/pkg/mod/github.com/astaxie/beego@v1.12.3/beego.go
      增加一行 (58行) :

    fmt.Println("mod")
    

    当然记得要引入包:import "fmt"

    image.png
    • 执行 go run main.go

      image.png
      可以证明确实读取了 $GOPATH/pkg/mod的beego。
    • 生成 vendor,执行 go mod vendor

    • my-app下执行 vim vendor/github.com/astaxie/beego/beego.go
      还是增加一行 (58行) :

    fmt.Println("vendor")
    

    如图所示:


    image.png
    • 执行 go run main.go
      image.png
      可以看到此时优先读取了 vendor里面的外部包

    1.2 在$GOPATH/src目录下

    • 复制my-app的目录到$GOPATH/src目录下
    • 执行go run main.go
      image.png
      可以看到优先读取的还是vendor
    • 执行 rm -rf vendor
    • 再次 执行go run main.go
      image.png
      依然读的是mod的。

    2. GO111MODULE="off"

    先执行命令:

    go env -w GO111MODULE="off"
    

    此时我的配置如下:


    image.png

    2.1 GO111MODULE="off"且项目不在 $GOPATH/src下

    • 还是之前在GOPATH/src外的my-app目录,复制vendor里面的目录到GOPATH/src下面:

      image.png
    • 执行vim $GOPATH/src/github.com/astaxie/beego/beego.go
      还是之前的位置,改为

    fmt.Println("src")
    
    image.png
    • 执行 go run main.go
      image.png
      直接读取的是 $GOPATH/src下面的包。

    2.2 GO111MODULE="off"且项目在 $GOPATH/src下

    • 还是之前在GOPATH/src外的my-app目录,整个目录复制到GOPATH/src;
    • 在 $GOPATH/src/my-app 执行 go run main.go
      image.png
      发现竟然读的是vendor的。
    • 执行:mv vendor vendor_bak 即去除vendor的影响,再执行 go run main.go
      image.png
      这回读取的就是src的了。

    3. GO111MODULE="auto"

    执行:

     go env -w GO111MODULE="auto"
    

    修改后环境变量如下:


    image.png

    3.1 没有go.mod 且项目在$GOPATH/src下

    注意:记得要在:GOPATH/src,GOPATH/pkg/mod, vendor里面的beego包加入了之前的调试语句:

    fmt.Println("src")
    fmt.Println("mod")
    fmt.Println("vendor")
    
    • 目录文件如下:


      image.png
    • 执行 go run main.go
      居然报错了:

      image.png
    • 看看$GOPATH/src是否有包, ls /mnt/d/GoProjects/src/github.com/astaxie/beego

      image.png
      包是有的。
    • 执行一下:go get -v github.com/astaxie/beego

      image.png
    • 再运行:go run main.go,发现可以了:

      image.png
    • 猜想走的是$GOPATH/pkg/mod里面的包,改了一下, vim /mnt/d/GoProjects/pkg/mod/github.com/astaxie/beego@v1.12.3/beego.go:

      image.png
    • 再运行:go run main.go,证实了:

      image.png
    • 开启vendor,目录结构如下:


      image.png
      image.png
    • 运行:go run main.go

      image.png

    还是走mod。

    查阅资料发现,只要main.go依赖的包用了go.mod,则默认会启用GOMODULE来下载依赖。

    3.2 没有go.mod 且项目不在$GOPATH/src下

    按3.1的流程跑了一遍,测试结果同上。

    • 目录结构:


      image.png
    • 运行:go run main.go
      image.png
      走的是mod
    • 开启vendor,目录结构:


      image.png
    • 运行:go run main.go
      image.png
      还是走的是mod。

    意味着,GO111MODULE="auto" 的情况下,只要依赖包包含了go.mod,那么无论有没有vendor,无论在不在$GOPATH/src下,都会开启mod,并走mod的外部引入包。

    3.3 有go.mod 且项目不在$GOPATH/src下

    • 目录结构:


      image.png
    • 运行:go run main.go

      image.png
      即有vendor情况下走的是vendor
    • 我们执行以下命令mv vendor vendor_bak去除vendor影响,目录结构:

      image.png
    • 运行:go run main.go

      image.png

    走的是mod。

    3.4 有go.mod 且项目在$GOPATH/src下

    • 目录结构:


      image.png
    • 运行:go run main.go

      image.png
      即有vendor是直接走vendor
    • 我们执行以下命令mv vendor vendor_bak去除vendor影响,目录结构:

      image.png
    • 运行:go run main.go

      image.png
      走的是mod。

    3.结论

    1.GO111MODULE="on"

    1.1 GO111MODULE="on" 且项目不在 $GOPATH/src下

    • 当vendor目录存在,优先读取vendor的外部包
    • 当vendor目录不存在,读取$GOPATH/pkg/mod下的外部包

    1.2 GO111MODULE="on" 且项目在 $GOPATH/src下

    跟上面情况(GO111MODULE="on" 且项目不在 $GOPATH/src下)一致。

    2. GO111MODULE="off"

    2.1.GO111MODULE="off" 且项目不在 $GOPATH/src下

    • 无论有没有vendor,直接读取$GOPATH/src里面的外部引入包,即不会读取vendor里面的包

    2.2.GO111MODULE="off" 且项目在 $GOPATH/src下

    • 有vendor则读取vendor的外部引入包
    • 没有vendor则读取$GOPATH/src里面的外部引入包

    3.GO111MODULE="auto"

    3.1 没有go.mod 且项目不在$GOPATH/src下

    • 没有vendor,且依赖的包里面有go.mod,直接走$GOPATH/pkg/mod
    • 没有vendor,且依赖的包里面都没有go.mod,直接走$GOPATH/src (待验证)
    • 有vendor,也没有用,只要依赖的包里面有go.mod,还是走$GOPATH/pkg/mod
    • 有vendor,且依赖的包里面都没有go.mod,走$GOPATH/src (待验证)

    3.2 没有go.mod 且项目在$GOPATH/src下

    • 没有vendor,且依赖的包里面有go.mod,直接走$GOPATH/pkg/mod
    • 没有vendor,且依赖的包里面都没有go.mod,直接走$GOPATH/src (待验证)
    • 有vendor,也没有用,只要依赖的包里面有go.mod,还是走$GOPATH/pkg/mod
    • 有vendor,且依赖的包里面都没有go.mod,走vendor (待验证)

    3.3 有go.mod 且项目不在$GOPATH/src下

    • 有vendor, 则读取vendor的外部引入包
    • 没有vendor则读取$GOPATH/pkg/mod里面的外部引入包

    3.4 有go.mod 且项目在$GOPATH/src下

    与上面的情况(有go.mod 且项目不在$GOPATH/src下)一致。

    相关文章

      网友评论

          本文标题:关于go mod的on,off,auto下引入外部包读取顺序的探

          本文链接:https://www.haomeiwen.com/subject/bttywltx.html