Pular para o conteúdo

Go 1.16-1.17: A era do lazy loading

As versões Go 1.16 e 1.17 marcam um divisor de águas no ecossistema Go, tornando módulos o padrão e introduzindo otimizações na resolução de dependências.

Timeline:

  • Go 1.16: Fevereiro 2021
  • Go 1.17: Agosto 2021

Mudança mais importante: módulos agora são o padrão

Seção intitulada “Mudança mais importante: módulos agora são o padrão”
Janela do terminal
# GO111MODULE agora ON por padrão
# GOPATH mode descontinuado para novos projetos
GO111MODULE=on # Padrão (não precisa mais definir!)

Impacto:

  • Novos projetos no modo de módulos precisam de go.mod
  • O modo GOPATH ainda pode ser selecionado com GO111MODULE=off
  • Migração para módulos se tornou urgente

Mudança de comportamento:

Janela do terminal
# Go ≤ 1.15
go build # Modifica go.mod automaticamente ✏️
# Go ≥ 1.16
go build # NÃO modifica go.mod ❌
go test # NÃO modifica go.mod ❌
go run # NÃO modifica go.mod ❌

Como adicionar dependências agora:

Janela do terminal
# Use explicitamente
go get <package>@<version>
go mod tidy

Novo: instalar programas em versões específicas:

Janela do terminal
# Antes (Go 1.15)
GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.43.0
# Agora (Go 1.16+)
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.43.0
# Instala em $GOPATH/bin ou $GOBIN

Benefícios:

  • Não polu go.mod do projeto
  • Versões explícitas
  • Isolamento de ferramentas

Marque versões problemáticas como não recomendadas:

go.mod
retract (
v1.5.0 // Bug crítico - use v1.5.1+
[v1.2.0, v1.2.3] // Builds quebradas
)

Ver capítulo: Module Retraction

Proteção contra comandos maliciosos:

Janela do terminal
# Padrão seguro
GOVCS="public:git|hg,private:all"
# Apenas Git
GOVCS="*:git"
Janela do terminal
# Go ≤ 1.15
go test all # Testa TUDO, incluindo deps transitivas
# Módulos com go 1.16 ou superior
go test all # Testa os pacotes do módulo principal e os importados por eles ou seus testes
  • GOMODCACHE, introduzido no Go 1.15, continua permitindo escolher outro local para o cache
  • Melhorias no vendor
  • go mod download mais robusto

Revolução de Performance!

Como funciona:

  • Carrega grafo de módulos sob demanda
  • Não carrega tudo upfront
  • Builds muito mais rápidos

Resultados esperados:

  • Menos arquivos go.mod lidos quando os requisitos já atendem ao comando
  • Menor trabalho de resolução, dependendo do grafo
  • Quantidade de checksums também depende da compatibilidade preservada pelo tidy

Ver capítulo: Lazy Loading

Poda do Grafo de Dependências:

Go 1.16:
Seu módulo
└─ Dep A
└─ Dep B
└─ Dep C ← Carrega TUDO
Go 1.17+:
Seu módulo
└─ Dep A
└─ Dep B ← Para aqui (pruning)

Benefícios:

  • Menos dependências processadas
  • Menos conflitos
  • Grafo mais limpo

Agora go.mod separa deps diretas e indiretas:

module example.com/projeto
go 1.17
// Dependências DIRETAS
require (
github.com/gin-gonic/gin v1.9.1
gorm.io/gorm v1.25.7
)
// Dependências INDIRETAS
require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
)

Vantagens:

  • Clara distinção
  • Fácil ver o que você realmente usa
  • Melhor legibilidade

Módulos com go 1.17 ou superior registram requisitos para os módulos que fornecem pacotes importados direta ou indiretamente pelo código e pelos testes:

Janela do terminal
# Go 1.16: go.mod tinha ~10 linhas
# Go 1.17+: go.mod pode ter ~100 linhas
# MAS grafo é podado, então builds são mais rápidos!
Janela do terminal
# Ver grafo podado
go mod graph
# Muito menor que antes!
Janela do terminal
# No Go 1.17, usar go get para instalar executáveis foi depreciado.
# No Go 1.18, go get passou a apenas alterar dependências.
# -d tornou-se desnecessária e foi removida no Go 1.25.
# Use go install para ferramentas
go install golang.org/x/tools/cmd/stringer@latest
  • go run passa a aceitar pacote@versão, sem alterar o módulo atual
  • Melhorias no go mod vendor

Janela do terminal
# 1. Baixar Go 1.16
# 2. Atualizar go.mod
go mod edit -go=1.16
# 3. Mudar workflow
# ANTES: go build modificava go.mod
# AGORA: Use go mod tidy
go mod tidy
go build ./...
Janela do terminal
# 1. Baixar Go 1.17
# 2. Atualizar go.mod
go mod edit -go=1.17
# 3. Reorganizar requires
go mod tidy -go=1.17
# 4. Revise os requisitos indiretos adicionados
# 5. Revise os checksums preservados por compatibilidade
Janela do terminal
# Ver diff do go.mod
git diff go.mod
# Ver diff do go.sum
git diff go.sum | head -50

  • Atualizar go line para 1.16
  • Remover variável GO111MODULE (não mais necessária)
  • Atualizar scripts que dependem de build modificando go.mod
  • Mudar go get para go install para ferramentas
  • Adicionar retract para versões problemáticas
  • Configurar GOVCS se necessário
  • Testar com o novo padrão “all”
  • Atualizar go line para 1.17
  • Executar go mod tidy -go=1.17
  • Revisar a separação de requisitos diretos e indiretos
  • Conferir os checksums necessários por compatibilidade
  • Atualizar deps para Go 1.17+ (para máximo pruning)
  • Medir o desempenho com as mesmas condições de cache
  • Atualizar CI/CD se necessário


Feature Impacto
Módulos por padrão (1.16) Novos projetos usam go.mod
Build não modifica go.mod (1.16) 🔒 Builds determinísticos
go install @version (1.16) 🛠️ Ferramentas versionadas
Retraction (1.16) 🚫 Marcar versões ruins
Lazy loading (1.17) Carregamento do grafo sob demanda
Graph pruning (1.17) ✂️ Menos conflitos
Dois blocos require (1.17) 📋 Mais legível