Workspace Mode
O que é Workspace Mode?
Seção intitulada “O que é Workspace Mode?”Workspace Mode (Modo Workspace) foi introduzido no Go 1.18 (março de 2022) e permite que você trabalhe com múltiplos módulos simultaneamente em um ambiente de desenvolvimento compartilhado.
Problema que resolve
Seção intitulada “Problema que resolve”Antes do Workspace Mode (Go ≤ 1.17)
Seção intitulada “Antes do Workspace Mode (Go ≤ 1.17)”Imagine que você está desenvolvendo dois módulos: app e library. O app depende de library:
# Para testar mudanças locais em library, você precisava:# 1. Editar app/go.mod adicionando:replace github.com/user/library => ../library
# 2. Desenvolver e testar# 3. LEMBRAR de remover a diretiva replace antes de fazer commit# 4. Publicar library# 5. Atualizar app para usar a versão publicadaIsso era trabalhoso, especialmente com muitos módulos!
Com Workspace Mode (Go ≥ 1.18)
Seção intitulada “Com Workspace Mode (Go ≥ 1.18)”# Simplesmente criar um workspace:go work init ./app ./library
# Agora app automaticamente usa a versão local de library!# Sem editar go.mod, sem replace, sem problemasEstrutura do arquivo go.work
Seção intitulada “Estrutura do arquivo go.work”O arquivo go.work tem sintaxe similar ao go.mod:
go 1.27.0
use ( ./app ./library ./another-module)
// Comentários são suportadosreplace golang.org/x/net => example.com/fork/net v1.4.5Diretivas do go.work
Seção intitulada “Diretivas do go.work”| Diretiva | Descrição | Exemplo |
|---|---|---|
go |
Versão mínima do Go para o workspace | go 1.27.0 |
use |
Módulos ativos no workspace | use ./module-path |
replace |
Sobrescreve módulos (opcional) | replace foo => bar v1.0.0 |
toolchain |
Sugere um toolchain do Go (Go 1.21+) | toolchain go1.27.1 |
Como funciona?
Seção intitulada “Como funciona?”Quando um arquivo go.work existe, o comando go:
- Trata todos os módulos listados em
usecomo módulos principais - Resolve importações preferindo os módulos do workspace
- Permite executar comandos em qualquer módulo a partir da raiz do workspace
- Sincroniza dependências entre os módulos quando solicitado
Criando um Workspace
Seção intitulada “Criando um Workspace”Método 1: Inicialização com módulos
Seção intitulada “Método 1: Inicialização com módulos”# Crie um diretório para o workspacemkdir meu-workspacecd meu-workspace
# Inicialize com módulos existentesgo work init ./module1 ./module2
# Ou inicialize vazio e adicione depoisgo work initgo work use ./module1go work use ./module2Método 2: Adicionar módulos recursivamente
Seção intitulada “Método 2: Adicionar módulos recursivamente”# Adiciona todos os módulos encontrados recursivamentego work use -r .
# Útil para monorepos com muitos módulosExemplo Prático Completo
Seção intitulada “Exemplo Prático Completo”Cenário: Desenvolvendo uma aplicação e uma biblioteca juntas
Seção intitulada “Cenário: Desenvolvendo uma aplicação e uma biblioteca juntas”# 1. Criar estrutura do workspacemkdir projetocd projeto
# 2. Criar o módulo da bibliotecamkdir stringutilcd stringutilgo mod init github.com/usuario/stringutil
# Criar stringutil/reverse.gocat > reverse.go << 'EOF'package stringutil
func Reverse(s string) string { runes := []rune(s) for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { runes[i], runes[j] = runes[j], runes[i] } return string(runes)}EOF
cd ..
# 3. Criar o módulo da aplicaçãomkdir appcd appgo mod init github.com/usuario/app
# Criar app/main.gocat > main.go << 'EOF'package main
import ( "fmt" "github.com/usuario/stringutil")
func main() { fmt.Println(stringutil.Reverse("Hello, World!"))}EOF
cd ..
# 4. Criar o workspacego work init ./app ./stringutil
# 5. Testar - funciona sem publicar stringutil!cd appgo run .# Saída: !dlroW ,olleHModificando a biblioteca
Seção intitulada “Modificando a biblioteca”# A partir do diretório app, criar outro arquivo na bibliotecacd ../stringutil
cat > upper.go << 'EOF'package stringutil
import "strings"
func ToUpper(s string) string { return strings.ToUpper(s)}EOF
# Usar imediatamente em app/main.go sem publicar!cd ../app
# Modificar main.go para usar ToUpper# ... app usa a nova função imediatamentego run .Comandos de Workspace
Seção intitulada “Comandos de Workspace”go work init
Seção intitulada “go work init”Cria um novo arquivo go.work:
# Inicializar vaziogo work init
# Inicializar com módulosgo work init ./module1 ./module2 ./module3
# Inicializar e depois definir o mínimo do workspacego work init ./module1go work edit -go=1.27.1go work use
Seção intitulada “go work use”Adiciona ou remove módulos do workspace:
# Adicionar um módulogo work use ./new-module
# Adicionar múltiplos módulosgo work use ./module1 ./module2
# Adicionar recursivamente todos os módulosgo work use -r .
# Remover um módulogo work edit -dropuse=./old-modulego work sync
Seção intitulada “go work sync”Sincroniza dependências do workspace para os módulos:
# Sincroniza as versões das dependênciasgo work sync
# Útil quando você quer que todos os módulos usem# as mesmas versões de dependências comunsgo work edit
Seção intitulada “go work edit”Edita o arquivo go.work:
# Adicionar replacego work edit -replace golang.org/x/net=../my-net
# Remover replacego work edit -dropreplace golang.org/x/net
# Definir versão do Gogo work edit -go=1.27.1
# Adicionar toolchaingo work edit -toolchain=go1.27.1go work vendor (Go 1.22+)
Seção intitulada “go work vendor (Go 1.22+)”Cria um diretório vendor para o workspace inteiro:
# Cria vendor/ com todas as dependências do workspacego work vendor
# Build de todos os módulos usando o vendor (Go 1.25+)go build -mod=vendor workTestar todos os módulos
Seção intitulada “Testar todos os módulos”Desde Go 1.25, o padrão work inclui os pacotes de todos os módulos do workspace:
go build workgo test workO padrão ./... é relativo ao diretório atual. Se a raiz do workspace não é um módulo, use work ou caminhos como ./app/... ./library/....
No Go 1.27, go work use -r . também ignora diretórios vendor. A linha go do workspace precisa atender à versão mínima de todos os módulos listados em use.
Variáveis de Ambiente
Seção intitulada “Variáveis de Ambiente”Controla qual arquivo workspace usar:
# Usar um arquivo go.work específicoGOWORK=/path/to/custom.work go build
# Desabilitar workspace mode (usar go.mod normalmente)GOWORK=off go build
# Padrão: Go procura por go.work no diretório atual e paisCasos de Uso
Seção intitulada “Casos de Uso”1. Desenvolvimento Local de Dependências
Seção intitulada “1. Desenvolvimento Local de Dependências”Trabalhar em uma aplicação e suas bibliotecas simultaneamente:
workspace/├── go.work├── api-server/ # Sua aplicação│ └── go.mod├── auth-lib/ # Biblioteca de autenticação│ └── go.mod└── database-lib/ # Biblioteca de banco de dados └── go.mod2. Monorepos
Seção intitulada “2. Monorepos”Gerenciar múltiplos serviços em um único repositório:
monorepo/├── go.work├── user-service/│ └── go.mod├── payment-service/│ └── go.mod├── notification-service/│ └── go.mod└── shared-lib/ └── go.mod3. Contribuindo para Projetos Open Source
Seção intitulada “3. Contribuindo para Projetos Open Source”Testar mudanças em um projeto que você está contribuindo:
# Clone o projeto que você usagit clone https://github.com/author/library
# Clone seu fork onde você está fazendo mudançasgit clone https://github.com/you/library library-fork
# Seu projetogit clone https://github.com/you/app
# Criar workspacecd appgo work init . ../library-fork
# Agora app usa sua versão modificada de libraryWorkflow de Release
Seção intitulada “Workflow de Release”Quando estiver pronto para publicar:
1. Publicar a biblioteca
Seção intitulada “1. Publicar a biblioteca”cd librarygit tag v1.2.0git push origin v1.2.02. Atualizar a aplicação
Seção intitulada “2. Atualizar a aplicação”cd ../app
# Atualizar para usar a versão publicadago get github.com/user/library@v1.2.0
# Verificargo mod tidy3. O workspace continua funcionando
Seção intitulada “3. O workspace continua funcionando”Mesmo após publicar, o workspace continua usando a versão local para desenvolvimento contínuo.
Melhores Práticas
Seção intitulada “Melhores Práticas”- Adicione
go.workego.work.sumao.gitignorequando o workspace for pessoal - Use workspace para desenvolvimento local
- Documente no README como configurar o workspace para novos desenvolvedores
- Use
go work syncperiodicamente para manter dependências sincronizadas
❌ Não faça
Seção intitulada “❌ Não faça”- Não versione um workspace pessoal como se fosse a configuração compartilhada do projeto
- Não confie em workspace para builds de produção
- Não use replace no
go.workse puder evitar (prefira nogo.modse necessário) - Não esqueça de testar sem o workspace antes de release
Troubleshooting
Seção intitulada “Troubleshooting”Problema: “package X is not in GOROOT or in any module”
Seção intitulada “Problema: “package X is not in GOROOT or in any module””# Verifique se todos os módulos estão listadoscat go.work
# Adicione o módulo faltantego work use ./path/to/moduleProblema: Versões de dependências conflitantes
Seção intitulada “Problema: Versões de dependências conflitantes”# Sincronize as versõesgo work sync
# Ou force um módulo específico a atualizarcd module1go get dependency@versioncd ..go work syncProblema: Build funciona localmente mas falha no CI/CD
Seção intitulada “Problema: Build funciona localmente mas falha no CI/CD”# CI não tem o workspace!# Certifique-se de que seus go.mod estão corretos:
# Desabilite workspace temporariamenteGOWORK=off go build ./...
# Isso mostrará erros que existem sem o workspacego.work.sum
Seção intitulada “go.work.sum”O go.work.sum registra hashes necessários ao workspace que não aparecem nos arquivos go.sum dos módulos principais. Ele complementa esses arquivos, sem substituí-los.
# É criado automaticamente# Para um workspace pessoal, adicione ao .gitignoreecho "go.work" >> .gitignoreecho "go.work.sum" >> .gitignoreComparação: replace vs workspace
Seção intitulada “Comparação: replace vs workspace”| Característica | replace (go.mod) | workspace (go.work) |
|---|---|---|
| Onde | Dentro do módulo | Fora dos módulos |
| Escopo | Um módulo | Múltiplos módulos |
| Commit | Sim (com cuidado) | Depende de ser pessoal ou compartilhado |
| Uso | Override permanente | Desenvolvimento local |
| Afeta CI | Sim | Sim, se estiver presente e habilitado |
Recursos Adicionais
Seção intitulada “Recursos Adicionais”- Tutorial Oficial: Multi-Module Workspaces
- Go Blog: Get familiar with workspaces
- Proposta Original: Design doc
- Go 1.18 Release Notes
Conclusão
Seção intitulada “Conclusão”Workspace Mode é uma ferramenta poderosa para desenvolvimento local com múltiplos módulos. Ele simplifica o workflow, elimina a necessidade de diretivas replace temporárias, e torna o desenvolvimento em monorepos muito mais agradável.