Skip to content

Go 1.18 引入了 go.work 文件,用来管理工作区(workspace):把多个 Go 模块放进一棵目录树,本地开发时它们可以直接互相引用,不必先发布再拉取。

1. go.work 文件概述 ​

作用 ​

go.work 文件用于定义一个工作区,这个工作区可以包含多个 Go 模块。这种方式主要用于以下场景:

  • 开发多个相关模块:当你在开发多个相互依赖的模块时,go.work 文件可以帮助你在一个统一的工作区中管理它们。
  • 本地开发和测试:在本地开发和测试多个模块时,你可以使用 go.work 文件来指定本地模块路径,使得模块之间的依赖关系可以得到正确处理。

结构 ​

go.work 文件是一个类似于 go.mod 的文件,但其用途是为工作区中的多个模块定义配置。它的基本结构如下:

go
go 1.20

use (
    ./module1
    ./module2
)

其中,use 关键字用于指定工作区包含的模块。

2. 使用 go.work 文件 ​

初始化工作区 ​

  1. 创建 go.work 文件

    在项目的根目录下,创建一个 go.work 文件,并定义需要包含的模块。例如:

    go
    go 1.20
    
    use (
        ./module1
        ./module2
    )

    这里 ./module1 和 ./module2 是相对于 go.work 文件所在目录的路径。

  2. 在模块中使用

    在 go.work 文件中指定的模块可以在工作区中相互引用。例如,你可以在 module1 中引用 module2,而不需要通过外部版本控制系统下载。

  3. 运行和构建

    使用 go 命令时,Go 工具链会优先使用 go.work 文件中定义的模块。在各个模块目录内,可以照常使用 ./... 模式构建或测试:

    bash
    cd module1
    go build ./...
    go test ./...

    注意:在工作区根目录下直接使用 ./... 会报错 pattern ./...: directory prefix . does not contain modules listed in go.work,此时需要改用模块路径模式,例如:

    bash
    go build example.com/module1/...
    go test example.com/module2/...

示例 ​

假设你有一个包含两个模块的工作区:

  • module1:包含一个 main 包。
  • module2:包含一个库包。

项目目录结构如下:

project/
├── go.work
├── module1/
│   └── main.go
└── module2/
    └── library.go

go.work 文件:

go
go 1.20

use (
    ./module1
    ./module2
)

module1/main.go:

go
package main

import (
    "fmt"
    "example.com/module2" // 假设 module2 的路径为 example.com/module2
)

func main() {
    fmt.Println(module2.Greet())
}

module2/library.go:

go
package module2

func Greet() string {
    return "Hello from module2!"
}

在这个示例中,你可以在 module1 中引用 module2,并且不需要在 go.mod 文件中声明 module2 的依赖。只需使用 go.work 文件来管理整个工作区。

3. 相关命令 ​

以下是与 go.work 文件相关的几个命令:

  • go work init:初始化 go.work 文件。

    bash
    go work init ./module1 ./module2

    这会创建一个新的 go.work 文件,并将指定的模块添加到工作区中。

  • go work edit:编辑现有的 go.work 文件。

    bash
    go work edit -use ./module3

    这会将 module3 添加到现有的 go.work 文件中。

4. 注意事项 ​

  • 工作区管理:go.work 文件是为了方便在开发过程中管理多个模块,但它并不影响生产环境的构建。生产环境依然使用模块中的 go.mod 文件来管理依赖。
  • 模块版本控制:使用 go.work 文件时,模块的版本仍然由每个模块的 go.mod 文件管理。go.work 主要用于本地开发和测试。

总结 ​

go.work 把几个本地模块圈进一个工作区,构建和测试时工具链优先用工作区里列出的模块;生产环境的依赖仍然由各模块自己的 go.mod 管。文件用 go work init 生成,之后增删模块用 go work edit。

参考资料 ​

相关页面 ​

Hello Golang