Artigo original: What exactly is Node.js?

O Node.js é um ambiente de tempo de execução do JavaScript. Certo, mas o que isso quer dizer? Como é que ele funciona?

O ambiente de tempo de execução chamado Node.js inclui tudo de que você precisa para executar um programa escrito em JavaScript.

1_sYPllpcAZLHmpuQSRPuO0Q
Se você conhece Java, esta é uma analogia que você pode usar

O Node.js passou a existir quando os desenvolvedores originais do JavaScript decidiram transformá-lo de algo que somente podia ser executado no navegador em algo que podia ser executado em sua máquina e como uma aplicação autônoma.

Agora, é possível fazer muito mais com o JavaScript do que tornar sites da web interativos.

O JavaScript, agora, consegue fazer coisas que outras linguagens de programação como o Python podem fazer.

Tanto o JavaScript do seu navegador quanto o Node.js são executados na engine de tempo de execução V8 do JavaScript. Essa engine recebe o código em JavaScript e o converte em código de máquina mais rápido. O código de máquina é um código de baixo nível que o computador pode executar sem a necessidade de interpretá-lo primeiramente.

Por que usar o Node.js?

Aqui temos uma definição formal dada no site oficial do Node.js:

O Node.js® é um tempo de execução do JavaScript criado com base na engine de JavaScript V8 do Chrome.

O Node.js usa um modelo de entrada e saída orientado por eventos e não bloqueador que o torna leve e eficiente.

O ecossistema de pacotes do Node.js, o npm, é o maior ecossistema de bibliotecas de código aberto do mundo.

Já discutimos a primeira linha dessa definição: "O Node.js® é um tempo de execução do JavaScript criado com base na engine de JavaScript V8 do Chrome." Agora, vamos entender as outras duas linhas para podermos descobrir a razão pela qual o Node.js é tão popular.

Entrada e saída têm a ver com o que chamamos em inglês de input/output (cuja sigla é I/O). Pode ser qualquer coisa – de ler ou gravar arquivos localmente a fazer uma solicitação de HTTP para uma API.

O processo de E/S (entrada e saída) leva tempo e, por isso, bloqueia outras funções.

Considere um cenário onde solicitamos a um banco de dados do back-end que nos retorne os detalhes sobre o usuário1 e o usuário2 (na imagem abaixo, user1 e user2) e que, em seguida, os imprima na tela/console. A resposta para essa solicitação leva tempo, mas as duas solicitações de dados dos usuários podem ser realizadas independentemente e ao mesmo tempo.

1_B_UCsFOPfRDKO8ovHpxphg
E/S com bloqueio (à esquerda) x E/S sem bloqueio (à direita)

E/S com bloqueio

No método com bloqueio, a solicitação de dados do usuário2 não é iniciada até que os dados do usuário1 sejam impressos na tela.

Se estamos falando de um servidor da web, teríamos de iniciar uma nova thread (algo como uma "sequência", em português) para cada novo usuário. O JavaScript, porém, usa uma thread única (isso não é bem verdade, mas ele tem um loop de eventos que são de thread única – falaremos sobre isso mais tarde). Assim, isso faria com que o JavaScript não fosse a melhor opção para tarefas que exigem várias threads.

É aí que entra a parte do "sem bloqueio".

E/S sem bloqueio

Por outro lado, usando uma solicitação sem bloqueio, é possível iniciar uma solicitação de dados do usuário2 sem esperar pela resposta dada sobre o usuário1. Você pode iniciar as duas solicitações em paralelo.

Essa E/S sem bloqueio elimina a necessidade de várias threads, já que o servidor pode lidar com diversas solicitações ao mesmo tempo.

O loop de eventos do JavaScript

Se você tiver 26 minutos à disposição, assista essa explicação em vídeo excelente sobre o loop de eventos do Node (em inglês):

Caso contrário, aqui, temos uma explicação passo a passo de como funciona o loop de eventos em JavaScript.

1_BBlPbUjGVtfSPd7BHa1LHw
Créditos da imagem: curso de Andrew Mead na Udemy sobre o Node
  1. Colocar main() na stack de chamadas.
  2. Colocar console.log() na stack de chamadas. Ele é executado imediatamente e retirado da stack.
  3. Colocar setTimeout(2000) na stack. setTimeout(2000) é uma API do Node. Quando a chamamos, registramos o par evento-função de callback. O evento aguardará 2.000 milissegundos, depois chamará a função de callback.
  4. Depois de ser registrada nas APIs, setTimeout(2000) é retirada da stack de chamadas.
  5. O segundo setTimeout(0) é registrado do mesmo modo. Agora, temos duas APIs do Node esperando para serem executadas.
  6. Após aguardar 0 segundos, setTimeout(0) é movida para a fila de callback. O mesmo ocorre com setTimeout(2000).
  7. Na fila de callback, as funções aguardam que a stack de chamadas esteja vazia, pois apenas uma instrução pode ser executada por vez. Quem cuida disso é o loop de eventos.
  8. O último console.log() é executado e main() é retirado da stack de chamadas.
  9. O loop de eventos vê que a stack de chamadas está vazia e que a fila de callbacks não está. Ele, então, move as funções de callback (na ordem em que a primeira a entrar é a primeira a sair – FIFO) para a stack de chamadas para execução.

npm

0_A47ZVKudfCOCBbyx

Essas são as bibliotecas criadas pela fantástica comunidade e que resolverão a maior parte dos problemas genéricos. O npm (do inglês, Node package manager) tem pacotes que você pode usar com suas aplicações para tornar o desenvolvimento mais rápido e mais eficiente.

Require

Require faz três coisas:

  • Carrega os módulos que vêm com o Node.js, como o sistema de arquivos e o HTTP a partir da API do Node.js.
  • Carrega as bibliotecas de terceiros, como o Express e o Mongoose, que você instalará a partir do npm.
  • Permite que você solicite seus próprios arquivos e modularize seu projeto.

Require é uma função que aceita o parâmetro "path" (caminho) e retorna module.exports.

Módulos do Node

Um módulo do Node é um bloco de código reutilizável cuja existência não afeta outros códigos acidentalmente.

Você pode escrever seus próprios módulos e usá-los em diversas aplicações. O Node.js tem um conjunto de módulos já incorporados que você pode usar sem precisar instalá-los.

A V8 turbina o JavaScript fazendo uso do C++

A V8 é uma engine de tempo de execução de código aberto escrita em C++.

JavaScript -> V8(C++) -> código de máquina

A V8 implementa uma linguagem de script chamada ECMAScript, conforme especificado na ECMA-262. O ECMAScript foi criado pela Ecma International para padronizar o JavaScript.

A V8 pode ser executada de modo autônomo ou ser incorporada a qualquer aplicação em C++. Ela tem hooks que permitem que você escreva seu próprio código em C++ e que você pode disponibiizar para o JavaScript.

Essencialmente, isso permite que você adicione recursos ao JavaScript incorporando a V8 em seu código em C++ para que o código em C++ entenda mais do que aquilo que, de outro modo, é especificado pelo padrão do ECMAScript.

Comentário: Greg Bulmash chamou minha atenção para o fato de que existem muitas engines de tempo de execução do JavaScript além da V8, usada no Chrome. Também existem a SpiderMonkey, da Mozilla, a Chakra, da Microsoft, entre outras. Detalhes sobre isso podem ser encontrados nesta página.

Eventos

Eventos são situações que ocorrem em nossas aplicações e as quais podemos responder. Existem dois tipos de eventos no Node.

  • Eventos de sistema: a base do C++ a partir de uma biblioteca chamada libuv (por exemplo, terminar de ler um arquivo).
  • Eventos personalizados: a base do JavaScript.

Como escrever o 'Hello World' no Node.js

Precisamos fazer isso, certo?

Crie um arquivo app.js e adicione a ele o seguinte:

console.log("Hello World!");

Abra seu terminal do Node, altere o diretório para a pasta onde o arquivo está salvo e execute o comando node app.js.

Aí está! Você acaba de escrever o 'Hello World' no Node.js.

Você pode seguir o autor, Priyesh Patel, no Twitter.

Existem diversos recursos que você pode usar para aprender mais sobre o Node.js, incluindo, é claro, o freeCodeCamp.org.