Começando com NodeJS - Parte 3

Posted by uselessdev on 26/11/2016

Package.json

Vamos falar um pouco sobre o package.json, o package.json nada mais é que um arquivo que guarda informações sobre nosso pacote e/ou aplicação, como nome, versão, description, scripts, authpr, dependencias e outras coisas que podem ou não fazer parte desse arquivo, sendo o mais importante o name e o version uma vez que seu pacote, não pode ser instalado sem esses dois campos. você pode e deve ler a documentação completa aqui

Hello World!

Bem, vamos entender melhor, criando um pacote simples tanto pra rodar local quanto global, nosso pacote vai ser uma calculadora, então crie a pasta o mesmo nome e seu package.json:

1
$ mkdir calculadora; cd calculadora; npm init

Seu arquivo deve ser semelhante a esse:

1
2
3
4
5
6
7
8
9
10
11
{
"name": "calculadora",
"version": "0.1.0",
"description": "Uma calculadora",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Wallace Batista",
"license": "MIT"
}

crie agora seu arquivo index.js e adicione o seguinte conteúdo:

1
2
3
'use strict'
console.log('Nossa calculadora vai começar aqui')

No terminal você pode visualizar essa mensagem fazendo o seguinte:

1
$ node index.js

Antes de tudo vamos fazer o seguinte, crie uma pasta chamada bin e dentro dela o arquivo calculadora.js é aqui que vai ficar nosso código principal. Dentro de calculadora.js vamos adicionar o seguinte código:

1
2
3
4
5
6
7
8
9
10
11
12
13
function sum (x, y) {
return x + y
}
function multiply (x, y) {
return x * y
}
function square (x) {
return multiply(x, x)
}
module.exports = {sum, multiply, square}

Que ta acontencendo aqui?

Muito simples ~joves~, primeiro nós criamos três funções simplesinhas, sum, multiply e square, logo depois exportamos essas funções, com isso, deixamos elas disponíveis na aplicação, existem outras formas de fazermos isso:

1
2
3
4
5
6
7
8
9
...
module.exports = function sum () {
// código...
}
module.exports = function multiply () {
// código...
}
...

Ou:

1
2
3
4
5
6
7
8
9
10
11
...
module.exports = calculadora = {
sum: function () {
},
multiply: function () {
}
}
...

Cada um com suas diferenças, mas por hora vamos manter, como fizemos na primeira vez, pela simplicidade, só uma observação, estamos exportando um Objeto que possui chaves que correspondem as funções, o fato de eles possuirem o mesmo nome,~nos permite fazer isso: module.exports = {sum, multiply, square} porém, poderiámos alterar o nome dessa forma: module.exports = {soma: sum, multiplicacao: multiply, quadrado: square}, entendeu?

Agora vamos modificar nosso arquivo index.js, remova o console.log e adicione:

1
module.exports = require('./bin/calculadora')

Agora nós precisamos testar nossa aplicação correto? O jeito mais simples de testar isso é automatizando usando TDD, mas isso é assunto pra outra hora. Precisamos transformar nosso pequeno pacote um instalável, pra isso só precisamos rodar:

1
$ npm pack

Pronto o npm criou um nosso arquivo: calculadora-0.1.0.tgz que é exatamente como os arquivos ficam no repositório, agora para conseguirmos testar nossa calculadora, vamos criar uma aplicação de teste bem simples, crie uma pasta em outro lugar e inicie o npm:

1
$ mkdir teste; cd teste; npm init -y;

Agora vamos instalar nosso pacote calculadora faremos isso o comando install, porém como não publicamos nosso pacote, vamos apontar o caminho fisíco do do arquivo:

1
$ npm install ../calculadora/calculadora-0.1.0.tgz --save

Agora temos uma pasta node_modules dentro da pasta teste que é onde o npm mantém os pacotes instaldos, vamos criar um arquivo calc.js e começar a usar nossa calculadora:

1
2
3
4
5
// calc.js
var calc = require('calculadora')
console.log(calc)

