Node JS
Introdução ao Node.js
O Node.js é um ambiente usado para a execução de código JavaScript (runtime), que é interpretado pelo V8 Engine durante a execução do programa. Essa engine (motor) é escrita em C++, com isso, escrevemos um código Java Script (mas não é 100% Java Script, existem algumas boas diferenças) que será convertido para C++ graças ao V8 Engine. Isso possibilita uma alta performance na execução do código.
O Node.js fornece um console interativo que você pode acessar digitando node
no terminal ou prompt de comando sem a necessidade de usar um arquivo com os códigos, o Python também possui um console desses. Aqui no NodeJS esse console se chama REPL (Read-Eval-Print Loop).
Para sair do console interativo, basta teclar
Ctrl+c
duas vezes ou apenasCtrl+d
.
NPM
O npm é um gerenciador de pacotes para o Node.js, assim como o pip é o gerenciador de pacotes para Python. Com ele nós poderemos baixar novas bibliotecas que serão usadas no nosso código. Também podemos fazer a execução de determinados scripts do programa que estivermos criando.
Os módulos ou bibliotecas baixadas pelo npm ficam num diretório chamado node_modules
, esse diretório deve ser descartável, a cada instalação do projeto, o npm baixa todos os pacotes novamente.
Além de instalar um pacote localmente (dentro de um projeto), também podemos instalar um pacote globalmente usando o NPM, assim ele não precisa estar dentro de um projeto específico. Podemos usar o seguinte comando:
npm install -g <nome_do_pacote>
O parâmetro -g indica que você deseja instalar o pacote globalmente, ou seja, disponível em todo o sistema, não apenas em um projeto específico. Isso é útil para pacotes que você deseja acessar de qualquer lugar no seu sistema, como ferramentas de linha de comando.
NPM vs YARN
O NPM (Node Package Manager) e o Yarn são gerenciadores de pacotes para o ecossistema Node.js. Ambos são usados para instalar, compartilhar e gerenciar as dependências do projeto. O Yarn foi criado para ser uma alternativa mais rápida e confiável ao NPM. Ele foi desenvolvido pelo Facebook, Google, Exponent e Tilde.
O Yarn oferece melhor desempenho em termos de velocidade de instalação e resolve problemas de segurança e consistência com mais eficiência do que o NPM. No entanto, o NPM também é bastante popular e tem sido amplamente utilizado na comunidade Node.js.
Criando um projeto com NPM
É possível instalar pacotes usando o NPM mesmo sem iniciar um projeto. No entanto, a maioria das ferramentas e bibliotecas disponíveis através do NPM são projetadas para serem usadas em um contexto de projeto Node.js. Esses pacotes podem exigir configurações específicas, arquivos de configuração ou estruturas de diretório que são mais adequadas para projetos Node.js.
Iniciar um projeto Node.js com o comando npm init
cria um arquivo package.json
, que é usado para gerenciar as dependências e metadados do projeto. Isso permite que você instale e gerencie pacotes específicos para o seu projeto, além de fornecer informações úteis sobre o projeto e suas dependências.
Se você está trabalhando em um projeto Node.js e precisa de pacotes adicionais, é recomendável iniciar um projeto com npm init
e, em seguida, instalar os pacotes necessários usando o NPM. Isso ajudará a organizar e gerenciar suas dependências de forma mais eficiente e evitar conflitos entre diferentes projetos.
Criando um projeto com NPM
# Crie um diretório para o projeto e entre no diretório:
mkdir p001 && cd p001
# Inicie o Projeto:
npm init
Gerenciando pacotes com NPM
Para gerenciar pacotes com o NPM, você pode usar os seguintes comandos:
Comando | Descrição |
---|---|
npm install nome_do_pacote | Instala um pacote no seu projeto. |
npm install nome_do_pacote --save | Instala um pacote e o adiciona como uma dependência no arquivo package.json . |
npm install nome_do_pacote --save-dev | Instala um pacote como uma dependência de desenvolvimento no arquivo package.json . |
npm uninstall nome_do_pacote | Remove um pacote do seu projeto. |
npm update nome_do_pacote | Atualiza um pacote para a versão mais recente. |
npm list | Lista todas as dependências do projeto. |
npm update | Atualiza os pacotes instalados do projeto. |
npm update packagename | Atualiza um pacotes específico do projeto. |
npx npm-check-updates -u | Verifica se existem algum pacote do projeto que precisa ser atualizado, nesse caso, ignora as versões dos pacotes em package.json . Depois de rodar ele, basta executar npm install nomedopacote . |
npm run script | É usado para executar scripts definidos no arquivo package.json de um projeto Node.js. |
npm link nomedopacote | Copia os arquivos de um módulo instalado globalmente para o projeto local, fazendo com que o projeto consiga acessar os arquivos do módulo. |
NPM com Script
Veja como está meu package.json
:
{
"name": "p001",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Agora adicione:
{
"name": "p001",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Sem teste configurado\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Agora teste:
$ npm run test
> p001@1.0.0 test
> echo "Sem teste configurado" && exit 1
Sem teste configurado
Instalando o Node.js e NPM no Linux
- Instalação via repositório
- Compilando o NodeJS
A instalação via repositório no Ubuntu é bastante simples:
sudo apt install -y nodejs npm
No Ubuntu 23.10, a versão atual do repositório nesse momento é:
- NodeJS: 18.13.0
- NPM: 9.2.0
Podemos ver a versão do NodeJS e do NPM usando os comandos abaixo:
# Veja a versão do NodeJS instalado:
$ nodejs -v
v18.13.0
# Veja a versão do NPM instalado:
$ npm -v
9.2.0
A instalação via compilação não é tão complicada e garante a versão mais atual dos pacotes. Primeiro acesse a página oficial do Nodejs e baixe o pacote mais recente.
# Instale os pacotes necessários para conseguir compilar pacotes:
sudo apt install build-essential gcc
# Crie o diretório abaixo e entre nele:
sudo mkdir /usr/src/nodejs-20.11.1 && cd /usr/src/nodejs-20.11.1
# Baixe o código fonte:
sudo wget https://nodejs.org/dist/v20.11.1/node-v20.11.1.tar.gz
# Descompacte o Nodejs e entre no diretório:
sudo tar xvf node-v20.11.1.tar.gz && cd node-v20.11.1
# Configure o ambiente de compilação:
sudo ./configure
Node.js configure: Found Python 3.10.12...
INFO: configure completed successfully
# Compile o Node:
sudo make
# Instale o Node:
sudo make install
Exibindo mensagens no console de execução
O console.log("")
é uma expressão que chama o método log
do objeto console
em JavaScript. O console.log
é utilizado para exibir mensagens no console do ambiente de execução, como o console de um navegador web ou o console do Node.js.
console.log("Olá, Mundo!");
Agora é só executar:
$ nodejs hello_world.js
Olá, Mundo!
Ainda podemos configurar o arquivo para ser executável e rodar o nodejs:
#!/usr/bin/nodejs
console.log("Olá, Mundo!");
Agora vamos dar permissão de execução para o arquivo:
# Dê permissão de execução:
$ chmod +x hello_world.js
# Agora execute em forma de script:
$ ./hello_world.js
Olá, Mundo!
Strings
Uma string é uma sequência de caracteres, ou seja, uma coleção ordenada de caracteres que pode incluir letras, números, espaços, pontuações e outros caracteres especiais. Em muitas linguagens de programação, incluindo JavaScript (e, por extensão, Node.js), as strings são usadas para representar e manipular texto.
Uma variável declarada fora de uma função ou bloco aninhado, será reconhecida dentro de todas as funções ou blocos aninhados do código. Entende-se que variáveis criadas fora de funções ou blocos aninhados são do escopo Global. Variáveis declarada dentro de uma função, só serão reconhecidas dentro da função em que foram declaradas, os blocos aninhados dentro de uma função herdarão as variáveis declaradas na função.
No JavaScript (e NodeJS), existem algumas palavras-chave que são usadas na criação de variáveis, essas palavras-chaves são:
let - Cria uma variável mutáveis (o valor dela poderá ser modificado mais para frente). Não pode ser chamada antes de ser declarada.
const - Cria uma variável imutável (o valor dela não poderá ser modificado mais para frente). Não pode ser chamada antes de ser declarada. Pode ser visto como constantes, que tem o mesmo significado de imutável.
var - Pode ser chamada antes de ser declarada, mas o valor
undefined
será exibido.
Comentários no código podem ser realizados usando a opção //
para linha única e para multi linhas, comece com /*
e termine com */
, semelhante ao HTML. Em JavaScript podemos declarar valores com o uso de aspas ou apóstrofos para variáveis que recebem valores de string (números não precisa). No momento de usar o valor da variável o interpretador consegue diferenciar uma string literal de uma variável durante a execução do código, isso é conhecido como avaliação dinâmica.
let variavel_peso = 95;
let person = {
nome: 'Bob',
idade: 30,
peso: variavel_peso
};
console.log(person.peso);
console.log(person);
$ node index.js 95 { nome: 'Bob', idade: 30, peso: 95 }
O código acima representa muito bem que o interpretador consegue identificar que variavel_peso
em peso: variavel_peso
é uma variável e não uma string literal. Porém, caso você queira substituir o valor da chave pelo valor de uma variável, é necessário usar colchetes []
:
let kg = 'peso';
let variavel_peso = 95;
let person = {
nome: 'Bob',
idade: 30,
[kg]: variavel_peso
};
console.log(person);
$ node index.js { nome: 'Bob', idade: 30, peso: 95 }
Concatenar strings
No Node.js (e em JavaScript em geral), podemos usar alguns operadores para concatenar strings.
Usando o operador +
para junção de strings:
let a = 'Abe';
let b = 'lha';
console.log(a + b);
$ node index.js Abelha
No JavaScript, o operador *
não é usado para repetir uma string como em Python. Para alcançar esse efeito, podemos usar repeat(N)
, onde N
é a quantidade de vezes:
let a = 'Abe';
console.log(a.repeat(3));
$ node index.js AbeAbeAbe
O operador ,
pode ser usado para unir strings com espaços (semelhante ao Python):
let a = 'Abe';
let b = 'lha';
console.log(a, b);
Neste caso, o operador
,
adiciona um espaço entre as duas strings ao imprimi-las.
$ node index.js Abe lha
Template Literals
Template literals são strings que permitem a interpolação de expressões, incluindo variáveis e até mesmo expressões aritméticas, dentro de strings. Para criar template literals devemos usar o caractere conhecido como crase.
let variavel_peso = 95;
nome = 'Bob'
idade = 30
peso = variavel_peso
console.log(`O ${nome} tem ${idade} anos de idade e pesa ${peso} Kg.`);
$ node index.js O Bob tem 30 anos de idade e pesa 95 Kg.
Interpolar Strings
Também podemos usar %s
para indicar que o valor deve ser substituído pela variável que vem logo em seguida:
const nome = "Alice";
console.log("Olá, %s!", nome);
$ node index.js Olá, Alice!
Podemos usar com mais de uma variável também:
const nome = "Alice";
const sobrenome = 'Fernanda';
console.log("Olá, %s!. Seu sobrenome %s é muito bonito", nome, sobrenome);
$ node index.js
Olá, Alice!. Seu sobrenome Fernanda é muito bonito
Argumentos com process.argv
O módulo process
função argv
fornece uma maneira de passar argumentos ao programa NodeJS.
A estrutura de process.argv
é a seguinte:
process.argv[0]
: Caminho para o executável Node.js.process.argv[1]
: Caminho para o script Node.js que está sendo executado.process.argv[2]
e além: Argumentos fornecidos na linha de comando.
Exemplo simples usando process.argv
:
// slice(2) = Pega tudo depois do segundo índice (descartando os índices 0 e 1):
const args = process.argv.slice(2)
console.log(args);
const nome = args[0].split('=')[1]
console.log(nome);
// args[0] = Primeiro índice de 'args'
// split('=')[1] = Divide quando ver o símbolo de igual e pega a primeira parte (começa em zero).
Agora no terminal execute:
nodejs index.js arg1=valor arg2
[ 'arg1=valor', 'arg2' ]
valor
Outro método é pegar os argumentos pelos seus respectivos números ou usar o slice.
const nodejs_path = process.argv[0]
console.log(nodejs_path);
const indexjs_path = process.argv[1]
console.log(indexjs_path);
const arg1 = process.argv[2]
console.log(arg1);
const arg2 = process.argv[3]
console.log(arg2);
$ nodejs index.js arg1=valor arg2
/usr/bin/node /tmp/index.js arg1=valor arg2
Módulos
No Node.js, os módulos são arquivos JavaScript que podem ser importados e usados em outros arquivos JavaScript. Eles fornecem uma maneira de organizar seu código em unidades modulares e reutilizáveis.
Existem três tipos principais de módulos no Node.js:
- Core Modules: São módulos integrados ao Node.js e podem ser usados sem instalação adicional. Alguns exemplos de módulos principais incluem
fs
,http
epath
. - Extern Modules: São módulos criados por outras pessoas e podem ser instalados usando o gerenciador de pacotes
npm
. Você pode encontrar uma variedade de módulos de terceiros no site npmjs.com. - Our Modules: São os módulos que nós mesmos criamos.
Para importar um módulo em seu código, você pode usar a palavra-chave require
ou import
. É importante notar que por questões de boas práticas, a variável que vai receber o módulo terá o mesmo nome do módulo que está sendo importado.
// Importando com 'require':
const fs = require('fs');
// Importando com 'import':
import fs from 'fs';
O conceito de "importar um módulo para dentro de uma variável" geralmente está relacionado à atribuição do conteúdo do módulo a uma variável específica. Isso é feito para que você possa acessar e utilizar as funcionalidades ou dados fornecidos pelo módulo de uma maneira mais conveniente.
Our Modules
Quando se cria módulos em Node.js, geralmente é uma prática comum exportar funcionalidades ou objetos para que possam ser usados em outros arquivos ou módulos. Exportar permite que você torne partes específicas do seu código acessíveis a outros módulos ou arquivos, promovendo uma abordagem modular e reutilizável.
Para exportar podemos usar a instrução module.exports
ou a abreviação exports
. Essencialmente, você está tornando disponíveis determinadas variáveis, funções ou objetos para outros módulos que precisam delas.
Método 1 de exportar:
function sum(a, b) {
console.log(a + b);
}
// Exportando a função
module.exports = sum;
Método 2 de exportar:
module.exports = {
sum(a, b) {
console.log(a + b);
}
}
Como a função está diretamente em
module.exports
não precisamos colocar a palavrafunction
.
Agora vamos criar o script que vai usar o módulo criado:
/* Precisa fornecer o caminho de onde está o módulo, no caso está no mesmo diretório.
Não precisa colocar o '.js'. */
const mym = require('./mymodule');
const soma = mym.sum
// Usando a função importada
soma(6, 2)
Esse método de importar um módulo segue as práticas comuns e convenções estabelecidas, visando à clareza, organização e facilidade de leitura do código.
$ nodejs index.js 8
Import e Export do ES6
ES6, ou ECMAScript 2015, é a sexta edição do padrão ECMAScript, que é a especificação na qual o JavaScript é baseado. Lançada em 2015, a ES6 introduziu várias novas funcionalidades e melhorias à linguagem JavaScript. Isso significa que são funcionalidades mais modernas e com mais recursos do que as opções anteriores.
Para podermos usar os novos métodos, precisamos modificar os nossos arquivos para a extensão .mjs
.
Novo método de exportar módulos:
function sum(a, b) {
console.log(a + b);
}
export default sum;
Novo método de importar módulos:
import soma from './mymodule.mjs';
soma(2, 9)
Módulos Externos
O comando npm init
é utilizado para inicializar um novo projeto Node.js. Ao executar este comando no terminal, o npm
guiará você por uma série de perguntas interativas para configurar as informações básicas do seu projeto, como nome, versão, descrição, ponto de entrada (entry point), scripts e outras configurações.
O comando npm init
também gera um arquivo chamado package.json
. Esse é um arquivo de configuração fundamental que contém informações sobre o projeto, dependências, scripts de execução, versão, autor, etc.
Sempre que for iniciar um novo projeto, deve-se executar npm init
, após isso os módulos ficam mapeados e podem ser instalados. É nesse ponto em que os módulos são salvos no diretório nodes_modules
.
# Crie um diretório para iniciar o projeto e entre nele:
$ mkdir nodep1 && cd nodep1
# Agora inicialize o projeto (por hora as opções default vão servir):
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (nodep1)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /home/bsilva/nodep1/package.json:
{
"name": "nodep1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes) yes
minimist
O minimist
é um módulo Node.js que facilita o parsing (análise) de argumentos da linha de comando. Ele é útil quando você precisa extrair valores específicos de uma lista de argumentos passados na linha de comando ao executar um script. A principal funcionalidade do minimist
é converter os argumentos da linha de comando em um objeto JavaScript, tornando mais fácil acessar e utilizar esses valores.
Primeiro, instale o minimist
usando o npm:
$ npm install minimist
added 1 package, and audited 2 packages in 481ms
1 package is looking for funding
run `npm fund` for details
found 0 vulnerabilities
Crie um arquivo para js
para testar:
const minimist = require('minimist');
// Obtendo os argumentos da linha de comando
const args = minimist(process.argv.slice(2));
// Extraindo valores específicos
const nome = args.nome || 'Usuário';
const idade = args.idade || 25;
console.log(`Olá, ${nome}! Você tem ${idade} anos.`);
Agora execute o script com argumentos da linha de comando:
$ node index.js --nome=Bob --idade=30 Olá, Bob! Você tem 30 anos.
Como nós usamos ||
na declaração das variáveis nome
e idade
, caso não seja fornecido nada, será usado os valores que fornecemos como valores padrões:
$ node index.js Olá, Usuário! Você tem 25 anos.
inquirer
O inquirer
é um módulo que simplifica a criação de interfaces de linha de comando interativas, especialmente quando se trata de fazer perguntas ao usuário e coletar suas respostas. Ele oferece uma variedade de tipos de perguntas predefinidos, como listas, caixas de seleção, perguntas abertas, entre outros.
Para usar o inquirer
, temos que instalar ele:
npm install inquirer@8.1.2
A versão mais recente possui algumas diferenças na importação, podendo gerar alguns erros.
Veja um exemplo básico de como usar o inquirer
:
const inquirer = require('inquirer');
// Definindo as perguntas
const perguntas = [
{
type: 'input',
name: 'nome',
message: 'Qual é o seu nome?'
},
{
type: 'list',
name: 'fruta',
message: 'Escolha uma fruta:',
choices: ['Maçã', 'Banana', 'Morango', 'Uva']
}
];
// Perguntando ao usuário
inquirer.prompt(perguntas)
// O que será executado de fato:
.then((answers) => {
console.log('Respostas:', answers);
})
// Sempre que der erro ele vai para o 'catch', usamos ele para exibir o erro:
.catch((error) => {
console.error('Erro:', error);
});
$ node index.js
? Qual é o seu nome? fulano ? Escolha uma fruta: Banana Respostas: { nome: 'fulano', fruta: 'Banana' }
O inquirer.prompt
é usado para apresentar as perguntas definidas no array perguntas
. As respostas do usuário são capturadas no método .then()
.
O inquirer
fornece diversos tipos de perguntas (tipo 'input'
, 'list'
, 'checkbox'
, etc.), permitindo que você colete informações de maneira flexível. Além disso, você pode personalizar as perguntas de acordo com as necessidades do seu aplicativo.
As variáveis dentro de .then
e .catch
é onde o inquirer vai armazenar as respostas.
Em JavaScript, as Promises (Promessas) são objetos que representam o resultado de uma operação assíncrona, que pode ser resolvida (com sucesso) ou rejeitada (com falha). As promessas permitem que você trabalhe com código assíncrono de uma maneira mais limpa e eficiente, evitando assim o aninhamento excessivo de callbacks (conhecido como callback hell).
Uma promessa pode estar em um de três estados:
- Pendente (Pending): O estado inicial de uma promessa. Isso significa que a operação assíncrona ainda não foi concluída.
- Resolvida (Fulfilled): A operação assíncrona foi concluída com sucesso.
- Rejeitada (Rejected): A operação assíncrona falhou.
As promessas têm dois métodos principais que você pode usar para interagir com elas:
then()
: Este método é usado para lidar com o caso em que a promessa é resolvida com sucesso. Ele recebe duas funções de retorno de chamada como argumentos, uma para o caso de sucesso e outra para o caso de falha.catch()
: Este método é usado para lidar com o caso em que a promessa é rejeitada. Ele recebe uma função de retorno de chamada que será chamada se a promessa for rejeitada.
Neste exemplo:
- Criamos uma nova promessa que simula uma operação assíncrona.
- Dentro da promessa, usamos
resolve()
para indicar sucesso ereject()
para indicar falha. - Usamos
then()
para lidar com o caso de sucesso ecatch()
para lidar com o caso de falha.
Módulos Built-in
O Node vem com diversos módulos built-in prontos para serem utilizados. Vejamos alguns módulos Built-In do Node que acabei documentando.
Módulo FS
O módulo fs
(File System) é um módulo integrado no Node.js que fornece funcionalidades relacionadas ao sistema de arquivos. Com o fs
, você pode realizar várias operações de leitura, escrita e manipulação de arquivos e diretórios no sistema de arquivos local.
fs.readFile
Lêr o conteúdo de um arquivo.
const fs = require('fs');
// fs.readFile(): Lê o conteúdo de um arquivo.
fs.readFile('arquivo.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
fs.writeFile
Escrever num arquivo.
const fs = require('fs');
// fs.writeFile(): Escreve dados em um arquivo, substituindo o conteúdo existente.
fs.writeFile('arquivo.txt', 'Novo conteúdo', 'utf8', (err) => {
if (err) {
console.error(err);
return;
}
console.log('Arquivo escrito com sucesso!');
});
fs.readdir
Lê o conteúdo de num diretório, semelhante ao ls
do Linux.
const fs = require('fs');
// fs.readdir(): Lista os arquivos em um diretório.
fs.readdir('.', (err, files) => {
if (err) {
console.error(err);
return;
}
console.log('Arquivos no diretório:', files);
});
fs.mkdir
Cria um diretório, semelhante ao mkdir
do Linux.
const fs = require('fs');
// fs.mkdir(): Cria um novo diretório.
fs.mkdir('novo_diretorio', (err) => {
if (err) {
console.error(err);
return;
}
console.log('Diretório criado com sucesso!');
});
fs.rmdir
Remove um diretório, semelhante ao rmdir
do Linux.
const fs = require('fs');
// fs.rmdir()`: Remove um diretório.
fs.rmdir('diretorio_para_remover', (err) => {
if (err) {
console.error(err);
return;
}
console.log('Diretório removido com sucesso!');
});
PATH
O módulo path
é um módulo integrado do Node.js que fornece utilitários para trabalhar com caminhos de arquivos e diretórios. Ele é particularmente útil para lidar com caminhos de forma segura e independente do sistema operacional, garantindo que seu código seja portátil e funcione em diferentes plataformas.
path.extname
Retorna a extensão de um arquivo.
const path = require('path');
const caminhofile = path.extname("arquivo.txt");
// Resultado depende do sistema operacional: /pasta/subpasta/arquivo.txt ou \pasta\subpasta\arquivo.txt
console.log(caminhofile)
$ node index.js .txt
readline
O módulo readline
é utilizado para realizar operações de leitura de entrada do usuário a partir de streams (como o terminal). Ele fornece uma interface para ler dados de uma stream linha por linha, o que é útil para criar interfaces de linha de comando interativas.
Além disso, o método question
é uma parte do módulo readline
que permite fazer perguntas interativas ao usuário, esperar por uma resposta e executar uma função de retorno de chamada com a resposta fornecida pelo usuário.
Aqui está um exemplo básico de como usar readline
e readline.question
:
// Importa o módulo já executando ele:
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// Pergunta ao usuário
readline.question('Qual é o seu nome? ', (resposta) => {
console.log(`Olá, ${resposta}!`);
// Fecha a interface de leitura
readline.close();
});
readline.createInterface
é usado para criar uma interface de leitura a partir das streams de entrada (process.stdin
) e saída (process.stdout
).
readline.question
é utilizado para fazer uma pergunta ao usuário, e a função de retorno de chamada é acionada quando o usuário fornece uma resposta. O método readline.close()
é chamado para encerrar a interface de leitura depois que a pergunta é respondida.
resposta
é o nome da variável onde vamos armazenar a resposta do usuário (qualquer coisa que ele digitar).
EventEmitter
O EventEmitter
é uma classe no módulo events
que fornece uma implementação de um padrão de design chamado "Emitter/Observer" ou "Publish/Subscribe". Esse padrão permite que objetos emitam e escutem eventos nomeados, facilitando a comunicação e coordenação entre partes distintas de um aplicativo.
A classe EventEmitter
é usada para criar objetos que podem emitir (disparar) eventos e registrar ouvintes (listeners) para esses eventos. Um objeto que herda de EventEmitter
pode ser usado como um canal de comunicação entre diferentes partes do código.
Aqui está um exemplo básico de como usar EventEmitter
:
const EventEmitter = require('events');
// Criando um objeto EventEmitter
const evenEmitter = new EventEmitter();
// Registrando um ouvinte para o evento 'eventoPersonalizado'
evenEmitter.on('start', () => {
console.log('durante');
});
console.log('Antes');
// Emitindo o evento 'start' com alguns dados:
evenEmitter.emit('start');
console.log('depois');
$ node index.js
Antes
durante
depois
HTTP
O módulo http
é usado para criar servidores HTTP e interagir com protocolos HTTP. Com este módulo, você pode construir aplicativos web, criar APIs e lidar com solicitações e respostas HTTP.
const http = require('http');
const port = 8080
const server = http.createServer((req, res) => {
res.write('Hellow World!');
res.end(); // encerra a conexão para nao ficar aberto para sempre!
});
server.listen(port, () => {
console.log(`Servidor rodando em http://localhost:${port}/`);
});
O método createServer
cria o servidor web, ele recebe uma função de retorno de chamada que é chamada sempre que uma solicitação é recebida. Esta função de retorno de chamada recebe dois argumentos: req
(requisição) e res
(resposta).
$ node index.js Servidor rodando em http://localhost:${port}/
Hellow World!
Retornar um HTML no HTTP
const http = require('http');
const port = 8080
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/html');
res.end('<h1>Olá, este é apenas um teste!!!');
});
server.listen(port, () => {
console.log(`Servidor rodando em http://localhost:${port}/`);
});
URL
O módulo url
é um módulo que fornece utilitários para manipulação e análise de URLs. Ele é útil para extrair informações específicas de URLs, como partes do caminho, parâmetros de consulta, hostname, etc.
const url = require('url');
const url_address = 'https://www.meusite.com.br/catalog?produtos=cadeira';
const parsedUrl = url.parse(url_address, true); // O segundo argumento 'true' faz com que os parâmetros de consulta sejam convertidos em um objeto
console.log('Protocolo:', parsedUrl.protocol);
console.log('Host:', parsedUrl.host);
console.log('Hostname:', parsedUrl.hostname);
console.log('Porta:', parsedUrl.port);
console.log('Caminho:', parsedUrl.pathname);
console.log('Parâmetros de Consulta:', parsedUrl.query);
$ node index.js Protocolo: https: Host: www.meusite.com.br Hostname: www.meusite.com.br Porta: null Caminho: /catalog Parâmetros de Consulta: [Object: null prototype] { produtos: 'cadeira' }
Função
Uma função é um bloco de código que realiza uma tarefa específica. Ela pode ser chamada de qualquer lugar do seu código, desde que você chame ela após declara-lá, o que facilita a organização e o reuso de código.
Criando uma função simples:
// Cria a função chamada minhaFuncao:
function minhaFuncao() {
console.log("Olá, mundo!");
}
// Chamando a função
minhaFuncao();
Nós também podemos passar argumentos para uma função. Os argumentos são valores que a função pode usar para realizar uma tarefa.
// Cria a função soma, nela definimos duas variáveis: A e B:
function soma(a, b) {
// Retorna a soma de a e b
return a + b;
}
// Chamando a função informando o valor de A (a=2) e B (b=3):
let resultado = soma(2, 3);
console.log(resultado); // Imprime 5
Função Estática
Uma função estática é uma função associada a uma classe ou a um objeto que pode ser chamada sem criar uma instância desse objeto. No contexto de classes, uma função estática é definida usando a palavra-chave static
. Isso significa que a função está associada à classe em si, e não a instâncias individuais da classe.
Isso permite que você chame a função diretamente na classe, sem precisar criar um objeto dessa classe. Aqui está um exemplo de como uma função estática pode ser definida em uma classe em Node.js:
class MyClass {
static staticFunction() {
console.log('Esta é uma função estática!');
}
}
// Chama a função estática diretamente na classe, sem criar uma instância
MyClass.staticFunction();
$ node index.js Esta é uma função estática!
No exemplo acima,
staticFunction
é uma função estática da classeMyClass
, e pode ser chamada diretamente na classe sem instanciá-la.
Uma função estática em uma classe é útil para operações que não dependem de uma instância específica da classe, mas ainda são úteis para a classe como um todo. Você pode chamá-las diretamente na classe, sem precisar criar um objeto daquela classe.
Estruturas de condições
Estruturas de condição permitem que um programa execute diferentes blocos de código com base em uma condição lógica. Essas estruturas permitem tomar decisões e direcionar o fluxo do programa com base em diferentes cenários.
No JavaScript, você usará os operadores de comparação da seguinte forma:
<
: Menor que>
: Maior que<=
: Menor ou igual a>=
: Maior ou igual a==
: Igual a (verifica apenas o valor, não o tipo)===
: Estritamente igual a (verifica o valor e o tipo)!=
: Diferente de (verifica apenas o valor, não o tipo)!==
: Estritamente diferente de (verifica o valor e o tipo)
Note que o operador de atribuição
=
é usado apenas para atribuir valores a variáveis.
IF
A estrutura if
permite que um bloco de código seja executado se uma condição específica for verdadeira.
#################################
# Estrutura #
#################################
if (condition) {
// Código a ser executado se a condição for verdadeira
} else if (condition) {
// Código a ser executado se a condição for verdadeira
} else {
// Código a ser executado se a condição for falsa
}
Exemplo geral do uso com IF
:
const objeto = { chave1: 'valor1', chave2: 'valor2' };
if ('chave1' in objeto) {
console.log('A chave1 existe no objeto.');
} else {
console.log('A chave1 não existe no objeto.');
}
Switch
A estrutura switch é usada para avaliar uma expressão em relação a vários casos possíveis.
switch (expressao) {
case valor1:
// Bloco de código a ser executado se expressao for igual a valor1
break;
case valor2:
// Bloco de código a ser executado se expressao for igual a valor2
break;
default:
// Bloco de código a ser executado se nenhum caso corresponder
}
Estruturas de repetição
As estruturas de repetição permitem a execução repetida de um bloco de código com base em determinadas condições ou contadores. Essas estruturas são valiosas para automatizar tarefas repetitivas e melhorar a eficiência dos programas.
For
O loop for
é especialmente útil quando você sabe antecipadamente quantas vezes deseja que o código seja repetido. Ele geralmente possui três partes principais: uma inicialização, uma condição de continuação e uma expressão de iteração.
#################################
# Estrutura #
#################################
for (<initialization>; <continuation condition>; <iterable>) {
<statement(s)>
}
Exemplo geral do uso com For
:
// Imprime os números pares de 0 a 10 usando um loop for
for (let i = 0; i <= 10; i++) {
if (i % 2 === 0) {
console.log(i);
}
}
i % 2
?A expressão i % 2
calcula o resto da divisão de i
por 2
. Esse operador é chamado de operador de módulo. O resultado dessa expressão será zero se i
for um número par e será 1
se i
for um número ímpar.
While
O loop while
é uma estrutura de repetição mais flexível, pois continua executando o bloco de código enquanto uma condição especificada for verdadeira.
#################################
# Estrutura #
#################################
while (<condition>) {
<statement(s)>
}
Exemplo geral do uso com While
:
let contador = 0;
while (contador < 5) {
console.log(`Iteração ${contador + 1}`);
contador++;
}
// Resultado:
// Iteração 1
// Iteração 2
// Iteração 3
// Iteração 4
// Iteração 5
Objetos
Os objetos em JavaScript são coleções de pares chave-valor, onde as chaves são strings ou símbolos e os valores podem ser de qualquer tipo de dado, incluindo outros objetos. No Python é conhecido como Dicionários.
// Criando um Objeto simples e vazio:
let empty_object = {};
// Criando um Objeto simples e vazio:
let person = {
nome: 'Bob',
idade: 30,
peso: 95
};
Podemos também criar objetos aninhados. Objetos aninhados são basicamente uma chave um valor, mas o valor acaba recebendo outro conjunto de chaves e valores, é uma prática comum para organizar e estruturar dados de maneira hierárquica. Segue um exemplo simples:
let pessoa = {
nome: 'João',
idade: 25,
endereco: {
rua: 'Rua Principal',
cidade: 'Cidade A',
estado: 'Estado X'
}
};
// Acessando propriedades do objeto aninhado
console.log(pessoa.nome);
console.log(pessoa.endereco.cidade);
console.log(pessoa);
$ node index.js João Cidade A depois { nome: 'João', idade: 25, endereco: { rua: 'Rua Principal', cidade: 'Cidade A', estado: 'Estado X' } }
Arrays
Os Arrays funcionam como coleções ordenadas de elementos do mesmo tipo, armazenados em uma sequência contígua de memória. Imagine um array como uma fila onde cada item ocupa uma posição específica. Os Arrays são conhecidos como listas no Python e Array em Shell Script 😅.
O Array sempre começa em 0.
// Criando um Array:
const array1 = [1, 2, 3, 4]
const array2 = ['laranja', 'mamão', 'maçã', 'uva']
// A variável `segundaFruta` recebe o segundo elemento de array2 (índice 1)
const segundaFruta = array2[1];
console.log(segundaFruta);
// Percorrendo o array usando for loop
for (let i = 0; i < array2.length; i++) {
console.log(array2[i]);
}
$ node index.js mamão laranja mamão maçã uva
push()
O método push é usado para adicionar um ou mais elementos ao final de um array.
const array = ["a", "b", "c"];
array.push("d"); // Adiciona "d" ao final do array
console.log(array);
$ node index.js ["a", "b", "c", "d"]
spread ...
O operador spread ...
em JavaScript é utilizado para copiar elementos de um array (ou objetos) para outro array (ou objeto) de forma rápida e concisa. Ele também pode ser utilizado para espalhar elementos em uma função ou em uma expressão.
const array = ["a", "b", "c"];
const newArray = [...array, "d"];
console.log(newArray);
$ node index.js ["a", "b", "c", "d"]
concat
O método concat
em JavaScript é utilizado para combinar dois ou mais arrays, criando um novo array que contém todos os elementos dos arrays originais. Ele não modifica os arrays originais, mas retorna um novo array contendo os elementos concatenados.
const array = ["a", "b", "c"];
const newArray = array.concat(["d"]);
console.log(newArray);
$ node index.js ["a", "b", "c", "d"]
pop()
O método pop()
em JavaScript é utilizado para remover o último elemento de um array e retornar esse elemento. Ele modifica o array original, reduzindo seu comprimento em 1.
const array = ["a", "b", "c"];
const removedValue = array.pop(); // Remove "c" do final do array
console.log(array);
console.log(removedValue);
$ node index.js ["a", "b"] "c"
splice()
O método splice()
em JavaScript é utilizado para modificar o conteúdo de um array, adicionando ou removendo elementos. Ele permite realizar operações mais complexas do que os métodos push()
e pop()
, pois você pode adicionar, remover e substituir elementos em posições específicas do array.
A sintaxe geral do método splice()
é a seguinte:
array.splice(inicio, quantidadeRemovida, elemento1, elemento2, ...);
inicio
: Índice no array onde a modificação começará.quantidadeRemovida
: Número de elementos a serem removidos a partir do índice de início. Se for0
, nenhum elemento é removido.elemento1, elemento2, ...
: Elementos a serem adicionados no array a partir do índice de início.
Adicionar elementos em uma posição específica:
let meuArray = [1, 2, 3, 4, 5];
meuArray.splice(2, 0, 6, 7);
console.log(meuArray); // Resultado: [1, 2, 6, 7, 3, 4, 5]
Neste exemplo, a partir do índice 2, nenhum elemento é removido (
0
), e os elementos6
e7
são adicionados no array.
Remover elementos em uma posição específica:
let meuArray = [1, 2, 3, 4, 5];
meuArray.splice(2, 2);
console.log(meuArray); // Resultado: [1, 2, 5]
Neste exemplo, a partir do índice 2, dois elementos são removidos, resultando no array
[1, 2, 5]
.
Substituir elementos em uma posição específica:
let meuArray = [1, 2, 3, 4, 5];
meuArray.splice(2, 2, 6, 7);
console.log(meuArray); // Resultado: [1, 2, 6, 7, 5]
Neste exemplo, a partir do índice 2, dois elementos são removidos, e os elementos
6
e7
são adicionados no lugar, resultando no array[1, 2, 6, 7, 5]
.
filter()
O método filter()
em JavaScript é utilizado para criar um novo array contendo apenas os elementos do array original que atendem a uma condição específica. Ele não modifica o array original, mas retorna um novo array contendo os elementos filtrados.
const array = ["a", "b", "c", "d"];
const newArray = array.filter(element => element !== "b"); // Adiciona os elementos que são diferente "b" do array
console.log(newArray); // ["a", "c", "d"]
A expressão
element => element !== "b"
é uma função de seta que verifica se cada elemento do array original (array) é diferente deb
. Se o elemento não for igual ab
, ele é incluído no novo array (newArray). Se for igual ab
, é excluído do novo array.
indexOf()
O método indexOf
é utilizado para encontrar a posição de uma determinada substring em uma string. Ele retorna o índice da primeira ocorrência da substring na string, ou -1
se a substring não for encontrada.
const array = ["a", "b", "c", "d"];
const position = array.indexOf("c"); // Retorna a posição de "c" no array
console.log(position);
$ node index.js 2
findIndex()
O método findIndex
é uma função de array em JavaScript, e não uma função diretamente relacionada a strings como o indexOf
. No entanto, é possível utilizá-lo para encontrar o índice de um elemento em um array que satisfaça uma determinada condição.
const array = ["a", "b", "c", "d"];
const position = array.findIndex(element => element === "c"); // Retorna a posição de "c" no array
console.log(position);
$ node index.js 2
chalk
O chalk
é uma biblioteca popular em Node.js usada para colorir a saída no console. Com ela, você pode adicionar cores, estilos e fundos ao texto que é exibido no terminal. Isso é particularmente útil ao criar interfaces de linha de comando (CLI) ou ao destacar mensagens importantes.
Para utilizar o chalk
, precisamos instalá-lo primeiro, para isso vamos usar o npm
:
# Instalando o chalk localmente:
npm install chalk
added 1 package in 207ms
1 package is looking for funding
run `npm fund` for details
Para desinstalar a versão do Chalk, podemos usar:
npm uninstall chalk
.
Aqui está um exemplo simples de como usar o chalk
:
const chalk = require('chalk');
// Exemplo de uso
console.log(chalk.blue('Este é um texto azul'));
console.log(chalk.red.bold('Este é um texto vermelho e em negrito'));
console.log(chalk.bgGreen.white('Este texto tem fundo verde e cor branca'));
// Com template literals
const mensagem = chalk.yellow`Esta mensagem está em amarelo`;
console.log(mensagem);
O código acima usa diversas funções do chalk
para colorir e estilizar o texto. Algumas das funções comumente utilizadas incluem chalk.bold
, chalk.italic
, chalk.underline
, e várias funções de cor, como chalk.red
, chalk.blue
, chalk.green
, entre outras.
O chalk
fornece uma maneira fácil de adicionar estilo ao seu output no console, tornando a leitura e interpretação das mensagens mais visuais e informativas.
Módulos com Argumentos
Vou criar um script que vai usar um módulo e fornecer argumentos via scripts passando para o módulo executar uma soma.
module.exports = {
soma(a,b) {
console.log(a + b);
}
}
const minimist = require('minimist');
// o '.soma' estamos pegando a função 'soma' de dentro do módulo 'soma' (./soma)
const soma = require('./soma').soma
// Obtendo os argumentos da linha de comando
const args = minimist(process.argv.slice(2));
// parseInt é uma função usada para analisar uma string e retornar um número inteiro:
const a = parseInt(args['a']);
const b = parseInt(args['b']);
soma(a, b)
Agora vamos executar:
$ node index.js --a=2 --b=98
100
Console
O objeto console
é uma parte integrante do ambiente JavaScript, comumente utilizado em ambientes como navegadores (dentro do console do desenvolvedor) e no ambiente Node.js. Ele fornece métodos para a exibição de mensagens no console do desenvolvedor ou na saída padrão do terminal, dependendo do ambiente de execução.
Abaixo podemos ver alguns dos métodos mais comuns disponíveis no objeto console
.
Console.log
Imprime mensagens no console.
console.log("Olá, mundo!");
Console.info
Funciona de maneira semelhante ao console.log
, mas geralmente é usado para mensagens informativas.
console.info("Isso é uma informação.");
Console.warn
Exibe uma mensagem de advertência.
console.warn("Isso é uma advertência!");
Console.error
Exibe uma mensagem de erro.
console.error("Algo deu errado!");
Console.table
Exibe dados tabulares na forma de uma tabela.
const dados = [
{ nome: 'Alice', idade: 25 },
{ nome: 'Bob', idade: 30 }
];
console.table(dados);
$ node index.js ┌─────────┬─────────┬───────┐ │ (index) │ nome │ idade │ ├─────────┼─────────┼───────┤ │ 0 │ 'Alice' │ 25 │ │ 1 │ 'Bob' │ 30 │ └─────────┴─────────┴───────┘
Console.clear
Limpa o console.
console.clear();
Console.group
Agrupa mensagens no console.
console.group("Grupo A");
console.log("Mensagem 1");
console.log("Mensagem 2");
console.groupEnd();
console.group("Grupo B");
console.log("Mensagem 3");
console.log("Mensagem 4");
console.groupEnd();
$ node index.js Grupo A Mensagem 1 Mensagem 2 Grupo B Mensagem 3 Mensagem 4
Console.assert
Exibe uma mensagem de erro se a expressão fornecida for falsa.
console.assert(2 + 2 === 5, "Erro: 2 + 2 não é igual a 5");
$ node index.js Assertion failed: Erro: 2 + 2 não é igual a 5
Console.count
O console.count
é usado para contar quantas vezes o método foi chamado. Ele é útil para rastrear a frequência de execução de um trecho de código específico.
A sintaxe básica do console.count
é a seguinte:
console.count([rótulo]);
rótulo
(opcional): Uma string que serve como identificador para o contador. Se fornecido, o contador será incrementado apenas se o rótulo for o mesmo nas chamadas subsequentes.
Exemplo:
function exemplo() {
console.count("Chamada da Função");
console.log("Executando a função...");
}
exemplo();
exemplo();
exemplo();
$ node index.js Chamada da Função: 1 Executando a função... Chamada da Função: 2 Executando a função... Chamada da Função: 3 Executando a função...
Lidando com erros
O try
, catch
, e throw
são construções usadas para lidar com exceções e erros.
try
O bloco try
é usado para envolver um trecho de código no qual você espera que ocorram erros. O código dentro do bloco try
é executado normalmente. Se uma exceção ocorrer durante a execução deste bloco, o controle é transferido para o bloco catch
.
try {
// Código que pode gerar uma exceção
} catch (error) {
// Bloco executado se ocorrer uma exceção
}
catch
O bloco catch
é onde você trata a exceção capturada no bloco try
. O parâmetro error
(ou qualquer nome que você escolher) contém informações sobre a exceção que ocorreu.
try {
// Código que pode gerar uma exceção
} catch (error) {
// Bloco executado se ocorrer uma exceção
console.error('Ocorreu um erro:', error);
}
throw
A palavra-chave throw
é usada para lançar uma exceção manualmente. Você pode usá-la para sinalizar que algo inesperado ocorreu em seu código.
const x = "10"
if (!Number.isInteget(x)) {
throw new Error("O valor não é inteiro.")
}
console.log('Continuando o código');
$ node index.js 95 { nome: 'Bob', idade: 30, peso: 95 }
HTTP com URL
Vejamos um exemplo muito simples e básico.
const http = require('http');
const port = 8080
const server = http.createServer((req, res) => {
const urlinfo = require('url').parse(req.url, true)
const name = urlinfo.query.name
res.statusCode = 200
res.setHeader('Content-Type', 'text/html');
if(!name) {
res.end('<h1>Coloque seu nome!</h1><form method="GET"><input type="text" name="name" /><input type="submit" value="Enviar" /></form>');
} else {
res.end(`<h1>Olá, seja bem vindo ${name} </h1>`);
}
});
server.listen(port, () => {
console.log(`Servidor rodando em http://localhost:${port}/`);
});
Renderizando HTML com FS
const http = require('http');
const fs = require('fs');
const port = 8080
const server = http.createServer((req, res) => {
fs.readFile('mensagem.html', function(err, data) {
res.writeHead(200, {'Content-Type': 'text/html'})
res.write(data)
return res.end()
})
})
server.listen(port, () => {
console.log(`Servidor rodando em http://localhost:${port}/`);
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mensagem</title>
</head>
<body>
<h1>Este arquivo foi lido pelo fs!</h1>
</body>
</html>
Linha | Código | Descrição |
---|---|---|
1 | const http = require('http'); | Importa o módulo http do Node.js, que fornece funcionalidades para criar servidores HTTP. |
2 | const fs = require('fs'); | Importa o módulo fs (file system) do Node.js, que fornece funcionalidades para manipular arquivos. |
4 | const port = 8080 | Define a variável port com o valor 8080 , indicando a porta em que o servidor irá escutar. |
6-16 | const server = http.createServer((req, res) => { ... }) | Cria um servidor HTTP usando o método createServer . A função de retorno de chamada é executada quando uma solicitação é recebida. |
8-15 | fs.readFile('mensagem.html', function(err, data) { ... }) | Lê o conteúdo do arquivo mensagem.html de forma assíncrona. A função de retorno de chamada é executada quando a leitura é concluída. |
10 | res.writeHead(200, {'Content-Type': 'text/html'}) | Configura o cabeçalho da resposta com o código de status 200 (OK) e o tipo de conteúdo como text/html . |
11 | res.write(data) | Escreve o conteúdo do arquivo lido na resposta. |
12 | return res.end() | Finaliza a resposta, indicando que nenhum outro conteúdo será enviado. |
18-20 | server.listen(port, () => { ... }) | Inicia o servidor para escutar na porta especificada (8080 ) e exibe uma mensagem quando estiver pronto para receber solicitações. |
A função dentro de fs.readFile
é uma função de retorno de chamada (callback). No Node.js, muitas operações, como a leitura de arquivos, são assíncronas. Isso significa que o código não espera pela conclusão da operação e continua executando outras tarefas enquanto a operação assíncrona está em andamento.
A função de retorno de chamada é uma maneira de lidar com o resultado de uma operação assíncrona quando ela é concluída. Nesse caso específico, a função de retorno de chamada é acionada quando a leitura do arquivo mensagem.html
é concluída.
err
: É o objeto de erro. Se a operação for bem-sucedida,err
seránull
. Se houver um erro,err
conterá informações sobre o erro.data
: Contém os dados lidos do arquivo. Se não houver erros,data
conterá o conteúdo do arquivo.
Escrevendo em arquivos
Vamos usar um formulário HTML para escrever num arquivo.
const http = require("http");
const fs = require("fs");
const url = require("url");
const port = 8080;
const server = http.createServer((req, res) => {
var urlInfo = require("url").parse(req.url, true);
const name = urlInfo.query.name;
res.statusCode = 200;
res.setHeader("Content-Type", "text/html");
if (!name) {
fs.readFile("index.html", function (err, data) {
res.writeHead(200, { "Content-Type": "text/html" });
res.write(data);
return res.end();
});
} else {
fs.writeFile("arquivo.txt", name, function (err, data) {
res.writeHead(302, {
Location: "/",
});
return res.end();
});
}
});
server.listen(port, () => {
console.log(`Servidor rodando na porta: ${port}`);
});
A linha de código var urlInfo = require("url").parse(req.url, true);
utiliza o módulo url
para analisar a URL contida no objeto de solicitação (req
).
.parse(req.url, true)
: O métodoparse
do módulourl
é chamado para analisar a URL contida emreq.url
.req.url
: Contém a parte da URL após o domínio, incluindo o caminho e os parâmetros de consulta.true
: O segundo argumento (true
) especifica que os parâmetros de consulta devem ser convertidos em um objeto. Se forfalse
ou omitido, os parâmetros de consulta serão retornados como uma string.
A linha de código const name = urlInfo.query.name;
está extraindo o valor do parâmetro de consulta chamado "name" do objeto urlInfo
.
urlInfo.query
: A propriedadequery
do objetourlInfo
contém um objeto com os parâmetros de consulta da URL. O segundo argumentotrue
indica que os parâmetros de consulta devem ser convertidos em um objeto.urlInfo.query.name
: Aqui,name
é uma propriedade específica que está sendo acessada no objetourlInfo.query
. Se a URL da solicitação incluir um parâmetro de consulta chamado "name", entãourlInfo.query.name
conterá o valor associado a esse parâmetro.const name = ...;
: O valor obtido é atribuído à constantename
. Agora, a variávelname
contém o valor do parâmetro de consulta "name" da URL.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mensagem</title>
</head>
<body>
<h1>Como você se chama?</h1>
<form action="/" method="GET">
<input type="text" name="name" placeholder="Insira seu nome" />
<input type="submit" value="Enviar" />
</form>
</body>
</html>
Criando um sistema de contas
# Crie o projeto:
mkdir p002 && cd p002 && npm init -y
# Instale os pacotes abaixo:
npm install inquirer@8.1.2 chalk@4.1.2
Adicione a sessão abaixo no seu package.json
(sessão em destaque):
{
"name": "p002",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Crie index.js
com o conteúdo abaixo:
// modulos externos:
const inquirer = require("inquirer");
const chalk = require("chalk");
// modulos internos:
const fs = require("fs");
console.log('Iniciando o sistema de contas!')
process.setMaxListeners(0)
function operationsonaccounts () {
inquirer.prompt([{
type: 'list',
name: 'action',
message: 'O que você deseja fazer? ',
choices: [
'Criar conta',
'Deletar uma conta',
'Consultar saldo',
'Depositar',
'Sacar',
'Sair'],
},
])
.then((answer) => {
const action = answer['action']
if (action === 'Criar conta') {
createAccount()
} else if (action === 'Depositar') {
Depositar()
} else if (action === 'Deletar uma conta') {
delconta()
} else if (action === 'Consultar saldo') {
getAccountBalance()
} else if (action === 'Sacar') {
pegarmoney()
} else if (action === 'Sair') {
console.log(chalk.bgBlue.black('Obrigado por usar o Accounts!'))
process.exit()
}
})
.catch((err) => console.log(err))
}
// create user account
function createAccount() {
console.log(chalk.bgGreen.black('Obrigado por escolher nosso sistema!'))
console.log(chalk.green('Escolha uma das opções a seguir'))
criarconta()
}
// Função para criar a conta:
function criarconta() {
inquirer
.prompt([
{
name: 'accountName',
message: 'Digite o nome da sua conta:',
},
])
.then((answer) => {
console.info(answer['accountName'])
const accountName = answer['accountName']
// Verifica se o diretório 'accounts' existe!
if (!fs.existsSync('accounts')) {
// Se não existir, cria!
fs.mkdirSync('accounts')
}
// Verifica se o nomedaconta.json existe:
if (fs.existsSync(`accounts/${accountName}.json`)) {
console.clear();
console.log(
chalk.bgRed.black('Esta conta já existe, escolha outro nome!'),
)
// Se existir, pede para escolher outro nome
criarconta(accountName)
return
} else {
// Se não existir, cria o json com o nome da conta
fs.writeFileSync(
`accounts/${accountName}.json`,
'{"balance":0}',
function (err) {
console.log(err)
},
)
console.log(chalk.green('Parabéns, sua conta foi criada!'))
// Agora volta do início:
operationsonaccounts()
}
})
}
function delconta() {
// Verifica se o diretório 'accounts' existe!
if (!fs.existsSync('accounts')) {
// Se não existir, cria!
console.clear();
console.log(chalk.bgRed.black("Nenhuma conta no sistema!"))
operationsonaccounts()
} else {
inquirer
.prompt([
{
name: 'accountName',
message: 'Digite o nome da conta para deletar:',
},
])
.then((answer) => {
console.info(answer['accountName'])
const accountName = answer['accountName']
// Verifica se o nomedaconta.json existe:
if (!checkAccount(accountName)) {
// retorna novamente para a função, para digitar o nome novamente.
return delconta()
}
fs.unlink(`accounts/${accountName}.json`, (err) => {
if (err) {
console.error(err);
return;
} else if (!fs.existsSync(`accounts/${accountName}.json`)) {
console.clear();
console.log(chalk.bgRed.black('Conta removida com sucesso!'));
// Agora volta do início:
operationsonaccounts()
}
});
})
}
}
function getAccount(accountName) {
// Lê o arquivo:
const accountJSON = fs.readFileSync(`accounts/${accountName}.json`, {
encoding: 'utf8', // já lê usando utf8
flag: 'r', // Somente 'ler (read)' o arquivo
})
return JSON.parse(accountJSON) // retorna o arquivo em json
}
// add an amount to user account
function Depositar() {
inquirer
.prompt([
{
name: 'accountName',
message: 'Qual o nome da sua conta?',
},
])
.then((answer) => {
const accountName = answer['accountName']
// Se 'checkAccount' retornar false, execute o IF:
if (!checkAccount(accountName)) {
// retorna novamente para a função, para digitar o nome novamente.
return Depositar()
}
inquirer
.prompt([
{
name: 'amount',
message: 'Quanto você deseja depositar?',
},
])
.then((answer) => {
const amount = answer['amount']
if (!verificarvalor(amount)) {
Depositar();
return // precisa do return ja que é um erro no sistema, sem ele quebra tudo!!
}
// Chama a função que faz o depósito:
addAmount(accountName, amount)
// Volta para o inicio:
operationsonaccounts()
})
})
}
function addAmount(accountName, amount) {
const accountData = getAccount(accountName) // accountData recebe o o json pela função 'getAccount'
console.log('Object.balance', accountData.balance)
if (!amount) {
console.log(
chalk.bgRed.black('Ocorreu um erro, tente novamente mais tarde!'),
)
return Depositar()
}
// .balance é a chave 'balance' que está no json 'accountData', nesse caso, retorna o valor
// da chave 'balance', que é o valor que tem na conta!!
accountData.balance = parseFloat(amount) + parseFloat(accountData.balance) // Soma o valor a ser depositado com o valor atual da conta!
fs.writeFileSync(
`accounts/${accountName}.json`,
JSON.stringify(accountData), // transforma o json em texto, informando o json = accountData
function (err) {
console.log(err)
},
)
console.log(
chalk.green(`Foi depositado o valor de R$${amount} na sua conta!`),
)
}
function checkAccount(accountName) {
if (!fs.existsSync(`accounts/${accountName}.json`)) {
console.log(chalk.bgRed.black('Esta conta não existe, escolha outro nome!'))
return false
}
return true
}
function getAccountBalance() {
inquirer
.prompt([
{
name: 'accountName',
message: 'Qual o nome da sua conta?',
},
])
.then((answer) => {
const accountName = answer['accountName']
if (!checkAccount(accountName)) {
return getAccountBalance()
}
const accountData = getAccount(accountName)
console.log(
chalk.bgBlue.black(
`Olá, o saldo da sua conta é de R$${accountData.balance}`,
),
)
operationsonaccounts()
})
}
function verificarvalor(isdigit) {
//console.log(isdigit)
if (!isNaN(isdigit)) { // Verifica se o valor é um número
return true;
} else {
console.log("Valor indefinido, favor digitar um número para o depósito!");
return false;
}
}
// get money from account
function pegarmoney() {
inquirer
.prompt([
{
name: 'accountName',
message: 'Qual o nome da sua conta?',
},
])
.then((answer) => {
const accountName = answer['accountName']
if (!checkAccount(accountName)) {
return pegarmoney()
}
inquirer
.prompt([
{
name: 'amount',
message: 'Quanto você deseja sacar?',
},
])
.then((answer) => {
const amount = answer['amount']
removeAmount(accountName, amount)
operationsonaccounts()
})
})
}
function removeAmount(accountName, amount) {
const accountData = getAccount(accountName) // accountData recebe o json pela função 'getAccount'
if (!amount) {
console.log(
chalk.bgRed.black('Ocorreu um erro, tente novamente mais tarde!'),
)
return pegarmoney()
}
if (accountData.balance < amount) {
console.log(chalk.bgRed.black('Valor indisponível!'))
return pegarmoney()
}
// .balance é a chave 'balance' que está no json 'accountData', nesse caso, retorna o valor
// da chave 'balance', que é o valor que tem na conta!!
accountData.balance = parseFloat(accountData.balance) - parseFloat(amount)
fs.writeFileSync(
`accounts/${accountName}.json`,
JSON.stringify(accountData),
function (err) {
console.log(err)
},
)
console.log(
chalk.green(`Foi realizado um saque de R$${amount} da sua conta!\nAgora você possui apenas RS${accountData.balance} na conta.`),
)
}
operationsonaccounts()