Gerenciando múltiplas versões de linguagens com nvm, pyenv e rbenv

1. Introdução ao problema das múltiplas versões de linguagens

No desenvolvimento de software moderno, é comum trabalhar com múltiplos projetos que exigem versões diferentes de Node.js, Python e Ruby. Um projeto legado pode precisar de Node.js 12, enquanto um novo projeto utiliza Node.js 20. Da mesma forma, aplicações Python podem variar entre Python 2.7 e Python 3.12, e projetos Ruby entre Ruby 2.5 e Ruby 3.3.

Instalar versões globais de linguagens no sistema operacional é arriscado. Conflitos de dependências, quebras de ambiente e dificuldades para reproduzir ambientes de produção são problemas frequentes. Ferramentas como nvm, pyenv e rbenv surgem como soluções isoladas que permitem instalar, gerenciar e alternar entre múltiplas versões de cada linguagem sem poluir o sistema.

2. nvm: Gerenciando versões do Node.js

O nvm (Node Version Manager) é a ferramenta mais popular para gerenciar versões do Node.js. Sua instalação é simples via curl ou wget:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Após reiniciar o terminal, comandos básicos permitem gerenciar versões:

nvm install 18.17.0        # Instala versão específica
nvm install --lts          # Instala a versão LTS mais recente
nvm use 18.17.0            # Ativa a versão instalada
nvm ls                     # Lista versões instaladas
nvm alias default 18.17.0  # Define versão padrão

Para projetos específicos, crie um arquivo .nvmrc na raiz do projeto:

18.17.0

Ao entrar no diretório, execute nvm use para ativar automaticamente a versão definida. Dica importante: sempre prefira versões LTS para projetos de produção e evite instalar versões desnecessárias.

3. pyenv: Gerenciando versões do Python

O pyenv permite instalar e gerenciar múltiplas versões do Python de forma isolada. A instalação requer dependências de sistema para compilação:

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev

# Instalação do pyenv
curl https://pyenv.run | bash

Comandos essenciais do pyenv:

pyenv install 3.10.12      # Instala versão específica
pyenv install 3.12.0       # Instala outra versão
pyenv global 3.10.12       # Define versão global
pyenv local 3.12.0         # Define versão local (por projeto)
pyenv versions             # Lista versões instaladas

Para isolar dependências de projetos, utilize o plugin pyenv-virtualenv:

pyenv virtualenv 3.10.12 meu-projeto-env
pyenv activate meu-projeto-env

O arquivo .python-version gerado por pyenv local garante que cada projeto use sua versão correta automaticamente.

4. rbenv: Gerenciando versões do Ruby

O rbenv é uma ferramenta leve para gerenciar versões do Ruby, com foco em simplicidade. A instalação inclui o plugin ruby-build para compilar versões:

# Instalação via git
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv && src/configure && make -C src

# Plugin ruby-build
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Comandos básicos do rbenv:

rbenv install 3.1.4        # Instala versão específica
rbenv install 3.2.2        # Instala outra versão
rbenv global 3.1.4         # Define versão global
rbenv local 3.2.2          # Define versão local (cria .ruby-version)
rbenv versions             # Lista versões instaladas

O arquivo .ruby-version na raiz do projeto define automaticamente a versão ao entrar no diretório. Diferente do RVM, o rbenv é mais leve e não interfere com gemsets, deixando essa responsabilidade para o Bundler.

5. Automatizando a troca de versões com arquivos de configuração

A verdadeira produtividade surge quando a troca de versões é automática. Cada ferramenta utiliza um arquivo de configuração específico:

  • Node.js: .nvmrc
  • Python: .python-version
  • Ruby: .ruby-version

Para automatizar a ativação ao entrar em diretórios, configure hooks no shell. Exemplo para bash:

# ~/.bashrc
enter_directory() {
  if [[ -f .nvmrc ]]; then
    nvm use
  fi
  if [[ -f .python-version ]]; then
    pyenv local
  fi
  if [[ -f .ruby-version ]]; then
    rbenv local
  fi
}
cd() {
  builtin cd "$@" && enter_directory
}

Exemplo prático de um projeto que mistura versões:

# Projeto: app-multilang
# .nvmrc contém: 18.17.0
# .python-version contém: 3.10.12
# .ruby-version contém: 3.1.4

# Ao entrar no diretório, automaticamente:
# - Node.js 18.17.0 é ativado
# - Python 3.10.12 é ativado
# - Ruby 3.1.4 é ativado

6. Resolução de problemas e boas práticas

Erros comuns e suas soluções:

  • Permissões negadas: Nunca use sudo com nvm, pyenv ou rbenv. As ferramentas gerenciam versões no diretório home do usuário.
  • Compilação falha no pyenv: Instale todas as dependências de sistema listadas anteriormente.
  • PATH mal configurado: Verifique se as linhas de inicialização foram adicionadas corretamente ao ~/.bashrc ou ~/.zshrc.
  • Comando não encontrado: Reinicie o terminal ou execute source ~/.bashrc.

Boas práticas recomendadas:

  • Mantenha apenas versões realmente necessárias
  • Prefira versões LTS para projetos de produção
  • Utilize nvm cache clear, pyenv uninstall e rbenv uninstall para remover versões não utilizadas
  • Documente as versões nos arquivos de configuração do projeto

7. Comparação final e fluxo de trabalho integrado

Característica nvm pyenv rbenv
Instalação curl/wget pyenv.run git clone
Comando instalar nvm install pyenv install rbenv install
Versão global nvm alias default pyenv global rbenv global
Versão local .nvmrc .python-version .ruby-version
Plugin virtual Não necessário pyenv-virtualenv Bundler
Leveza Alta Média Alta

Fluxo de trabalho diário integrado:

# 1. Clonar repositório
git clone https://github.com/exemplo/projeto-multilang.git
cd projeto-multilang

# 2. Versões ativadas automaticamente pelos hooks
# Node.js 18.17.0, Python 3.10.12, Ruby 3.1.4

# 3. Instalar dependências
npm install
pip install -r requirements.txt
bundle install

# 4. Desenvolver e testar
npm run dev
python app.py
ruby main.rb

Alternativas modernas como fnm (Node.js), mise (multilinguagem) e asdf (multilinguagem) oferecem desempenho superior e unificação, mas nvm, pyenv e rbenv continuam sendo as ferramentas mais maduras e com maior suporte da comunidade.

Referências