Se você executar node calc.js agora vai ter uma resposta semelhante a essa:

1
2
3
4
5
{
sum: [Function: sum],
multiply: [Function: multiply],
square: [Function: square]
}

Isso quer dizer que: nossa váriavel calc agora possui o conteúdo exportado do nosso pacote calculadora que são 3 funções, sum, multiply e square, bem vamos continuar agora testando, adicione o seguinte no seu calc.js

1
2
3
console.log('Somando: ' + calc.sum(5, 2)) // 7
console.log('Multiplicando: ' + calc.multiply(5, 2)) // 10
console.log('3²: ' + calc.square(3)) // 9

Como vocês podem ver, nós já temos um módulo que pode ser utilizando em qualquer outra aplicação. Agora vamos transformar isso em uma CLI, então voltando pra nossa pasta calculadora vamos fazer o seguinte no arquivo package.json adicione o seguinte:

1
2
3
"bin": {
"calc": "./bin/calc.js"
}

Dentro da pasta bin crie o arquivo, calc.js e adicione o seguinte conteúdo:

1
2
3
4
5
#! /usr/bin/env node
var calc = require('./calculadora')
console.log(calc)

Bem pra executarmos isso a partir da linha de comando queremos usar como se tivessemos instalado de forma global, porém não queremos publicar esse módulo então pra simular isso podemos usar o comando link dessa forma:

1
$ npm link

Feito isso se você executar: calc teremos o mesmo retorno da primeira vez:

1
2
3
4
5
{
sum: [Function: sum],
multiply: [Function: multiply],
square: [Function: square]
}

Queremos executar nossa CLI da seguinte forma: calc sum 4 5 então vamos adicionar o seguinte código no nosso arquivo calc.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#! /usr/bin/env node
var calc = require('./calculadora')
var args = process.argv.splice(2)
var operator = calc[args[0]]
var x = parseInt(args[1])
var y = parseInt(args[2])
if (!operator) {
return console.log('Operação indísponivel')
}
if (operator === 'square') {
return console.log(operator(x))
}
return console.log(operator(x, y))

Primeiro criamos uma váriavel args que vai receber o valor de process.argv que é um array contendo os argumentos que foram passados quando o processo foi iniciado, sendo o primeiro indice o caminho de onde ele está sendo executado, o segundo o caminho do arquivo que está sendo executado, e o restante os argumentos reais, dessa forma nós usamos o método splice(2) que vai nos retornar um novo array a partir do indice 2 do process.argv

1
$ calc sum 2 3

É semelhante a isso:

1
2
3
4
5
6
7
[
'/home/uselessdev/.nvm/versions/node/v4.6.1/bin/node',
'/home/uselessdev/.nvm/versions/node/v4.6.1/bin/calc',
'sum',
2,
3
]

depois do splice nós temos isso na váriavel args

1
2
3
4
5
[
'sum',
2,
3
]

Sabendo disso nós podemos definir então que o primeiro indice 0 é a nossa função, e os seguintes: 1, 2 são nossos valores, logo:

1
2
3
var operator = calc[args[0]]
var x = args[1]
var y = args[2]

Depois disso nós verificamos se o valor de operator é false case for, significa que a função que foi passada pra CLI não existe, então nós retornamos uma mensagem: return console.log('Operação indísponivel')

Logo após isso nós fazemos outra verificação que é, verificar se a função passada foi square que como você se lembra recebe apenas um argumento, depois nós continuamos e finalizamos a CLI retornando o resultado.

E com isso nós finalizamos, caso você queira agora remover esse módulo basta apenas fazer o seguinte:

1
$ npm unlink

E pronto. Sobre a CLI existem alguns módulos que facilitam muito o desenvolvimento de coisas mais complexas como Commander e o Inquirer mas é claro que pra coisas simples você não vai precisar carregar outros módulos.

Espero que vocês tenham entendido e qualquer coisa, só perguntar.


Comentários: