Workspace Mode
Workspace Mode para desenvolvimento com múltiplos módulos simultaneamente
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.
Antes do Workspace Mode, desenvolver em múltiplos módulos localmente exigia editar manualmente diretivas replace no go.mod, o que era trabalhoso e propenso a erros. Agora, você pode trabalhar em vários módulos sem modificar seus arquivos go.mod.
Problema que resolve
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)
# 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
O arquivo go.work tem sintaxe similar ao go.mod:
go 1.25
use (
./app
./library
./another-module
)
// Comentários são suportados
replace golang.org/x/net => example.com/fork/net v1.4.5Diretivas do go.work
go
Versão do Go para interpretar o arquivo
go 1.25
use
Módulos ativos no workspace
use ./module-path
replace
Sobrescreve módulos (opcional)
replace foo => bar v1.0.0
toolchain
Especifica toolchain do Go (Go 1.21+)
toolchain go1.25.0
Como funciona?
Quando um arquivo go.work existe, o comando go:
Trata todos os módulos listados em
usecomo módulos principaisResolve 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
Método 1: Inicialização com módulos
# Crie um diretório para o workspace
mkdir meu-workspace
cd meu-workspace
# Inicialize com módulos existentes
go work init ./module1 ./module2
# Ou inicialize vazio e adicione depois
go work init
go work use ./module1
go work use ./module2Método 2: Adicionar módulos recursivamente
# Adiciona todos os módulos encontrados recursivamente
go work use -r .
# Útil para monorepos com muitos módulosExemplo Prático Completo
Cenário: Desenvolvendo uma aplicação e uma biblioteca juntas
# 1. Criar estrutura do workspace
mkdir projeto
cd projeto
# 2. Criar o módulo da biblioteca
mkdir stringutil
cd stringutil
go mod init github.com/usuario/stringutil
# Criar stringutil/reverse.go
cat > 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ção
mkdir app
cd app
go mod init github.com/usuario/app
# Criar app/main.go
cat > main.go << 'EOF'
package main
import (
"fmt"
"github.com/usuario/stringutil"
)
func main() {
fmt.Println(stringutil.Reverse("Hello, World!"))
}
EOF
cd ..
# 4. Criar o workspace
go work init ./app ./stringutil
# 5. Testar - funciona sem publicar stringutil!
cd app
go run .
# Saída: !dlroW ,olleHModificando a biblioteca
# Adicionar uma nova função em stringutil/reverse.go
cd stringutil
cat >> reverse.go << 'EOF'
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 imediatamente
go run .Comandos de Workspace
go work init
Cria um novo arquivo go.work:
# Inicializar vazio
go work init
# Inicializar com módulos
go work init ./module1 ./module2 ./module3
# Inicializar especificando versão do Go
go work init -go=1.25 ./module1go work use
Adiciona ou remove módulos do workspace:
# Adicionar um módulo
go work use ./new-module
# Adicionar múltiplos módulos
go work use ./module1 ./module2
# Adicionar recursivamente todos os módulos
go work use -r .
# Remover um módulo
go work edit -dropuse=./old-modulego work sync
Sincroniza dependências do workspace para os módulos:
# Sincroniza as versões das dependências
go work sync
# Útil quando você quer que todos os módulos usem
# as mesmas versões de dependências comunsgo work edit
Edita o arquivo go.work:
# Adicionar replace
go work edit -replace golang.org/x/net=../my-net
# Remover replace
go work edit -dropreplace golang.org/x/net
# Definir versão do Go
go work edit -go=1.25
# Adicionar toolchain
go work edit -toolchain=go1.25.1go work vendor (Go 1.22+)
Cria um diretório vendor para o workspace inteiro:
# Cria vendor/ com todas as dependências do workspace
go work vendor
# Build usando o vendor
go build -mod=vendor ./...Variáveis de Ambiente
GOWORK
Controla qual arquivo workspace usar:
# Usar um arquivo go.work específico
GOWORK=/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
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
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
Testar mudanças em um projeto que você está contribuindo:
# Clone o projeto que você usa
git clone https://github.com/author/library
# Clone seu fork onde você está fazendo mudanças
git clone https://github.com/you/library library-fork
# Seu projeto
git clone https://github.com/you/app
# Criar workspace
cd app
go work init . ../library-fork
# Agora app usa sua versão modificada de libraryWorkflow de Release
Quando estiver pronto para publicar:
1. Publicar a biblioteca
cd library
git tag v1.2.0
git push origin v1.2.02. Atualizar a aplicação
cd ../app
# Atualizar para usar a versão publicada
go get github.com/user/library@v1.2.0
# Verificar
go mod tidy3. O workspace continua funcionando
Mesmo após publicar, o workspace continua usando a versão local para desenvolvimento contínuo.
Melhores Práticas
✅ Faça
Adicione
go.workego.work.sumao.gitignoreUse 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
Nunca comite
go.workno repositório (é pessoal)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
Problema: "package X is not in GOROOT or in any module"
# Verifique se todos os módulos estão listados
cat go.work
# Adicione o módulo faltante
go work use ./path/to/moduleProblema: Versões de dependências conflitantes
# Sincronize as versões
go work sync
# Ou force um módulo específico a atualizar
cd module1
go get dependency@version
cd ..
go work syncProblema: 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 temporariamente
GOWORK=off go build ./...
# Isso mostrará erros que existem sem o workspacego.work.sum
Similar ao go.sum, o arquivo go.work.sum contém checksums das dependências usadas no workspace.
# É criado automaticamente
# Também deve ser adicionado ao .gitignore
echo "go.work" >> .gitignore
echo "go.work.sum" >> .gitignoreComparação: replace vs workspace
Onde
Dentro do módulo
Fora dos módulos
Escopo
Um módulo
Múltiplos módulos
Commit
Sim (com cuidado)
Não (sempre local)
Uso
Override permanente
Desenvolvimento local
Afeta CI
Sim
Não
Recursos Adicionais
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.
Dica: Se você trabalha regularmente com múltiplos módulos relacionados, workspace mode vai economizar muito tempo e frustração!
Last updated