Conhecendo o NPM 1.0

No dia primeiro deste mês, foi lançado a versão 1.0 do NPM (Node Package Manager). Pra quem não sabe, o NPM é o gerenciador de pacotes oficial do Node.JS. É com ele que criamos e baixamos bibliotecas para desenvolver nossas aplicações em Node.JS.

Não vou explicar aqui como funcionava até a versão 0.3.18 (a última antes das pré 1.0) para não ficar um artigo grande (já vai ficar), mas a explicação sobre o funcionamento da versão 1.0 deve ser suficiente para você conseguir migrar.

Instalando

Existem algumas instruções de instalação, mas basicamente a melhor forma é instalar limpando as coisas velhas. Digo isso porque agora que chegou na 1.0 e quase todas as libs já atualizaram para essa versão e novo modelo, não faz sentido manter libs, a não ser que você tenha alguma lib muito específica. Execute o seguinte:

$ curl http://npmjs.org/install.sh | clean=yes sh

Certifique que você tem permissão para escrever no diretório /usr/local.

Isso vai instalar o NPM 1.0.6 (versão do momento que escrevo o artigo) e limpar suas libs antigas). Se preferir, desinstale antes seu NPM antigo (npm uninstall npm) e apague o diretório ~/.npm. Novidades da instalação:

/usr/local/bin/npm #executável
/usr/local/lib/node_modules/ #pacotes globais

Desde a versão 0.4.x do Node.JS, o diretório node_modules passa a ser o diretório de armazenamento de pacotes, sempre contextualmente ao diretório do projeto que você está trabalhando. Tanto isso é verdade que as bibliotecas instaladas em /usr/local/lib/node_modules/ não ficam automaticamente visíveis para você dar require nelas. Falarei mais sobre isso adiante.

Sendo assim, a nova forma de trabalhar com o NPM é a seguinte:

  • Pacotes que contém executáveis (nodeunit, express, etc) instale com npm install pacote -g
  • Pacotes sem executáveis instale com npm install pacote

Qual a diferença?

A diferença é que a instalação utilizando -g deve ser utilizada primariamente para pacotes que contém executáveis, pois os executáveis já ficam visíveis no path. Outro uso é quando você quer compartilhar algum pacote com diversos projetos. Isso é feito criando um link, que falaei adiante. A instalação local limita o pacote ao escopo do projeto/diretório que foi instalado, ou seja, somente dentro desse diretório e seus subdiretórios esse pacote estará disponível para require.

Para listar os pacotes instalados localmente, basta executar o seguinte comando:

$ npm list
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Esse comando lista apenas os pacotes instalados no diretório node_modules dentro do diretório que aparece logo abaixo do comando npm list (ou npm ls)

Para listar os pacotes globais basta executar:

$ npm ls -g
/usr/local/lib
├─┬ connect@1.4.1
│ ├── mime@1.2.2
│ └── qs@0.1.0
├── nodeunit@0.5.1
└─┬ npm@1.0.6
  ├── abbrev@1.0.3
  ├── node-uuid@1.1.0
  ├── nopt@1.0.4
  └── semver@1.0.5

Repare que a lista é bem diferente. Nenhum desses pacotes podem ser utilizados sem que sejam linkados. Vamos fazer isso agora para que eles fiquem disponíveis localmente.

$ npm link connect
./node_modules/connect -> /usr/local/lib/node_modules/connect

E agora veremos novamente nossos pacotes locais:

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ connect@1.4.1 -> /usr/local/lib/node_modules/connect extraneous
│ ├── mime@1.2.2
│ └── qs@0.1.0
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Repare que o pacote connect aponta para um diretório na instalação global. Com esse link, é possível utilizar o pacote no projeto/diretório atual.

Alguns desenvolvedores utilizam a variável de ambiente NODE_PATH apontando para /usr/local/lib/node_modules/ porque seus projetos não estão enxergando os pacotes globais. De fato isso funciona, mas não é a maneira adequada, pois se você instalar um pacote local e outro global utilizando essa configuração, o pacote global vai prevalecer sobre o local, o que não deveria ser o comportamento esperado.

É importante entender que o escopo local é definido tão somente pelo diretório que você está. Se você voltar um diretório e listar novamente os pacotes perceberá que não tem nada instalado ou a lista de pacotes instalados é diferente (no caso de você ter instalado algo nesse diretório). Vejamos:

$ cd ..
$ npm ls
/Users/emerson.leite/Pet
(empty)

Voltemos para o diretório anterior e vamos remover o link ao pacote connect.

$ cd -
/Users/emerson.leite/Pet/node-database-cleaner
$ npm unlink connect
$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
├── nodeunit@0.5.1
└── redis@0.6.0

Nesse momento não temos mais o link para o pacote connect e portanto não podemos mais fazer um require dele.

Utilizando o package.json para gerenciar suas dependências

O arquivo package.json é um arquivo que descreve um pacote NPM. Nesse arquivo também pode/deve ser utilizado para especificar os pacotes que seu projeto depende. Dessa forma, basta estar no diretório e executar npm install que o NPM já instalará as dependências necessárias. Vejamos um exemplo:

{
  "name" : "database-cleaner",
  "description" : "Database Cleaner for node.js",
  "keywords" : [ "database", "cleaner", "mongodb",
                 "redis", "couchdb", "tests", "package.json" ],
  "version" : "0.3.2",
  "author" : "Emerson Macedo ",
  "repository" : {
    "type" : "git",
    "url" : "git://github.com/emerleite/node-database-cleaner.git"
  },
  "dependencies" : {
    "mongoose" : "1.0.10",
    "redis" : ">=0.5.7",
    "cradle" : ">=0.5.x"
  },
  "main": "index",
  "engines" : { "node" : ">=0.2.5" }
}

Vamos limpar o diretório e instalar novamente as dependências para ver como funciona. Primeiro vou apagar o diretório node_modules, listar para mostrar que está vazio e instalar as dependências.

$ rm -fr node_modules/
$ npm ls
npm WARN cradle >=0.5.x Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN mongoose 1.0.10 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
npm WARN redis >=0.5.7 Unmet dependency in /Users/emerson.leite/Pet/node-database-cleaner
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├── UNMET DEPENDENCY cradle >=0.5.x
├── UNMET DEPENDENCY mongoose 1.0.10
└── UNMET DEPENDENCY redis >=0.5.7

A resposta mostra que as dependências não estão instaladas, o que vamos resolver agora:

$ npm install
redis@0.6.0 ./node_modules/redis
mongoose@1.0.10 ./node_modules/mongoose
vargs@0.1.0 ./node_modules/cradle/node_modules/vargs
eyes@0.1.6 ./node_modules/cradle/node_modules/vows/node_modules/eyes
vows@0.5.8 ./node_modules/cradle/node_modules/vows
cradle@0.5.5 ./node_modules/cradle

Agora vamos listar apenas para conferir.

$ npm ls
database-cleaner@0.3.2 /Users/emerson.leite/Pet/node-database-cleaner
├─┬ cradle@0.5.5
│ ├── vargs@0.1.0
│ └─┬ vows@0.5.8
│   └── eyes@0.1.6
├── mongoose@1.0.10
└── redis@0.6.0

Pra fechar

O NPM tem uma série de outros recursos que vou tentar destacar em outros artigos, mas vejo que muita gente não estava entendendo bem a forma mais adequada de usar a versão 1.0, inclusive apelando para o uso inadequado da variável de ambiente NODE_PATH. Espero que este artigo possa ajudar a explicar um pouco do NPM 1.0.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Publicado em nodejs | Com a tag , , | Deixar um comentário

BrazilJS – Como foi

Na última sexta e sábado, 13 e 14 de maio, aconteceu o primeiro BrazilJS, conferência Brasileira relacionada a Javascript. Os organizadores foram: Cristiano Milfont, Felipe Nascimento, Francisco Barroso, Henrique Soares e Jaydson Gomes.

Só pude comparecer no sábado, infelizmente. Mas mesmo indo apenas um dia, fiquei impressionado com a empolgação do pessoal e como a comunidade Javascript Brasileira curtiu o evento. As palestras foram de alto nível. Teve palestra de Javascript no iOS, Android, desenvolvimento de Jogos, Node.JS, testes, qualidade de código, programação funcional e outras coisas mais.

Em breve a organização do evento deve disponibilizar os vídeos e um lugar com link para todos os slides publicados. Acompanhe na hashtag #braziljs no twitter.

Sinceramente o evento superou todas as minhas expectativas. Pra quem não viu ainda, segue os slides e o código da minha apresentação sobre aplicações Realtime com Node.JS.

Código: http://goo.gl/DKmiN

No fim da minha palestra fiz o sorteio de uma bolsa para a próxima turma do nosso curso de Node.JS da e-Genial. O ganhador foi o Jonathas Jivago

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Publicado em javascript, nodejs | Com a tag , , , | 2 comentários

Duostack lança hospedagem Beta de Node.JS

poucas horas atrás, a Duostack lançou uma hospedagem beta de Node.JS. Essa hospedagem está muuuuito parecida com a do Heroku. A documentação está ótima, muito melhor que a da Joyent e que dá Nodester. Pode parecer bobeira, mas documentação faz toda a diferença pra quem precisa de um host desse tipo. Já criei minha conta e estou fazendo alguns testes. Quando testar melhor, postarei aqui minhas primeiras impressões sobre o serviço.

Crie logo a sua conta, pois por enquanto não tem coupon mas é provável que passe a ter.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Publicado em nodejs | Com a tag , | Deixar um comentário

Node.JS – Mudanças arquiteturais na versão 0.6 e suporte a Windows

Na última CodeConf, Ryan Dahl apresentou o Road Map do Node.JS para a versão 0.6. Dentre as mudanças, o foco em fazer funcionar no Windows sem tranqueiras (i.e. Cygwin) teve bastante destaque. Isso resultará em uma grande mudança arquitetural, no que diz respeito ao core do projeto, que é a gerência de I/O Assíncrono.

O problema do Node.JS com o Windows se dá porque sistemas operacionas UNIX e Windows tratam Network Programming de forma totalmente diferente. Enquanto no Unix usamos libev e libeio por cima de select, epoll ou kqueue (isso varia de acordo com o sabor de unix), no Windows esse tratamento é totalmente diferente. Windows até tem suporte a select, porém não é eficiente para sistemas de alta concorrência. O que resolve esse problema no Windows se chama I/O Completion Ports (IOCP), que sinceramente não conheço nada sobre. Eu li a página da documentação mas sequer um teste básico eu fiz. Pretendo fazer e depois escrever alguma coisa sobre isso mais pra frente.

Até onde eu entendi, o I/O Completion Ports já tem o suporte completo para I/O Assíncrono, sem precisar ter um Thread Pool próprio para gerênciar isso (que é o que o Node faz no Unix). Posso estar enganado pois não testei isso.

Junto a essa idéia, criou-se um projeto chamado liboio, que é a nova abstração para o tratamento de I/O de cada plataforma (i.e. Sistema Operacional). Esse projeto será integrado a versão 0.6 do Node.JS.

A nova estrutura fica da seguinte forma:

Estrutura Node.JS 0.6.0

Anteriormente não existia essa segunda camada, nem a parte de IOCP e Windows Kernel, portanto considero a mudança significativa, apesar de a parte *nix receber basicamente uma abstração, o que não deve mudar mundo quando nesses SOs.

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

Publicado em nodejs | Com a tag , , | 1 comentário