├── Capitulo_1.md
├── Capitulo_10.md
├── Capitulo_2.md
├── Capitulo_3.md
├── Capitulo_4.md
├── Capitulo_5.md
├── Capitulo_6.md
├── Capitulo_7.md
├── Capitulo_8.md
├── Capitulo_9.md
├── README.md
├── Sumário.md
└── images
├── Capitulo-5
├── browser-information.png
├── callstack-2.png
├── callstack.png
├── iterations-2.png
└── iterations.png
├── Capitulo-7
├── axios.png
└── browser-support.png
├── callback.PNG
├── cowsay1.PNG
├── cowsay2.PNG
├── cowsay3.PNG
├── globals.PNG
├── object.PNG
└── outdated.PNG
/Capitulo_1.md:
--------------------------------------------------------------------------------
1 |
INTRODUÇÃO
2 |
3 | ## Introdução ao Node
4 |
5 | ### Este post é um guia de introdução ao Node.js, o ambiente de execução do JavaScript no lado do servidor. O Node.js é construído sobre a engine Google Chrome V8, e é usado principalmente para criar Web Servers - mas não é limitado a isso
6 |
7 | - Visão geral
8 | - Os melhores recursos do Node
9 | - Rápido
10 | - Simples
11 | - JavaScript
12 | - V8
13 | - Plataforma assíncrona
14 | - Um enorme número de bibliotecas
15 | - Um exemplo de aplicação Node
16 | - Frameworks e ferramentas do Node
17 |
18 | ## Visão geral
19 |
20 | O Node.js é um ambiente de tempo de execução* para JavaScript que é executado no servidor.
21 |
22 | * Runtime, ou em tempo de execução, significa que o programa é gerenciado enquanto é executado.
23 |
24 | O Node.js é de open source, multiplataforma e, desde sua introdução em 2009, ficou muito popular, desempenhando um papel significativo no desenvolvimento web. Se as estrelas do GitHub são um
25 | fator de indicação de popularidade, ter mais de 46000 delas significa ser muito popular.
26 |
27 | ## Os melhores recursos do Node.js
28 |
29 | ### Fast
30 |
31 | Um dos principais pontos de venda do Node.js é a velocidade. Devido ao seus paradigma não-bloqueador, o código JavaScript em execução no Node.js (dependendo do benchmark) pode ser duas vezes mais rápido que as linguagens compiladas, como C ou Java, e ainda mais rápido se comparado a linguagens interpretadas, como Python ou Ruby.
32 |
33 | ### Simples
34 |
35 | O Node.js é simples. Extremamente simples, na verdade.
36 |
37 | ### JavaScript
38 |
39 | O Node executa código JavaScript. Isso significa que milhões de desenvolvedores front-end que já usam JavaScript no navegador podem ser capazes de executar o código do servidor e o código do frontend usando a mesma linguagem de programação, sem a necessidade de aprender uma ferramenta completamente diferente.
40 |
41 | Os paradigmas são todos iguais, e no Node.js os novos padrões ECMAScript podem ser usados primeiro, já que você não precisa esperar que todos os usuários atualizem seus navegadores - você decide qual versão do ECMAScript deseja usar, alterando a versão do Node.js.
42 |
43 | ### V8
44 |
45 | Em execução na Google V8 JavaScript engine, de código aberto, o Node.js pode alavancar o trabalho de milhares de engenheiros que fazem (e continuarão a fazer) o Tempo de execução do Chrome JavaScript em alta velocidade.
46 |
47 | ### Plataforma assíncrona
48 |
49 | Nas linguagens de programação tradicionais (C, Java, Python, PHP), todas as instruções são bloqueadas por
50 | padrão, a menos que você "aceite" explicitamente a execução de operações assíncronas. Se você executar uma
51 | solicitação de rede para ler algum JSON, a execução desse encadeamento específico é bloqueada até que o
52 | resposta está pronta.
53 |
54 | O JavaScript permite criar código assíncrono e sem bloqueio de uma maneira muito simples,
55 | usando um único encadeamento (single thread), callbacks e programação orientada a eventos. Toda vez
56 | que uma operação cara (expensive operation) ocorrer, passamos uma função de callback, que será chamada assim que pudermos
57 | continuar com o processamento. Não estamos mais esperando que isso termine antes de continuar com o resto
58 | do programa.
59 |
60 | Esse mecanismo deriva do navegador. Mal podemos esperar até que algo carregue de um AJAX
61 | antes de poder interceptar eventos de clique na página. Para foornecer uma boa experiência ao usuário, tudo deve acontecer na hora.
62 |
63 | > Se você já criou um manipulador `onclick` para uma página da web, você já usou técnicas de programação assíncrona com event listeners (algo como ouvintes de eventos).
64 |
65 | Isso permite que o Node.js manipule milhares de conexões simultâneas com um único servidor,
66 | sem introduzir o ônus de gerenciar a simultaneidade de threads, o que seria uma grande
67 | fonte de erros.
68 | O Node fornece E/S primitivas sem bloqueio e, geralmente, as bibliotecas no Node.js são gravadas usando
69 | paradigmas não-bloqueadores, tornando o comportamento de bloqueio uma exceção.
70 |
71 | Quando o Node.js precisa executar uma operação de E/S, como a leitura da rede, acessar um
72 | banco de dados ou um sistema de arquivos, em vez de bloquear o encadeamento, ele simplesmente retomará a
73 | operação quando a resposta voltar, evitando desperdiçar ciclos de CPU em espera.
74 |
75 | ### Um enorme número de bibliotecas
76 |
77 | O `npm`, com sua estrutura simples, ajudou o ecossistema do Node.js a proliferar. Atualmente o npm hospeda quase 500.000 pacotes open source, os quais você pode usar livremente.
78 |
79 | ## Um exemplo de aplicação Node
80 |
81 | O exemplo mais comum do Hello World em Node.js é um web server:
82 |
83 | ```
84 |
85 | const http = require('http')
86 |
87 | const hostname = '127.0.0.1'
88 | const port = 3000
89 |
90 | const server = http.createServer((req, res) => {
91 | res.statusCode = 200
92 | res.setHeader('Content-Type', 'text/plain')
93 | res.end('Hello World\n')
94 | })
95 |
96 | server.listen(port, hostname, () => {
97 | console.log(`Server running at http://${hostname}:${port}/`)
98 | })
99 |
100 | ```
101 |
102 | Para executar esse snippet, salve-o como um arquivo `server.js` e execute `node server.js` no seu terminal.
103 | Esse código primeiro inclui o módulo `http`.
104 |
105 | O Node.js possui uma biblioteca padrão incrível, incluindo um suporte de primeira classe para redes.
106 |
107 | O método `createServer()` do `http` cria um novo servidor HTTP e o retorna.
108 | O servidor está configurado para escutar na porta e no nome do host especificados. Quando o servidor estiver pronto, a callback é chamada, neste caso, informando que o servidor está em execução.
109 | Sempre que uma nova solicitação é recebida, o evento `request` é chamado, fornecendo dois objetos:
110 | `request` (um objeto http.IncomingMessage) e `send` (um objeto http.ServerResponse).
111 | Esses 2 objetos são essenciais para lidar com a chamada HTTP.
112 | O primeiro fornece os detalhes da solicitação. Neste exemplo simples, isso não é usado, mas você pode
113 | acessar os cabeçalhos da solicitação e solicitar dados.
114 |
115 | O segundo é usado para retornar dados a quem o invocar.
116 | Neste caso com
117 |
118 | ```
119 | res.statusCode = 200
120 | ```
121 |
122 | definimos a propriedade `statusCode` como 200, para indicar uma resposta bem-sucedida.
123 | Definimos o cabeçalho Content-Type:
124 |
125 | ```
126 | res.setHeader('Content-Type', 'text/plain')
127 | ```
128 |
129 | e encerramos a resposta, adicionando o conteúdo como argumento ao `end()`:
130 |
131 | ```
132 | res.end('Hello World\n')
133 | ```
134 |
135 | ## Frameworks e ferramentas do Node
136 |
137 | O Node.js é uma plataforma de baixo nível, e para tornar as coisas mais fáceis e interessantes para os desenvolvedores
138 | milhares de bibliotecas foram criadas no Node.js.
139 | Muitos das quais foram estabelecidas ao longo do tempo como opções populares. Aqui está uma lista para
140 | as que considero muito relevantes e que valem a pena aprender:
141 |
142 | - `Express`, uma das maneiras mais simples e poderosas de criar um web server. Possui uma abordagem, sem opinião, focada nos principais recursos de um servidor, é a chave para seu sucesso.
143 |
144 | - `Meteor`, uma estrutura full-stack incrivelmente poderosa, fornecendo uma isomórfica
145 | abordagem para criar aplicativos com JavaScript, compartilhando código no cliente e no servidor.
146 | Antes era uma ferramenta pronta para uso que fornecia tudo, agora ela se integra às bibliotecas de front-end
147 | React, Vue e Angular. Também pode ser usada para criar aplicativos móveis.
148 |
149 | - `koa`, criado pela mesma equipe por trás do Express, pretende ser ainda mais simples e menor,
150 | construindo sobre anos de conhecimento. O novo projeto nasceu da necessidade de criar
151 | alterações incompatíveis sem interromper a comunidade existente.
152 |
153 | - `Next.js`, um framework para renderizar aplicativos React renderizados no servidor.
154 |
155 | - `Micro`, um servidor muito leve para criar microsserviços HTTP assíncronos.
156 |
157 | - `Socket.io`, um mecanismo de comunicação em tempo real para criar aplicativos de rede.
158 |
159 | ## Uma breve história do Node
160 |
161 | ### Uma retrospectiva da história do Node.js de 2009 até hoje
162 |
163 | Acredite ou não, o Node.js tem apenas 11 anos.
164 | Em comparação, o JavaScript tem 23 anos e a Web como a conhecemos (após a introdução do
165 | Mosaic) tem 25 anos.
166 | 9 anos é uma quantidade de tempo muito pequena para uma tecnologia, mas o Node.js parece ter existido desde sempre.
167 | Tive o prazer de trabalhar com o Node desde os primeiros dias, quando ele tinha apenas 2 anos e,
168 | apesar da pouca informação disponível, você já podia sentir que era uma coisa enorme.
169 |
170 | Neste post, quero desenhar o panorama geral do Node em sua história, para colocar as coisas em perspectiva.
171 |
172 | - Um pouco de história
173 | - 2009
174 | - 2010
175 | - 2011
176 | - 2012
177 | - 2013
178 | - 2014
179 | - 2015
180 | - 2016
181 | - 2017
182 | - 2018
183 |
184 | ### Um pouco de história
185 |
186 | JavaScript é uma linguagem de programação criada na Netscape como uma ferramenta de script para
187 | manipular páginas da Web dentro de seu navegador, o Netscape Navigator.
188 |
189 | Parte do modelo de negócios da Netscape era vender servidores da Web, que incluíam um
190 | ambiente chamado Netscape LiveWire, onde se pode criar páginas dinâmicas usando
191 | JavaScript no lado do servidor. Portanto, a ideia do JavaScript no lado do servidor não foi introduzida pelo Node.js, mas é antiga
192 | assim como o JavaScript - apesar de não ter sido bem-sucedida na época.
193 |
194 | Um fator chave que levou ao sucesso do Node.js foi o tempo. JavaScript desde alguns anos foi
195 | começando a ser considerado uma linguagem séria, graças aos aplicativos "Web 2.0" que
196 | mostraram ao mundo como seria uma experiência moderna na web (pense no Google Maps ou
197 | Gmail).
198 |
199 | A barra de desempenho dos mecanismos JavaScript aumentou consideravelmente graças a competição dos browser, que continua forte. As equipes de desenvolvimento por trás de cada navegador principal
200 | trabalham duro todos os dias para nos dar um melhor desempenho, o que é uma grande vitória para o JavaScript como uma
201 | plataforma. O V8, mecanismo que o Node.js usa sob o capô, é um deles e, em particular, é
202 | o mecanismo JS do Chrome.
203 |
204 | Mas é claro que o Node.js não é popular apenas por pura sorte ou timing. Ele introduziu um pensamento inovador sobre como programar em JavaScript no lado do servidor.
205 |
206 | ### 2009
207 |
208 | Nasce o Node.js. A primeira forma de `npm` é criada.
209 |
210 | ### 2010
211 |
212 | `Express` nasce. `Socket.io` nasce.
213 |
214 | ### 2011
215 |
216 | npm alcança o 1.0. Grandes companhias começam a adotar o Node: LinkedIn, Uber. Hapi nasce.
217 |
218 | ### 2012
219 |
220 | A adoção continua muito rapidamente.
221 |
222 | ### 2013
223 |
224 | Primeira grande plataforma de blogs usando o Node: Ghost Koa nasce.
225 |
226 | ### 2014
227 |
228 | Grande drama: `IO.js é` o principal fork do Node.js, com o objetivo de introduzir o suporte ao ES6 e avançar mais rapidamente
229 |
230 | ### 2015
231 |
232 | Nasce a Node.js Foundation. O `IO.js` é mesclado novamente no Node.js.
233 |
234 | ### 2016
235 |
236 | O `Yarn` é criado. Node 6.
237 |
238 | ### 2017
239 |
240 | npm se concentra mais na segurança. Node 8. HTTP/2 V8 apresenta o Node em seu conjunto de testes,
241 | tornando o Node oficialmente um alvo para o mecanismo JS, além de 3 bilhões de downloads de npms no Chrome a cada
242 | semana
243 |
244 | ### 2018
245 |
246 | Node 10 ESModules
247 |
248 | ## Como instalar o Node
249 |
250 | ### Como você pode instalar o Node.js no seu sistema: um gerenciador de pacotes, o instalador oficial do site ou nvm
251 |
252 | O Node.js pode ser instalado de diferentes maneiras. Este post destaca as mais comuns e
253 | convenientes.
254 |
255 | Pacotes oficiais para todas as principais plataformas estão disponíveis em https://nodejs.org/en/download/.
256 |
257 | Uma maneira muito conveniente de instalar o Node.js é através de um gerenciador de pacotes. Nesse caso, cada sistema operacional tem o seu próprio.
258 | No macOS, é o Homebrew, e - uma vez instalado - permite instalar o Node.js
259 | com muita facilidade, executando este comando na CLI:
260 | ```
261 | brew install node
262 | ```
263 |
264 | Outros gerenciadores de pacotes para Linux e Windows estão listados em https://nodejs.org/en/download/package-manager/.
265 |
266 | O `nvm` é uma maneira popular de executar o Node. Permite alternar facilmente a versão do Node e instalar
267 | novas versões para tentar resolver o problema se algo quebrar, por exemplo.
268 | Também é muito útil testar seu código com versões antigas do Node.
269 |
270 | Consulte https://github.com/creationix/nvm para obter mais informações sobre esta opção.
271 |
272 | Minha sugestão é usar o instalador oficial se você está apenas começando e não usa
273 | linha de comando caso contrário, o Homebrew é a minha solução favorita.
274 | De qualquer forma, quando o Node estiver instalado, você terá acesso ao programa executável `node` na linha de comando.
275 |
276 | ## Quanto JavaScript você deve saber para usar o Node?
277 |
278 | ### Se você está apenas começando com JavaScript, o quão fundo você precisa conhecer a linguagem?
279 |
280 | Como iniciante, é difícil chegar a um ponto em que você tem confiança suficiente nas suas habilidades de programação.
281 | Ao aprender a codar, você também pode ficar confuso sobre onde termina o JavaScript e onde
282 | o Node.js começa, ou vice-versa.
283 |
284 | Eu recomendo que você tenha uma boa noção dos principais conceitos de JavaScript antes de mergulhar
285 | no Node.js:
286 |
287 | - Estrutura léxica
288 | - Expressões
289 | - Tipos
290 | - Variáveis
291 | - Funções
292 | - this
293 | - Arrow Functions
294 | - Loops
295 | - Loops e escopo
296 | - Arrays
297 | - Template Literals
298 | - Semicolons
299 | - Strict Mode
300 | - ECMAScript 6, 2016, 2017
301 |
302 |
303 | Com esses conceitos em mente, você está no caminho certo para se tornar um ótimo desenvolvedor JavaScript, tanto no navegador quanto no Node.js.
304 |
305 | Os seguintes conceitos também são fundamentais para entender a programação assíncrona, que é uma parte fundamental do Node.js:
306 |
307 | - Programação assíncrona e callbacks
308 | - Temporizadores
309 | - Promises
310 | - Async e Await
311 | - Closures
312 | - Event Loop
313 |
314 | Felizmente, escrevi um e-book gratuito que explica todos esses tópicos, o Manual do JavaScript. É o recurso mais compacto que você encontrará para aprender tudo isso.
315 |
316 | Você pode encontrar o ebook na parte inferior desta página: https://flaviocopes.com/javascript/.
317 |
318 | Eu também fiz a tradução desse livro, o resultado pode ser conferido aqui https://github.com/ChristySchott/Manual-Iniciante-JavaScript.
319 |
320 | ## Diferenças entre o Node e o navegador
321 |
322 | ### Como a escrita de uma aplicação JavaScript no Node.js difere da Programação Web dentro do navegador
323 |
324 | O navegador e o Node usam JavaScript como sua linguagem de programação, porém, criar aplicativos executados no navegador é algo completamente diferente de criar uma aplicação em Node.js.
325 |
326 | Apesar de ambos os casos utilizarem JavaScript, existem algumas diferenças importantes que tornam essa experiência radicalmente diferente.
327 |
328 | Como um desenvolvedor front-end que cria aplicativos para o Node, há uma enorme vantagem - a linguagem ainda é
329 | o mesmo.
330 |
331 | Você tem uma grande oportunidade, já sabemos como é difícil aprender uma
332 | linguagem de programação, ao usar a mesma linguagem para executar todo o seu trabalho na web -
333 | tanto no cliente quanto no servidor, você está em posição de vantagem.
334 |
335 | O que muda é o ecossistema.
336 |
337 | No navegador, na maioria das vezes, o que você está fazendo é interagir com a DOM ou com outra API Web, como os `cookies`. Essas APIs não existem no Node, é claro. Você não tem o `document`, `window` e todos os outros objetos fornecidos pelo navegador.
338 |
339 | E no navegador, não temos todas as excelentes APIs que o Node.js fornece por meio de seus módulos,
340 | como a funcionalidade de acesso ao sistema de arquivos.
341 |
342 | Outra grande diferença é que no Node.js você controla o ambiente. A menos que você esteja construindo
343 | um aplicativo open souce onde qualquer pessoa, de qualquer lugar, pode densenvolver, você sabe qual versão do
344 | Node em que você executará o aplicativo. Comparado com o ambiente do navegador, onde você não
345 | possui o luxo de escolher qual navegador seus visitantes usarão, isso é muito conveniente.
346 |
347 | Isso significa que você pode escrever todo o JavaScript ES6-7-8-9 moderno que sua versão do Node
348 | apoia.
349 |
350 | Como o JavaScript se move muito rápido, os navegadores podem ser um pouco lentos e os usuários podem levar tempo para fazer a atualização, então você se vê preso em usar versões mais antigas de JavaScript / ECMAScript.
351 |
352 | Você pode usar o Babel para transformar seu código em compatível com ES5 antes de enviá-lo para o
353 | navegador, mas no Node, você não precisará disso.
354 |
355 | Outra diferença é que o Node usa o sistema de módulos CommonJS, enquanto no navegador
356 | estão começando a utilizar o padrão ES Modules.
357 |
358 | Na prática, isso significa que, por enquanto, você usa `require()` no Node e `import` no
359 | navegador.
360 |
361 | **O livro é de 2018, hoje EM a prática mais comum é utilizar o padrão ES Modules. Apessar disso, algumas empresas ainda utilizam o CommonJS**
362 |
363 |
364 |
--------------------------------------------------------------------------------
/Capitulo_10.md:
--------------------------------------------------------------------------------
1 | DIVERSOS
2 |
3 | - [Streams](#streams)
4 | - [Trabalhando com MySQL](#working-mysql)
5 | - [Diferença entre desenvolvimento e produção](#difference-development-production)
6 |
7 | ## Streams
8 |
9 | **Saiba para que servem streams, por que eles são tão importantes e como usá-los.**
10 |
11 | - [O que são streams](#what-are-streams)
12 | - [Porque streams](#why-streams)
13 | - [Um exemplo de um stream](#example-of-stream)
14 | - [pipe()](#pipe)
15 | - [Streams mantidos por APIs do Node](#powered-node-apis)
16 | - [Diferente tipos de streams](#different-types)
17 | - [Como criar um stream Readable](#readable-stream)
18 | - [Como criar um stream Writable](#writable-stream)
19 | - [Como obter dados de um stream Readable](#get-data-from-readable-stream)
20 | - [Como enviar dados para um stream Writable](#send-data-to-writable-stream)
21 | - [Apontar para um stream Writable que você escreveu](#signaling-writable-stream)
22 | - [Conclusão](#streams-conclusion)
23 |
24 | ### O que são streams
25 |
26 | Streams são um dos conceitos fundamentais que impulsionam as aplicações Node.js.
27 |
28 | Eles são uma maneira eficiente de lidar com arquivos de leitura/gravação, comunicações de rede ou todo tipo de troca de informações ponta a ponta.
29 |
30 | Streams não são um conceito exclusivo do Node.js. Eles foram introduzidos há décadas no sistema operacional Unix, lá os programas podem interagir entre si, passando streams através do operador pipe (`|`).
31 |
32 | Por exemplo, na maneira tradicional, quando você diz para o programa ler um arquivo, o arquivo é lido do começo ao fim na memória, para depois ser processado.
33 |
34 | Usando streams você o lê peça por peça, processando seu conteúdo sem manter tudo na memória.
35 |
36 | O [módulo de `stream`](https://nodejs.org/api/stream.html) do Node.js fornece a base sobre a qual todas as APIs de streaming são construídas.
37 |
38 | ### Porque streams
39 |
40 | Streams fornecem basicamente duas vantagens principais em relação à outros métodos de manipulação de dados:
41 |
42 | - **Eficiência de memória**: você não precisa carregar grandes quantidades de dados na memória antes de
43 | poder processá-los
44 |
45 | - **Eficiência de tempo**: leva muito menos tempo para começar a processar dados assim que você os tiver, em vez de esperar até que toda a carga útil de dados esteja disponível
46 |
47 | ### Um exemplo de stream
48 |
49 | Um exemplo típico é o de ler arquivos de um disco.
50 |
51 | Usando o módulo do Node `fs` você pode ler um arquivo e enviá-lo por HTTP quando uma nova conexão for estabelecida no servidor http:
52 |
53 | ```
54 | const http = require('http')
55 | const fs = require('fs')
56 |
57 | const server = http.createServer(function (req, res) {
58 | fs.readFile(__dirname + '/data.txt', (err, data) => {
59 | res.end(data)
60 | })
61 | })
62 | server.listen(3000)
63 | ```
64 |
65 | `readFile()` lê todo o conteúdo do arquivo e chama a função callback quando estiver pronto.
66 |
67 | `res.end(data)` a função callback retornará o conteúdo do arquivo para o cliente HTTP.
68 |
69 | Se o arquivo for grande, a operação levará bastante tempo. Aqui está a mesma coisa escrita usando streams:
70 |
71 | ```
72 | const http = require('http')
73 | const fs = require('fs')
74 |
75 | const server = http.createServer((req, res) => {
76 | const stream = fs.createReadStream(__dirname + '/data.txt')
77 | stream.pipe(res)
78 | })
79 | server.listen(3000)
80 | ```
81 |
82 | Em vez de esperar até que o arquivo seja totalmente lido, começamos a transmiti-lo para o cliente HTTP assim que tivermos uma porção de dados pronta para ser enviada.
83 |
84 | ### pipe()
85 |
86 | O exemplo acima usa a linha `stream.pipe(res)`: o método `pipe()` é chamado no fluxo de arquivos.
87 |
88 | O que faz este código? Ele pega o código fonte e o envia para um destino.
89 |
90 | Você o chama no código do stream. Nesse caso, o stream de arquivos é enviado para a resposta HTTP.
91 |
92 | O valor de retorno do método `pipe()` é o stream de destino, que é uma coisa muito conveniente e nos permite encadear várias chamadas `pipe()`, assim:
93 |
94 | `src.pipe(dest1).pipe(dest2)`
95 |
96 | Essa construção é o mesmo que fazer:
97 |
98 | ```
99 | src.pipe(dest1)
100 | dest1.pipe(dest2)
101 | ```
102 |
103 | ### Streams mantidos por APIs do Node
104 |
105 | Devido às suas vantagens, muitos módulos principais do Node.js fornecem recursos nativos de manipulação de stream, os mais notáveis são:
106 |
107 | - `process.stdin` retorna um stream conectado ao stdin
108 | - `process.stdout` retorna um stream conectado ao stdout
109 | - `process.stderr` retorna um stream conectado ao stderr
110 | - `fs.createReadStream()` cria um stream Readable para um arquivo
111 | - `fs.createWriteStream ()` cria um stream Writable em um arquivo
112 | - `net.connect ()` inicia uma conexão baseada em stream
113 | - `http.request ()` retorna uma instância do http.ClasseClientRequest, que é um stream Writable
114 | - `zlib.createGzip ()` compacta dados usando gzip (um algoritmo de compressão) em um stream
115 | - `zlib.createGunzip ()` descomprime um stream gzip.
116 | - `zlib.createDeflate ()` compacta dados usando deflate (um algoritmo de compressão) em um stream
117 | - `zlib.createInflate ()` descomprime um stream de deflate
118 |
119 | ### Diferente tipos de streams
120 |
121 | Existem quatro classes de streams:
122 |
123 | - Readable: um stream no qual você pode receber, mas não enviar dados. Quando você envia dados para um stream Readable, ele é armazenado em buffer, até que o consumidor comece a ler os dados.
124 | - Writable: um stream no qual você pode enviar, mas não receber dados.
125 | - Duplex: um stream no qual você pode enviar e receber, basicamente uma combinação de um stream Readable e Writable.
126 | - Transform: um stream semelhante ao Duplex, mas a saída é uma transformação de sua entrada.
127 |
128 | ### Como criar um stream Readable
129 |
130 | Nós obtemos um stream Readable a partir do módulo [`stream`](https://nodejs.org/api/stream.html) e nós o inicializamos:
131 |
132 | ```
133 | const Stream = require('stream')
134 | const readableStream = new Stream.Readable()
135 | ```
136 |
137 | Agora que o stream foi inicializado, podemos enviar dados para ele:
138 |
139 | ```
140 | readableStream.push('hi!')
141 | readableStream.push('ho!')
142 | ```
143 |
144 | ### Como criar um stream Writable
145 |
146 | Para criar um stream Writable, criamos o objeto base `Writable` e implementamos o método `its_write()`.
147 |
148 | Primeiro, crie um objeto stream:
149 |
150 | ```
151 | const Stream = require('stream')
152 | const writableStream = new Stream.Writable()
153 | ```
154 |
155 | depois implemente `_write`:
156 |
157 | ```
158 | writableStream._write = (chunk, encoding, next) => {
159 | console.log(chunk.toString())
160 | next()
161 | }
162 | ```
163 |
164 | Agora você pode iniciar um stream Readable em:
165 |
166 | `process.stdin.pipe(writableStream)`
167 |
168 | ### Como obter dados de um stream Readable
169 |
170 | Como lemos dados de um stream Readable? Usando um stream Writable:
171 |
172 | ```
173 | const Stream = require('stream')
174 |
175 | const readableStream = new Stream.Readable()
176 | const writableStream = new Stream.Writable()
177 |
178 | writableStream._write = (chunk, encoding, next) => {
179 | console.log(chunk.toString())
180 | next()
181 | }
182 |
183 | readableStream.pipe(writableStream)
184 |
185 | readableStream.push('hi!')
186 | readableStream.push('ho!')
187 | ```
188 |
189 | Você também pode consumir um stream Readable diretamente, usando o evento `readable`:
190 |
191 | ```
192 | readableStream.on('readable', () => {
193 | console.log(readableStream.read())
194 | }
195 | ```
196 |
197 | ### Como enviar dados para um stream Writable
198 |
199 | Usando o método stream `write()`:
200 |
201 | `writableStream.write('hey!\n')`
202 |
203 | ### Apontar para o stream grávavel que você escreveu
204 |
205 | Use o método `end()`:
206 |
207 | ```
208 | const Stream = require('stream')
209 |
210 | const readableStream = new Stream.Readable()
211 | const writableStream = new Stream.Writable()
212 |
213 | writableStream._write = (chunk, encoding, next) => {
214 | console.log(chunk.toString())
215 | next()
216 | }
217 |
218 | readableStream.pipe(writableStream)
219 | ```
220 |
221 | ### Conclusão
222 |
223 | Esta é uma introdução aos streams. Há aspectos muito mais complicados para analisar e espero cobri-los em breve.
224 |
225 | ## Trabalhando com MySQL
226 |
227 | **O MySQL é um dos bancos de dados relacionais mais populares do mundo. Descubra como fazê-lo funcionar com o Node.js**
228 |
229 | É claro que o ecossistema do Node possui vários pacotes diferentes permitindo você interagir com o MySQL para armazenar dados, recuperar dados e assim por diante.
230 |
231 | Usaremos `mysqljs/mysql`, um pacote que existe há anos e tem mais de 12.000 estrelas no GitHub.
232 |
233 | ### Instalando o pacote mysql no Node
234 |
235 | Você instala usando npm
236 |
237 | `npm install mysql`
238 |
239 | ### Inicializando a conexão com o banco de dados
240 |
241 | Primeiramente, você inclui o pacote:
242 |
243 | `const mysql = require('mysql')`
244 |
245 | e cria uma conexão:
246 |
247 | ```
248 | const options = {
249 | user: 'the_mysql_user_name',
250 | password: 'the_mysql_user_password',
251 | database: 'the_mysql_database_name'
252 | }
253 | const connection = mysql.createConnection(options)
254 | ```
255 |
256 | Você inicia uma nova conexão chamando:
257 |
258 | ```
259 | connection.connect(err => {
260 | if (err) {
261 | console.error('An error occurred while connecting to the DB')
262 | throw err
263 | }
264 | })
265 | ```
266 |
267 | ### As opções de conexão
268 |
269 | No exemplo acima, o objeto options tinha 3 opções:
270 |
271 | ```
272 | const options = {
273 | user: 'the_mysql_user_name',
274 | password: 'the_mysql_user_password',
275 | database: 'the_mysql_database_name'
276 | }
277 | ```
278 |
279 | Existem muitas outras que você pode usar, incluindo:
280 |
281 | - `host`: o nome padrão do host do banco de dados é `localhost`
282 | - `port`: o número padrão da porta do servidor MySQL é 3306
283 | - `socketPath`: em vez de usar host e porta, socketPath é usado para especificar um socket unix.
284 | - `debug`: por padrão desabilitado, pode ser usado para depuração
285 | - `trace`: por padrão ativado, imprime rastreamentos de pilha quando ocorrem erros
286 | - `ssl`: usado para configurar uma conexão SSL com o servidor (fora do escopo deste tutorial)
287 |
288 | ### Executar uma consulta SELECT
289 |
290 | Agora você está pronto para executar uma consulta SQL no banco de dados. A consulta executada invocará uma função callback que contém um eventual erro, os resultados e os campos.
291 |
292 | ```
293 | connection.query('SELECT * FROM todos', (error, todos, fields) => {
294 | if (error) {
295 | console.error('An error occurred while executing the query')
296 | throw error
297 | }
298 | console.log(todos)
299 | })
300 | ```
301 |
302 | Você pode passar valores que serão retirados automaticamente:
303 |
304 | ```
305 | const id = 223
306 | connection.query('SELECT * FROM todos WHERE id = ?', [id], (error, todos, fields) => {
307 | if (error) {
308 | console.error('An error occurred while executing the query')
309 | throw error
310 | }
311 | console.log(todos)
312 | })
313 | ```
314 |
315 | Para passar vários valores, basta colocar mais elementos no array que você passa como o segundo parâmetro:
316 |
317 | ```
318 | const id = 223
319 | const author = 'Flavio'
320 | connection.query('SELECT * FROM todos WHERE id = ? AND author = ?', [id, author], (error, todos, fields) => {
321 | if (error) {
322 | console.error('An error occurred while executing the query')throw error
323 | }
324 | console.log(todos)
325 | })
326 | ```
327 |
328 | ### Executar uma consulta INSERT
329 |
330 | Você pode passar um objeto:
331 |
332 | ```
333 | const todo = {
334 | thing: 'Buy the milk'
335 | author: 'Flavio'
336 | }
337 | connection.query('INSERT INTO todos SET ?', todo, (error, results, fields) => {
338 | if (error) {
339 | console.error('An error occurred while executing the query')throw error
340 | }
341 | })
342 | ```
343 |
344 | Se a tabela tiver uma chave primária com `auto_increment`, o valor disso será retornado no valor de `results.insertId`:
345 |
346 | ```
347 | const todo = {
348 | thing: 'Buy the milk'
349 | author: 'Flavio'
350 | }
351 | connection.query('INSERT INTO todos SET ?', todo, (error, results, fields) => {
352 | if (error) {
353 | console.error('An error occurred while executing the query')
354 | throw error
355 | }}
356 | const id = results.resultId
357 | console.log(id)
358 | )
359 | ```
360 |
361 | ### Feche a conexão
362 |
363 | Quando você precisar finalizar a conexão com o banco de dados, pode chamar o método `end()`:
364 |
365 | `connection.end()`
366 |
367 | Isso garante que qualquer consulta pendente seja enviada e a conexão seja encerrada normalmente.
368 |
369 | ## Diferença entre desenvolvimento e produção
370 |
371 | **Aprenda a definir diferentes configurações para os ambientes de produção e desenvolvimento**
372 |
373 | Você pode ter configurações diferentes para ambientes de produção e desenvolvimento.
374 |
375 | O Node assume que está sempre rodando em um ambiente de desenvolvimento. Você pode sinalizar ao Node.js que está executando a produção, definindo a variável de ambiente `NODE_ENV=production`.
376 |
377 | Isso geralmente é feito executando o comando:
378 |
379 | `export NODE_ENV=production`
380 |
381 | no shell, mas é melhor colocá-lo no seu arquivo de configuração do shell (por exemplo, `.bash_profile` com o shell bash) porque, caso o sistema seja reinicializado, a configuração não se manterá.
382 |
383 | Você também pode aplicar a variável de ambiente anexando-a ao comando de inicialização do aplicativo:
384 |
385 | `NODE_ENV=production node app.js`
386 |
387 | Essa variável de ambiente também é uma convenção amplamente usada em bibliotecas externas.
388 |
389 | Definir o ambiente como `produção` geralmente garante que:
390 |
391 | - o registro é mantido em um nível mínimo e essencial
392 | - mais níveis de cache ocorram, otimizando o desempenho
393 |
394 | Por exemplo, Pug, a biblioteca de modelos usada pelo Express, compila no modo de debug se `NODE_ENV` não estiver definido como` produção`. As visualizações do Express são compiladas em cada modo de desenvolvimento de requisição, enquanto na produção elas são armazenadas em cache.
395 |
396 | Há muitos mais exemplos.
397 |
398 | O Express fornece hooks de configuração específicos para o ambiente, que são chamados automaticamente com base no valor da variável NODE_ENV:
399 |
400 | ```
401 | app.configure('development', () => {
402 | //...
403 | })
404 | app.configure('production', () => {
405 | //...
406 | })
407 | app.configure('production', 'staging', () => {
408 | //...
409 | })
410 | ```
411 |
412 | Por exemplo, você pode usar isso para definir diferentes manipuladores de erro para diferentes modos:
413 |
414 | ```
415 | app.configure('development', () => {
416 | app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
417 | })
418 | app.configure('production', () => {
419 | app.use(express.errorHandler())
420 | })
421 | ```
422 |
423 |
--------------------------------------------------------------------------------
/Capitulo_2.md:
--------------------------------------------------------------------------------
1 | BÁSICO
2 |
3 | ## Rodando scripts do Node da linha de comando
4 |
5 | ### Como rodar qualquer comando do Node na CLI
6 |
7 | A maneira usual de executar um programa Node é chamar comando global `node` (que fica disponível quando
8 | você instala o Node) e passar o nome do arquivo que deseja executar.
9 |
10 | Se o arquivo principal do aplicativo Node estiver em `app.js`, você poderá chamá-lo digitando
11 |
12 | ```
13 | node app.js
14 | ```
15 |
16 | ## Como sair de um programa em Node
17 |
18 | ### Aprenda a finalizar um aplicativo Node.js. da melhor maneira possível
19 |
20 | Existem várias maneiras de encerrar um aplicativo Node.js.
21 | Ao executar um programa no console, você pode fechá-lo com `ctrl-C`, mas o que eu quero
22 | discutir aqui é sair 'programaticamente'.
23 |
24 | Vamos começar com a maneira mais drástica e ver por que é melhor não usá-la.
25 |
26 | O módulo principal do `process` é um método útil que permite sair 'programaticamente' de um programa Node.js: `process.exit()`.
27 | Quando o Node.js executa esta linha, o processo é imediatamente forçado a terminar.
28 |
29 | Isso significa que qualquer retorno de chamada pendente, qualquer solicitação de rede ainda sendo enviada, qualquer
30 | acesso ao sistema de arquivos ou processos de gravação em `stdout` ou `stderr` - tudo será descartado imediatamente.
31 |
32 | Se isso for útil para você, você pode passar um número inteiro que sinalizará ao sistema operacional o código de saída:
33 |
34 | ```
35 | process.exit(1)
36 | ```
37 |
38 | Por padrão, o código de saída é 0, o que significa sucesso. Diferentes códigos de saída têm diferentes
39 | significados que você pode querer usar em seu próprio sistema para que o seu programa se comunique
40 | com outros programas.
41 |
42 | Você pode ler mais sobre códigos de saída em https://nodejs.org/api/process.html#process_exit_codes
43 |
44 | Você também pode definir a propriedade `process.exitCode`:
45 |
46 | ```
47 | process.exitCode = 1
48 | ```
49 |
50 | e quando o programa terminar, o Node retornará esse código de saída.
51 |
52 | Um programa será encerrado normalmente quando todo o processamento estiver concluído.
53 |
54 | Muitas vezes iniciamos servidores com o Node , como este servidor HTTP:
55 |
56 | ```
57 |
58 | const express = require('express')
59 | const app = express()
60 |
61 | app.get('/', (req, res) => {
62 | res.send('Hi!')
63 | })
64 |
65 | app.listen(3000, () => console.log('Server ready'))
66 |
67 | ```
68 |
69 | Este programa nunca vai acabar. Se você chamar `process.exit()`, qualquer solicitação pendente ou em execução será abortada. Isso não é o ideal.
70 |
71 | Nesse caso, você precisa enviar ao comando um sinal SIGTERM e lidar com isso usando
72 | manipulador de sinal do processo:
73 |
74 | > Nota: `process` não precisa de um "require", ele está disponível automaticamente.
75 |
76 | ```
77 |
78 | const express = require('express')
79 | const app = express()
80 |
81 | app.get('/', (req, res) => {
82 | res.send('Hi!')
83 | })
84 |
85 | const server = app.listen(3000, () => console.log('Server ready'))
86 |
87 | process.on('SIGTERM', () => {
88 | server.close(() => {
89 | console.log('Process terminated')
90 | })
91 | })
92 |
93 | ```
94 |
95 | `SIGKILL` são os sinais que informam um processo para terminar imediatamente e, idealmente, agiriam como
96 | `process.exit()`.
97 |
98 | `SIGTERM` são os sinais que informam a um processo para terminar normalmente. É o sinal que é enviado
99 | de gerentes de processo, como iniciantes ou supervisores.
100 |
101 | Você pode enviar este sinal de dentro do programa, em outra função:
102 |
103 | ```
104 | process.kill(process.pid, 'SIGTERM')
105 |
106 | ```
107 |
108 | ## Como ler variáveis de ambiente
109 |
110 | ### Aprenda a ler e usar variáveis de ambiente em uma aplicação Node.js
111 |
112 | O módulo principal `process` do Node fornece a propriedade `env`, que hospeda todos as
113 | variáveis de ambiente definidas no momento em que o processo foi iniciado.
114 |
115 | Aqui está um exemplo que acessa a variável de ambiente NODE_ENV, definida como
116 | `development` por padrão.
117 |
118 | ```
119 | process.env.NODE_ENV // "development"
120 |
121 | ```
122 |
123 | Configurá-lo para `production` antes da execução do script informará ao Node que esta é uma produção
124 | no seu ambiente.
125 |
126 | Da mesma maneira, você pode acessar qualquer variável de ambiente personalizada que definir.
127 |
128 | ## Opções de hospedagem Node
129 |
130 | ### Um aplicativo Node.js pode ser hospedado em muitos lugares, dependendo da sua
131 | necessidade. Esta é uma lista de algumas opções que você tem à sua disposição
132 |
133 | Aqui está uma lista das opções que você pode explorar quando deseja implantar seu aplicativo
134 | e torná-lo acessível ao público.
135 |
136 | Vou listar opções tanto simples e restritas quanto complexas e poderosas.
137 |
138 | - A opção mais simples: local tunnel
139 | - Deploys sem configuração
140 | - Glitch
141 | - Codepen
142 | - Serverless
143 | - PAAS
144 | - Zeit Now
145 | - Nanobox
146 | - Heroku
147 | - Microsoft Azure
148 | - Google Cloud Plataform
149 | - Servidor Virtual Privado
150 |
151 | ## A opção mais simples: local tunnel
152 |
153 | Mesmo se você possuir um IP dinâmico ou estiver sob um NAT, poderá implantar sua aplicação e servir
154 | solicitações diretamente do seu computador usando um túnel local.
155 |
156 | Essa opção é adequada para testes rápidos, demonstrações de produtos ou compartilhamento de uma aplicação com um grupo pequeno de pessoas.
157 |
158 | Uma ferramenta muito boa para isso, disponível em todas as plataformas, é o `ngrok`.
159 |
160 | Usando-o, você pode digitar `ngrok PORT` e o PORT desejado é exposto à Internet. Você
161 | obterá um domínio `ngrok.io`, mas com uma assinatura paga poderá obter um URL personalizado e
162 | mais opções de segurança (lembre-se de que você está expondo sua máquina na Internet).
163 |
164 | Outro serviço que você pode usar é https://github.com/localtunnel/localtunnel.
165 |
166 | ## Deploys sem configuração
167 |
168 | ### Glitch
169 |
170 | O Glitch é um playground e uma maneira de criar seus aplicativos mais rapidamente do que nunca, além de vê-los ao vivo
171 | no próprio subdomínio glitch.com. No momento, você não pode ter um domínio personalizado e existem outras
172 | restrições, mas é uma plataforma realmente ótima para prototipações. Você obtém todo o poder do Node.js, uma CDN, armazenamento seguro para
173 | credenciais, importação/exportação do GitHub e muito mais.
174 |
175 | Fornecido pela empresa por trás do FogBugz e Trello (e co-criadores do Stack Overflow).
176 |
177 | Eu o uso muito para fins de demonstração.
178 |
179 | ### Codepen
180 |
181 | Codepen é uma incrível plataforma e comunidade. Você pode criar um projeto com vários arquivos,
182 | e implantá-lo com um domínio personalizado.
183 |
184 |
185 | ## Serverless
186 |
187 | O Serverless é uma maneira de publicar seus aplicativos sem um servidor para gerenciá-los. É um
188 | paradigma em que você publica seus aplicativos como funções e eles respondem em um endpoint de rede
189 | (também chamado FAAS - Functions As a Service*). *Funções como um serviço.
190 |
191 |
192 | Algumas opções populares são:
193 |
194 | - Serverless Framework
195 | - Standard Library
196 |
197 | ## PAAS
198 |
199 | PAAS signfica Platform As A Service (Plataforma como um serviço). Essas plataformas poupam o seu trabalho em muitas coisas que você deveria se preocupar, permitindo que foque no seu aplicativo.
200 |
201 | ### Zeit Now
202 |
203 | Zeit é uma opção interessante. Você apenas digita `now` no seu terminal, e ele cuida da implantação
204 | sua aplicação. Existe uma versão gratuita com limitações, e a versão paga, que é ainda mais poderosa.
205 | Você simplesmente esquece que existe um servidor, apenas foca no aplicativo.
206 |
207 | ### Nanobox
208 |
209 | [Nanobox](https://nanobox.io/)
210 |
211 | ### Heroku
212 |
213 | Heroku é uma plataforma incrível.
214 | Este é um ótimo artigo sobre como startar o [Node.js no Heroku](https://devcenter.heroku.com/articles/getting-started-with-nodejs).
215 |
216 | ### Microsoft Azure
217 |
218 | Azure é uma oferta da Microsoft Cloud.
219 |
220 | Confira como criar uma aplicação web com [Node.js. no Azure](https://docs.microsoft.com/en-us/microsoftteams/platform/get-started/get-started-nodejs).
221 |
222 | ### Google Cloud Platform
223 |
224 | O Google Cloud é uma estrutura incrível para seus apps.
225 |
226 | Eles tem uma ótima sessão de [documentação do Node](https://cloud.google.com/node/).
227 |
228 | ## Servidor Virtual Privado
229 |
230 | - Digital Ocean
231 | - Linode
232 | - Amazon Web Services, em particular, menciono o Amazon Elastic Beanstalk, que consegue diminuir um pouco a complexidade da AWS.
233 |
234 | Como eles fornecem uma máquina Linux vazia na qual você pode trabalhar, não há tutorial específico para estes.
235 |
236 | Existem muito mais opções nessa categoria, essas são apenas as que eu usei e recomendo.
237 |
238 |
--------------------------------------------------------------------------------
/Capitulo_3.md:
--------------------------------------------------------------------------------
1 | LINHA DE COMANDO
2 |
3 | ## Usando o Node REPL
4 |
5 | ### REPL significa Read-Evaluate-Print-Loop, e é uma ótima maneira de explorar os recursos do Node de maneira rápida
6 |
7 | O comando `node` é único que usamos para rodar nossos scripts:
8 | ```
9 | node script.js
10 | ```
11 |
12 | Se nós omitirmos o nome do arquivos, usamos isso no modo REPL:
13 | ```
14 | node
15 | ```
16 |
17 | Se você tentar isso no seu terminal, é isso que irá acontecer:
18 | ```
19 | ❯ node
20 | >
21 | ```
22 | o comando permanece no modo ocioso e aguarda a entrada de algo.
23 |
24 | Para ser mais preciso, REPL está esperando que digitemos algum código JavaScript.
25 |
26 | Comece simples e digite
27 | ```
28 | > console.log('test')
29 | test
30 | undefined
31 | >
32 | ```
33 |
34 | O primeiro valor, `test`, é a saída que solicitamos para console imprimir e, em seguida, fica `undefined` o valor de retorno do `console.log()`.
35 |
36 | Agora podemos inserir uma nova linha de JavaScript.
37 |
38 | ### Use o tab para auto-completar
39 |
40 | O legal do REPL é que ele é interativo.
41 |
42 | Ao escrever seu código, se você pressionar a tecla Tab, o REPL tentará completar automaticamente o que você
43 | escreveu, correspondendo a uma variável que você já definiu ou a alguma predefinida.
44 |
45 | ### Explorando objetos JavaScript
46 |
47 | Tente digitar o nome de uma classe JavaScript, como Number, adicione um ponto e pressione tab.
48 |
49 | O REPL imprimirá todas as propriedades e métodos que você pode acessar nessa classe:
50 |
51 | 
52 |
53 | ### Explorando objetos globais
54 |
55 | Você pode inspecionar os globais aos quais tem acesso digitando `global.` e pressionando `tab`:
56 |
57 | 
58 |
59 | ### A variavél especial `_`
60 |
61 | Se após algum código você digitar `_`, isso imprimirá o resultado da última operação.
62 |
63 | ### Comandos com ponto
64 |
65 | O REPL possui alguns comandos especiais, todos começando com um ponto `.`. Eles são
66 |
67 | - `.help`: mostra o comando help
68 |
69 | - `.editor`: da mais liberdade ao editor, permitindo ao usuários escrever código JavaScript multilinha com mais facilidade. Quando você estiver
70 | nesse modo, digite ctrl-D para executar o código que você escreveu.
71 |
72 | - `.break`:: ao inserir uma expressão de várias linhas, inserir o comando `.break` abortará
73 | entrada adicional. O mesmo que pressionar ctrl-C.
74 |
75 | - `.clear`: redefine o contexto REPL para um objeto vazio e limpa qualquer expressão de várias linhas.
76 |
77 | - `.load`: carrega um arquivo JavaScript relativo ao diretório em que você está trabalhando.
78 | - `.save`: salva tudo que você enviou no REPL a um arquivo (especifique o nome do arquivo).
79 |
80 | - `.exit`: o mesmo que pressionar Ctrl-C duas vezes
81 |
82 | ## Passando argumentos da linha de comando
83 |
84 | ### Como aceitar argumentos transmitidos a partir linha de comando em um programa Node.js
85 |
86 | Você pode transmitir quantos argumentos desejar ao invocar uma aplicação Node.js. usando
87 |
88 | ```
89 | node app.js
90 | ```
91 |
92 | Os argumentos podem ser autônomos ou ter uma chave e um valor.
93 |
94 | Por exemplo:
95 |
96 | ```
97 | node app.js flavio
98 |
99 | ```
100 |
101 | ou
102 |
103 |
104 | ```
105 | node app.js name=flavio
106 | ```
107 |
108 | Isso muda como você recuperará esse valor no seu código.
109 |
110 | A maneira como você o recupera é usando o objeto `process` incorporado ao Node.
111 |
112 | Ela expõe uma propriedade `argv`, que é uma matriz que contém toda os argumentos invocados na linha de comando.
113 |
114 | O primeiro argumento é o caminho completo do comando `node`.
115 |
116 | O segundo elemento é o caminho completo do arquivo que está sendo executado.
117 |
118 | Todos os argumentos adicionais estão presentes a partir da terceira posição adiante.
119 |
120 | Você pode iterar sobre todos os argumentos (incluindo o caminho do node e o caminho do arquivo) usando um loop.
121 |
122 | ```
123 | process.argv.forEach((val, index) => {
124 | console.log(`${index}: ${val}`)
125 | })
126 | ```
127 |
128 | Você pode obter apenas os argumentos adicionais criando uma nova matriz que exclua os 2 primeiros
129 | parâmetros:
130 |
131 | ```
132 | const args = process.argv.slice(2)
133 | ```
134 |
135 | Se você tiver um argumento sem um nome de índice, assim:
136 |
137 | ```
138 | node app.js flavio
139 | ```
140 |
141 | você pode acessar usando
142 |
143 | ```
144 | const args = process.argv.slice(2)
145 | args[0]
146 |
147 | ```
148 |
149 | Nesse caso:
150 | ```
151 | node app.js name=flavio
152 | ```
153 |
154 | `args[0]` é `name=flavio` e você precisa dar um parse nele. A melhor maneira de fazer isso é usando o
155 | biblioteca minimista, que ajuda a lidar com argumentos:
156 |
157 | ```
158 | const args = require('minimist')(process.argv.slice(2))
159 | args['name'] //flavio
160 |
161 | ```
162 |
163 | # Saídas para a linha de comando
164 |
165 | ### Como escrever no console da linha de comando usando o Node, desde o básico, com console.log, até cenários mais complexos
166 |
167 | - Saída básica usando o console module
168 | - Limpando o console
169 | - Contando elementos
170 | - Calculando o tempo gasto
171 | - stdout e stderr
172 | - Criando uma barra de progresso
173 |
174 | ## Saída básica usando o console module
175 |
176 | O Node fornece um módulo `console`, que oferece maneiras muito úteis de interagir com a linha de comando.
177 |
178 | É basicamente o mesmo objeto `console` que você encontra no navegador.
179 |
180 | O método mais básico e mais usado é o `console.log()`, que imprime no console a string que lhe é passada.
181 |
182 | Se você passar um objeto, ele será renderizado como uma string.
183 | Você pode passar inúmeras variáveis para console.log, por exemplo:
184 |
185 | ```
186 | const x = 'x'
187 | const y = 'y'
188 | console.log(x, y)
189 | ```
190 |
191 | e o Node irá printar os dois.
192 |
193 | Também podemos formatar frases decorada passando um especificador de formato junto com as variáveis.
194 |
195 | Por exemplo:
196 |
197 | ```
198 | console.log('Meu %s tem %d anos', 'gato', 2)
199 | ```
200 |
201 | - `%s` formata uma variável como uma string
202 | - `%d` ou %i formata uma variável como um inteiro
203 | - `%f` formata a variável como float
204 | - `%O` usado para printar a representação de um objeto
205 |
206 | Example:
207 | ```
208 | console.log('%O', Number)
209 | ```
210 |
211 | ## Limpando o console
212 |
213 | `console.clear()` limpa o console (o comportamento pode depender do console usado).
214 |
215 | ## Contando elementos
216 |
217 | `console.count()` é um método útil.
218 |
219 | Veja esse código:
220 |
221 | ```
222 | const x = 1
223 | const y = 2
224 | const z = 3
225 | console.count(
226 | 'O valor de x é ' + x + ' e foi verificado.. quantas vezes?'
227 | )
228 | console.count(
229 | 'O valor de z é ' + z + ' e foi verificado .. quantas vezes?'
230 | )
231 | console.count(
232 | O valor de y é ' + y + ' e foi verificado .. quantas vezess?'
233 | )
234 |
235 | ```
236 |
237 | O que acontece é que o `count` contará o número de vezes que uma string é impressa e imprimirá a conta ao lado.
238 |
239 | Você pode apenas contar maçãs e laranjas:
240 |
241 | ```
242 | const laranjas = ['laranja', 'laranja']
243 | const maçãs = ['apenas uma maçã']
244 | maças.forEach(fruta => {
245 | console.count(fruta)
246 | })
247 | maçãs.forEach(fruta => {
248 | console.count(fruta)
249 | })
250 |
251 | ```
252 |
253 | ## Calculando o tempo gasto
254 |
255 | Você pode calcular facilmente quanto tempo uma função leva para executar, usando time () e timeEnd ()
256 |
257 | ```
258 | const doSomething = () => console.log('test')
259 | const measureDoingSomething = () => {
260 | console.time('doSomething()')
261 | //faça algo, e calcule o tempo que isso leva
262 | doSomething()
263 | console.timeEnd('doSomething()')
264 | }
265 | measureDoingSomething()
266 |
267 | ```
268 |
269 | ## stdout e stderr
270 |
271 | Como vimos, o console.log é ótimo para imprimir mensagens no console. É isso que chamamos de saída padrão ou `stdout`.
272 |
273 | `console.error` imprime no stderr.
274 |
275 | Ele não aparecerá no console, mas aparecerá no log de erros.
276 |
277 | ## Criando uma barra de progresso
278 |
279 | Progress é um pacote incrível para criar uma barra de progresso no console. Instale-o usando o `npm install progress`.
280 |
281 | Esse snippet cria uma barra de progresso de 10 etapas e, a cada 100ms, uma etapa é concluída. Quando
282 | a barra é concluída, limpamos o intervalo:
283 |
284 | ```
285 | const ProgressBar = require('progress')
286 |
287 | const bar = new ProgressBar(':bar', { total: 10 })
288 | const timer = setInterval(() => {
289 | bar.tick()
290 | if (bar.complete) {
291 | clearInterval(timer)
292 | }
293 | }, 100)
294 | ```
295 |
296 | ## Aceitando entradas da linha de comando
297 |
298 | Como tornar um programa CLI do Node.js. interativo?
299 |
300 | O Node, desde a versão 7, fornece o módulo `readline` para executar exatamente isso: obter a entrada de uma stream legível, como a stream `process.stdin`, que durante a execução de uma aplicação Node é a entrada do terminal, uma linha de cada vez.
301 |
302 | ```
303 | const readline = require('readline').createInterface({
304 | input: process.stdin,
305 | output: process.stdout
306 | })
307 |
308 | readline.question(`Qual o seu nome?`, (name) => {
309 | console.log(`Olá ${name}!`)
310 | readline.close()
311 | })
312 |
313 | ```
314 |
315 | Esse trecho de código solicita o nome de usuário e, uma vez que o texto é inserido e o usuário pressiona
316 | enter, enviamos uma saudação.
317 |
318 | O método `question()` mostra o primeiro parâmetro (uma pergunta) e aguarda a entrada do usuário. Isso
319 | chama a função de callback depois que o enter é pressionado.
320 |
321 | Nesta callback, fechamos a interface `readline`.
322 |
323 | O `readline` oferece vários outros métodos, e eu vou deixar você conferir no pacote
324 | documentação que eu vinculei acima.
325 |
326 | Se você precisar solicitar uma senha, é melhor repeti-la mostrando um `*`.
327 |
328 | A maneira mais simples é usar o pacote `readline-sync`, que é muito semelhante em termos de
329 | API e lida com isso imediatamente.
330 |
331 | Uma solução mais completa e abstrata é fornecida pelo pacote `Inquirer.js`.
332 |
333 | Você pode instalá-lo usando o `npm install inquirer` e, em seguida, pode replicar o código acima, como
334 | isto:
335 |
336 | ```
337 | const inquirer = require('inquirer')
338 |
339 | var questions = [{
340 | type: 'input',
341 | name: 'name',
342 | message: "Qual o seu nome?",
343 | }]
344 |
345 | inquirer.prompt(questions).then(answers => {
346 | console.log(`Oi ${answers['name']}!`)
347 | })
348 |
349 | ```
350 |
351 | O `Inquirer.js` permite fazer várias coisas, como mostrar várias opções, ter radio buttons,
352 | confirmações e muito mais.
353 |
354 | Vale a pena conhecer todas as alternativas, especialmente as internas fornecidas pelo Node, mas se você
355 | planeja levar a entrada da CLI para o próximo nível, o `Inquirer.js` é a melhor opção.
356 |
--------------------------------------------------------------------------------
/Capitulo_4.md:
--------------------------------------------------------------------------------
1 | NODE MODULES E NPM
2 |
3 | ## Expor a funcionalidade de um arquivo Node usando imports
4 |
5 | ### Como usar a API `module.exports` para expor dados a outros arquivos no seu aplicativo ou para outros aplicativos também
6 |
7 | O Node possui um sistema de módulos embutido.
8 |
9 | Um arquivo Node.js pode importar a funcionalidade exposta por outros arquivos Node.js.
10 |
11 | Quando você deseja importar algo que você usa
12 |
13 | ```
14 | const library = require('./library')
15 | ```
16 |
17 | para importar a funcionalidade exposta no arquivo `library.js` que reside na pasta do arquivo atual.
18 |
19 | Nesse arquivo, a funcionalidade deve ser exposta antes de poder ser importada por outros arquivos.
20 |
21 | Qualquer outro objeto ou variável definido no arquivo é privado por padrão, não ficando exposto ao
22 | 'mundo exterior'.
23 |
24 | É isso que a API `module.exports` oferecida pelo sistema do módulo nos permite fazer.
25 |
26 | Quando você atribui um objeto ou uma função como uma nova propriedade de exportação, isso é
27 | exposto e, como tal, pode ser importado tanto em outras partes do seu aplicativo local como em outros aplicativos externos.
28 |
29 | Você pode fazer isso de duas maneiras.
30 |
31 | O primeira é atribuindo um objeto ao `module.exports`, que é um objeto fornecido imediatamente
32 | pelo sistema de módulos, e isso fará com que seu arquivo exporte exatamente esse objeto:
33 |
34 | ```
35 | const car = {
36 | brand: 'Ford',
37 | model: 'Fiesta'
38 | }
39 |
40 | module.exports = car
41 | //..em outro arquivo
42 | const car = require('./car')
43 |
44 | ```
45 |
46 | A segunda maneira é adicionar o objeto exportado como uma propriedade de `exports`. Desta forma, você pode exportar vários objetos, funções ou dados:
47 |
48 | ```
49 | const car = {
50 | brand: 'Ford',
51 | model: 'Fiesta'
52 | }
53 |
54 | exports.car = car
55 | ```
56 |
57 | ou diretamente:
58 |
59 | ```
60 | exports.car = {
61 | brand: 'Ford',
62 | model: 'Fiesta'
63 | }
64 | ```
65 |
66 | E no outro arquivo, você o utilizará referenciando uma propriedade de sua importação:
67 |
68 | ```
69 | const items = require('./items')
70 | items.car
71 |
72 | ```
73 |
74 | ou
75 |
76 | ```
77 | const car = require('./items').car
78 | ```
79 |
80 | Qual é a diferença entre `module.exports` e `export`?
81 |
82 | O primeiro expõe o objeto para o qual aponta. O último expõe as propriedades do objeto para o qual aponta.
83 |
84 | ## npm
85 |
86 | Um guia rápido para o `npm`, o poderoso gerenciador de pacotes responsável pelo sucesso do Node.js. Em janeiro de 2017, mais de 350000 pacotes foram listados em
87 | registro npm, tornando-o o maior repositório de códigos de idioma único da Terra, e você pode ter certeza de que há um pacote para (quase!) tudo.
88 |
89 | - Introdução ao npm
90 | - Downloads
91 | - Instalando todas as dependências
92 | - Instalando um único pacote
93 | - Atualizando pacotes
94 | - Versionamento
95 | - Tarefas em execução
96 |
97 | ## Introdução ao npm
98 |
99 | `npm` é o gerenciador de arquivos padrão do Node.
100 |
101 | Em janeiro de 2017, mais de 350000 pacotes foram listados em
102 | registro npm, tornando-o o maior repositório de códigos de idioma único da Terra, e você pode ter certeza de que há um pacote para (quase!) tudo.
103 |
104 | Ele começou como uma maneira de baixar e gerenciar as dependências dos pacotes Node, mas também se tornou uma ferramenta usada no front-end com JavaScript.
105 |
106 | Há muitas coisas que o `npm` pode fazer.
107 |
108 | > O [Yarn](https://flaviocopes.com/yarn) é uma alternativa ao npm. Certifique-se de dar uma olhadinha também.
109 |
110 | ## Downloads
111 |
112 | O npm gerencia os downloads de dependências do seu projeto.
113 |
114 | ### Instalando todas as dependências
115 |
116 | Se um projeto tiver um arquivo `packages.json`, executando
117 |
118 | ```
119 | npm install
120 | ```
121 |
122 | ele instalará tudo o que o projeto precisa na pasta `node_modules`. Se essa pasta ainda não existir, ele irá criá-la.
123 |
124 | ### Instalando um único pacote
125 |
126 | Você também pode instalar um pacote específico executando
127 |
128 | ```
129 | npm install
130 |
131 | ```
132 |
133 | Frequentemente, você verá mais flags adicionados a este comando:
134 |
135 |
136 | - `--save` instala e adiciona nas `dependencies` do arquivo `package.json`
137 |
138 | - `--save-dev` instala e adiciona nas `devDependencies` do arquivo `package.json`
139 |
140 | A principal diferença é que as devDependencies geralmente recebem as ferramentas de desenvolvimento, como um biblioteca de teste, enquanto as dependencies são incluídas no aplicativo em produção.
141 |
142 | ### Atualizando pacotes
143 |
144 | A atualização também é fácil, executando
145 |
146 | ```
147 | npm update
148 | ```
149 |
150 | o `npm` verificará todos os pacotes em busca de uma versão mais nova e que atenda às suas restrições de versão.
151 |
152 | Você também pode especificar um único pacote para atualizar:
153 |
154 | ```
155 | npm update
156 | ```
157 |
158 | ## Versionamento
159 |
160 | Além dos downloads simples, o `npm` também gerencia o controle de versão, para que você possa especificar
161 | versão específica de um pacote ou requerir uma versão superior ou inferior à que você precisa.
162 |
163 | Muitas vezes, você descobrirá que uma biblioteca é compatível apenas com uma versão principal de outra biblioteca.
164 |
165 | Ou que um bug na versão mais recente de uma lib, ainda não corrigida, está causando um problema.
166 |
167 | Especificar uma versão explícita de uma biblioteca também ajuda a manter todos na mesma
168 | versão de um pacote, assim toda a equipe pode executar a mesma versão, desde o arquivo `package.json`
169 | esteja atualizado.
170 |
171 | Em todos esses casos, o controle de versão ajuda muito. O `npm` segue o controle de versão semântico padrão, o `semver`.
172 |
173 | ## Tarefas em execução
174 |
175 | O arquivo package.json suporta um formato para especificar tarefas da linha de comandos que podem ser executadas
176 | usando
177 |
178 | ```
179 | npm run
180 | ```
181 |
182 | Por exemplo:
183 |
184 | ```
185 | {
186 | "scripts": {
187 | "start-dev": "node lib/server-development",
188 | "start": "node lib/server-production"
189 | },
190 | }
191 |
192 | ```
193 |
194 | É muito comum usar esse recurso para executar o Webpack:
195 |
196 | ```
197 | {
198 | "scripts": {
199 | "watch": "webpack --watch --progress --colors --config webpack.conf.js",
200 | "dev": "webpack --progress --colors --config webpack.conf.js",
201 | "prod": "NODE_ENV=production webpack -p --config webpack.conf.js",
202 | },
203 | }
204 |
205 | ```
206 |
207 | Portanto, em vez de digitar esses comandos longos, fáceis de esquecer ou digitar errado, você pode executar
208 |
209 | ```
210 | $ npm run watch
211 |
212 | $ npm run dev
213 |
214 | $ npm run prod
215 | ```
216 |
217 | ## Onde o npm instala os pacotes
218 |
219 | ### Como descobrir onde o npm instala os pacotes
220 |
221 | > Leia o [guia do npm](https://flaviocopes.com/npm/) se você estiver começando com o npm, ele entra em muitos detalhes do npm.
222 |
223 | Ao instalar um pacote usando o npm (ou yarn), você pode executar 2 tipos de instalação:
224 |
225 | - instalação local
226 | - instalação global
227 |
228 | Por padrão, quando você digita um comando npm install, como:
229 |
230 | ```
231 | npm install lodash
232 | ```
233 | o pacote é instalado na árvore de arquivos atual, na subpasta `node_modules`.
234 |
235 | Quando isso acontece, o npm também adiciona a entrada lodash nas `dependencies` do
236 | arquivo package.json presente na pasta atual.
237 |
238 | Uma instalação global é realizada usando a flag `-g`:
239 |
240 | ```
241 | npm install -g lodash
242 | ```
243 |
244 | Quando isso acontece, o npm não instala o pacote na pasta local, mas, em vez disso, ele
245 | faz uma localização global.
246 |
247 | Mas onde exatamente?
248 |
249 | O comando `npm root -g` informará para onde esse local aponta na sua máquina.
250 |
251 | ## Como usar ou executar um pacote instalado com o npm
252 |
253 | ### Como incluir e usar no seu código um pacote instalado no seu arquivo node_modules
254 |
255 |
256 | Quando você instala um pacote de forma local ou global, como
257 | você usa isso no seu código Node?
258 |
259 | Digamos que você instale o lodash usando
260 |
261 | ```
262 | npm install lodash
263 | ```
264 |
265 | Isso instalará o pacote na pasta local `node_modules`.
266 |
267 | Para usá-lo em seu código, basta importá-lo para o seu programa usando o `require`:
268 |
269 | ```
270 | const _ = require('lodash)
271 | ```
272 |
273 | E se o seu pacote for um executável?
274 |
275 | Nesse caso, ele colocará o arquivo executável na pasta `node_modules / .bin /`.
276 |
277 | Uma maneira fácil de demonstrar isso é usando o `cowsay`.
278 |
279 | O pacote `cowsay` fornece um programa de linha de comando que pode ser executado para que uma vaca
280 | diga alguma coisa.
281 |
282 | Quando você instala o pacote usando o `npm install cowsay`, ele se instala sozinho e adiciona algumas
283 | dependências na pasta `node_modules`:
284 |
285 |
286 |
287 | Há uma pasta .bin oculta, que contém links simbólicos para os binários do cowsay:
288 |
289 |
290 |
291 | Como você os executa?
292 |
293 | É claro que você pode digitar `./node_modules/.bin/cowsay` para executá-lo, e isso funciona, mas o `npx`, incluído nas
294 | as versões recentes do npm (desde a 5.2), é uma opção muito melhor. Você só executou:
295 |
296 | ```
297 | npx cowsay
298 | ```
299 |
300 | e o npx vai encontrar a localização do pacote.
301 |
302 |
303 |
304 |
305 | ## O arquivo package.json
306 |
307 | ### O arquivo package.json é um elemento-chave nas bases de código dos aplicativos produzidos com o Node.js.
308 |
309 |
310 | Se você já trabalhou em um projeto de Frontend, ou apenas utilizou JavaScript ou Node.js, você certamente encontrou o arquivo `package.json`.
311 |
312 | Para que ele serve? O que você deve saber sobre ele e quais coisas você pode
313 | fazer com ele?
314 |
315 | O arquivo `package.json` é uma espécie de manifesto para o seu projeto. Ele pode fazer muitas coisas, algumas delas nem um pouco relacionadas. Pode servir como um repositório central de configuração de ferramentas, por exemplo. É também onde o `npm`
316 | e o `yarn` armazenam os nomes e as versões dos pacotes instalados.
317 |
318 | - A estrutura do arquivo
319 | - Divisão de propriedades
320 | - name
321 | - author
322 | - contributors
323 | - bugs
324 | - homepage
325 | - version
326 | - license
327 | - keywords
328 | - description
329 | - repository
330 | - main
331 | - private
332 | - scripts
333 | - dependencies
334 | - devDependencies
335 | - engines
336 | - browserList
337 | - Versões dos pacotes
338 |
339 | ## A estrutura do arquivo
340 |
341 | Aqui está um arquivo package.json de exemplo:
342 |
343 | ```
344 | {
345 |
346 | }
347 | ```
348 |
349 | Está vazio! Não há requisitos fixos do que deve estar em um arquivo package.json, para um
350 | aplicação. O único requisito é que respeite o formato JSON, caso contrário não poderá ser
351 | lido por programas que tentam acessar suas propriedades de forma programática.
352 |
353 | Se você estiver criando um pacote Node.js. que deseja distribuir por `npm`, as coisas mudam
354 | radicalmente, e você deve ter um conjunto de propriedades que ajudem outras pessoas a usá-lo. Veremos
355 | mais sobre isso mais adiante.
356 |
357 | Este é outro package.json:
358 |
359 | ```
360 | {
361 | "name": "test-project"
362 | }
363 |
364 | ```
365 |
366 | Ele define uma propriedade `name`, que informa o nome do aplicativo ou pacote que está contido pasta em que esse arquivo está localizado.
367 | Aqui está um exemplo muito mais complexo, que eu extraí de uma aplicação em Vue.js:
368 |
369 | ```
370 | {
371 | "name": "test-project",
372 | "version": "1.0.0",
373 | "description": "A Vue.js project",
374 | "main": "src/main.js",
375 | "private": true,
376 | "scripts": {
377 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
378 | "start": "npm run dev",
379 | "unit": "jest --config test/unit/jest.conf.js --coverage",
380 | "test": "npm run unit",
381 | "lint": "eslint --ext .js,.vue src test/unit",
382 | "build": "node build/build.js"
383 | },
384 | "dependencies": {
385 | "vue": "^2.5.2"
386 | },
387 | "devDependencies": {
388 | "autoprefixer": "^7.1.2",
389 | "babel-core": "^6.22.1",
390 | "babel-eslint": "^8.2.1",
391 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
392 | "babel-jest": "^21.0.2",
393 | "babel-loader": "^7.1.1",
394 | "babel-plugin-dynamic-import-node": "^1.2.0",
395 | "babel-plugin-syntax-jsx": "^6.18.0",
396 | "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
397 | "babel-plugin-transform-runtime": "^6.22.0",
398 | "babel-plugin-transform-vue-jsx": "^3.5.0",
399 | "babel-preset-env": "^1.3.2",
400 | "babel-preset-stage-2": "^6.22.0",
401 | "chalk": "^2.0.1",
402 | "copy-webpack-plugin": "^4.0.1",
403 | "css-loader": "^0.28.0",
404 | "eslint": "^4.15.0",
405 | "eslint-config-airbnb-base": "^11.3.0",
406 | "eslint-friendly-formatter": "^3.0.0",
407 | "eslint-import-resolver-webpack": "^0.8.3",
408 | "eslint-loader": "^1.7.1",
409 | "eslint-plugin-import": "^2.7.0",
410 | "eslint-plugin-vue": "^4.0.0",
411 | "extract-text-webpack-plugin": "^3.0.0",
412 | "file-loader": "^1.1.4",
413 | "friendly-errors-webpack-plugin": "^1.6.1",
414 | "html-webpack-plugin": "^2.30.1",
415 | "jest": "^22.0.4",
416 | "jest-serializer-vue": "^0.3.0",
417 | "node-notifier": "^5.1.2",
418 | "optimize-css-assets-webpack-plugin": "^3.2.0",
419 | "ora": "^1.2.0",
420 | "portfinder": "^1.0.13",
421 | "postcss-import": "^11.0.0",
422 | "postcss-loader": "^2.0.8",
423 | "postcss-url": "^7.2.1",
424 | "rimraf": "^2.6.0",
425 | "semver": "^5.3.0",
426 | "shelljs": "^0.7.6",
427 | "uglifyjs-webpack-plugin": "^1.1.1",
428 | "url-loader": "^0.5.8",
429 | "vue-jest": "^1.0.2",
430 | "vue-loader": "^13.3.0",
431 | "vue-style-loader": "^3.0.1",
432 | "vue-template-compiler": "^2.5.2",
433 | "webpack": "^3.6.0",
434 | "webpack-bundle-analyzer": "^2.9.0",
435 | "webpack-dev-server": "^2.9.1",
436 | "webpack-merge": "^4.1.0"
437 | },
438 | "engines": {
439 | "node": ">= 6.0.0",
440 | "npm": ">= 3.0.0"
441 | },
442 | "browserslist": [
443 | "last 2 versions",
444 | "not ie <= 8"
445 | ]
446 | }
447 |
448 | ```
449 |
450 | há muita coisa acontecendo aqui:
451 |
452 | - `name` define o nome do pacote/aplicativo
453 | - `version` indica a versão atual
454 | - `description` é uma curta explicação do pacote/aplicativo
455 | - `main` define o ponto de entrada da aplicação
456 | - `private` se definido como `true`, previne que o pacote/aplicativo seja acidentalmente publicado no `npm`
457 | - `scripts` define um conjuto de scripts que você pode rodar
458 | - `dependencies` define uma lista de pacotes `npm` instalados como dependências
459 | - `devDependencies` define uma lista de pacotes `npm` instalados como dependências de desenvolvimento
460 | - `engines` define em quais versões do Node este pacote/aplicativo funciona
461 | - `browserslist` é usado para dizer a quais navegadores (e suas versões) você deseja oferecer suporte
462 |
463 | Todas essas propriedades são utilizadas tanto pelo `npm` quanto por qualquer outra ferramenta que possamos escolher.
464 |
465 | ## Versões dos pacotes
466 |
467 | Você viu na descrição acima números de versão como estes: `~3.0.0` e `^0.13.0`.
468 |
469 | O que eles significam e quais outros especificadores de versão você pode usar?
470 |
471 | Esse símbolo define quais atualizações daquela dependência o seu pacote aceita.
472 |
473 | Dado que usando `semver`(controle de versão semântico) todas as versões têm 3 dígitos, sendo o primeiro a
474 | versão principal, a segunda a versão menor e a terceira a versão do patch, você tem esses
475 | regras:
476 |
477 | - `~ `: se você escrever `~0.13.0` , você deseja atualizar apenas a versão do patch: `0.13.1` está ok, mas `0.14.0` não.
478 | - `^ `: se você escrever `^0.13.0` , você deseja atualizar versão do patch e a versão menor: `0.13.1`, `0.14.0` e assim por diante.
479 | - `* `: se você escrever `*`, isso significa que você aceita todas as atualizações, incluindo as principais atualizações de versão.
480 | - `> `: você aceita qualquer versão superior à especificada
481 | - `>= `: você aceita qualquer versão igual ou superior à especificada
482 | - `<= `: você aceita qualquer versão igual ou inferior à especificada
483 | - `< `: você aceita qualquer versão inferior à especificada
484 |
485 | Existem outras regras também:
486 |
487 | - nenhum símbolo: você aceita apenas a versão especificada
488 | - `latest`: você deseja usar a versão mais recente disponível
489 |
490 | ## O arquivo package-lock.json
491 |
492 | ### Como descobrir qual a versão de um pacote que você instalou no seu aplicativo
493 |
494 | Para ver a versão mais recente de todo o pacote npm instalado, incluindo suas dependências:
495 |
496 | ```
497 | npm list
498 | ```
499 |
500 | Exemplo:
501 | ```
502 | ❯ npm list
503 | /Users/flavio/dev/node/cowsay
504 | └─┬ cowsay@1.3.1
505 | ├── get-stdin@5.0.1
506 | ├─┬ optimist@0.6.1
507 | │ ├── minimist@0.0.10
508 | │ └── wordwrap@0.0.3
509 | ├─┬ string-width@2.1.1
510 | │ ├── is-fullwidth-code-point@2.0.0
511 | │ └─┬ strip-ansi@4.0.0
512 | │ └── ansi-regex@3.0.0
513 | └── strip-eof@1.0.0
514 | ```
515 |
516 | Você também pode simplesmente abrir o arquivo `package-lock.json`, mas isso envolve alguma verificação visual.
517 |
518 | `npm list -g` é o mesmo, mas para pacotes instalados globalmente.
519 |
520 | Para obter apenas os pacotes de nível superior (basicamente, aqueles que você disse ao npm para instalar e que listou
521 | no `package.json`), execute `npm list --depth = 0`:
522 |
523 | ```
524 | ❯ npm list --depth=0
525 | /Users/flavio/dev/node/cowsay
526 | └── cowsay@1.3.1
527 |
528 | ```
529 |
530 | Você pode obter a versão de um pacote especificando o seu nome:
531 |
532 | ```
533 | ❯ npm list cowsay
534 | /Users/flavio/dev/node/cowsay
535 | └── cowsay@1.3.1
536 |
537 | ```
538 |
539 | Se você quiser ver qual é a versão mais recente do seu pacote disponível no repositório npm, execute
540 | `npm view [package_name] version`:
541 |
542 | ```
543 | ❯ npm view cowsay version
544 |
545 | 1.3.1
546 | ```
547 |
548 | ## Como instalar uma versão mais antiga de um pacote `npm`
549 |
550 | ### Aprenda a instalar uma versão mais antiga de um pacote npm, algo que pode ser útil para resolver um problema de compatibilidade
551 |
552 | Você pode instalar uma versão antiga de um pacote npm usando a sintaxe `@`:
553 |
554 | ```
555 | npm install @
556 | ```
557 | Exemplo:
558 | ```
559 | npm install cowsay
560 | ```
561 | instala a versão 1.3.1 (no momento da digitação).
562 | Instale a versão 1.2.0 com:
563 |
564 | ```
565 | npm install cowsay@1.2.0
566 | ```
567 |
568 | O mesmo pode ser feito com pacotes globais:
569 |
570 | ```
571 | npm install -g webpack@4.16.4
572 | ```
573 |
574 | Você também pode estar interessado em listar todas aa versôes anteriores de um pacote. Você pode fazer isso com
575 | `npm view versions`:
576 |
577 | ```
578 | ❯ npm view cowsay versions
579 | [ '1.0.0',
580 | '1.0.1',
581 | '1.0.2',
582 | '1.0.3',
583 | '1.1.0',
584 | '1.1.1',
585 | '1.1.2',
586 | '1.1.3',
587 | '1.1.4',
588 | '1.1.5',
589 | '1.1.6',
590 | '1.1.7',
591 | '1.1.8',
592 | '1.1.9',
593 | '1.2.0',
594 | '1.2.1',
595 | '1.3.0',
596 | '1.3.1' ]
597 | ```
598 |
599 | ## Como atualizar todas as dependências do Node para a última versão
600 |
601 | ### Como você atualiza todas as npm dependenciesx no arquivo package.json, para a versão mais recente disponível?
602 |
603 | Quando você instala um pacote usando o `npm install `, a versão mais recente disponível do
604 | o pacote é baixado e colocado na pasta `node_modules`, e uma entrada correspondente é
605 | adicionado aos arquivos `package.json` e `package-lock.json` presentes na sua pasta atual.
606 |
607 | O `npm` calcula as dependências e instala também a versão mais recente disponível.
608 |
609 | Digamos que você instale o `cowsay`, uma ferramenta legal de linha de comando que permite fazer uma vaca dizer coisas.
610 |
611 | Quando você npm instala o `cowsay`, essa entrada é adicionada ao arquivo `package.json`:
612 |
613 | ```
614 | {
615 | "dependencies": {
616 | "cowsay": "^1.3.1"
617 | }
618 | }
619 | ```
620 |
621 | e este é um extrato do package-lock.json, onde removi as dependências aninhadas para ter mais
622 | clareza:
623 |
624 | ```
625 | {
626 | "requires": true,
627 | "lockfileVersion": 1,
628 | "dependencies": {
629 | "cowsay": {
630 | "version": "1.3.1",
631 | "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz",
632 | "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkMAjufp+0F9eLjzRnOHz
633 | VAYeIYFF5po5NjRrgefnRMQ==",
634 | "requires": {
635 | "get-stdin": "^5.0.1",
636 | "optimist": "~0.6.1",
637 | "string-width": "~2.1.1",
638 | "strip-eof": "^1.0.0"
639 | }
640 | }
641 | }
642 | }
643 | ```
644 |
645 | Agora, esses 2 arquivos nos dizem que instalamos a versão `1.3.1` do cowsay, e nossa regra para atualizações é
646 | `^1.3.1`.
647 |
648 | Se houver uma nova versão secundária ou de patch e digitarmos `npm update`, a versão instalada será
649 | atualizado e o arquivo `package-lock.json` preenchido de acordo com a nova versão.
650 |
651 | O `package.json` permanece inalterado.
652 |
653 | Para descobrir novos lançamentos dos pacotes, execute npm `outdated`.
654 |
655 | Aqui está a lista de alguns pacotes desatualizados em um repositório que não atualizei por um bom tempo:
656 |
657 |
658 |
659 | Algumas dessas atualizações são major releases (versões principais). Rodar `npm update` não atualizará essas versões. As major releases nunca são atualizadas dessa maneira porque (por definição) introduzem alterações que podem quebrar a aplicação, e o npm quer evitar esses problemas.
660 |
661 | Para atualizar todos os pacotes para uma nova versão principal, instale o pacote `npm-check-updates`
662 | globalmente:
663 |
664 | ```
665 | npm install -g npm-check-updates
666 | ```
667 |
668 | depois execute isso:
669 |
670 | ```
671 | ncu -u
672 | ```
673 |
674 | isso atualizará todas as dicas de versão no arquivo package.json, tanto nas `dependencies` quanto nas `devDependencies`, assim o npm poder instalar a nova versão principal.
675 |
676 | Agora você está pronto para executar a atualização:
677 |
678 | ```
679 | npm update
680 | ```
681 | Se você acabou de baixar o projeto sem as dependências do `node_modules` e deseja instalar as novas versões primeiro, basta executar
682 |
683 | ```
684 | npm install
685 | ```
686 |
687 | ## Desinstalando pacotes npm
688 |
689 | ### Como desinstalar um pacote npm no Node, localmente ou globalmente
690 |
691 | To uninstall a package you have previously installed locally (using npm install in the node_modules folder, run
692 | Para desinstalar um pacote que você instalou localmente (usando `npm install `) na pasta `node_modules`, execute
693 |
694 | ```
695 | npm uninstall
696 | ```
697 |
698 | Usando a flag `-S` ou `--save`, esta operação também removerá a referência no
699 | arquivo `package.json`.
700 |
701 | Se o pacote for uma dependência de desenvolvimento listada nas devDependencies do
702 | arquivo package.json, você deve usar as flags `-D` / `--save-dev` para removê-lo do arquivo:
703 |
704 | ```
705 | npm uninstall -S
706 | npm uninstall -D
707 | ```
708 | Se o pacote está instalado globalmente, você precisa adicionar as flags `-g` / `--global`:
709 |
710 | ```
711 | npm uninstall -g
712 | ```
713 |
714 | por exemplo:
715 | ```
716 | npm uninstall -g webpack
717 | ```
718 |
719 | Você pode executar este comando de qualquer lugar no seu sistema, não importando a pasta
720 | onde você está atualmente.
721 |
722 | ## Pacotes globais ou locais
723 |
724 |
725 | ### Quando é melhor instalar um pacote globalmente? E por quê?
726 |
727 | A principal diferença entre pacotes globais e locais é isso:
728 |
729 | - `pacotes locais` são instalados no diretório onde você executou `npm install `, e eles são colocados na pasta `node_modules`
730 |
731 | - `pacotes globais` são todos colocados em um único lugar no seu sistema (exatamente onde depende do seu setup), independente de onde você executou `npm install -g `
732 |
733 | No seu código, os dois são chamados da mesma maneira
734 |
735 | ```
736 | require('package-name') ou import
737 | ```
738 |
739 | Em geral, todos os pacotes devem ser instalados localmente.
740 |
741 | Isso garante que você possa ter dezenas de aplicativos em seu computador, todos executando como uma versão específica de cada pacote, se necessário.
742 |
743 | A atualização de um pacote global faria com que todos os seus projetos usassem a nova versão e, como você pode
744 | imaginar, isso pode causar pesadelos em termos de manutenção, pois alguns pacotes podem ter quebra de
745 | compatibilidade com outras dependências.
746 |
747 | Todos os projetos têm sua própria versão local de um pacote, mesmo que isso possa parecer um desperdício de
748 | recursos, é um esforço mínimo se comparado às possíveis consequências negativas.
749 |
750 | Um pacote deve ser instalado globalmente quando fornece um comando executável a partir da shell (CLI) e vai ser reutilizado em diferentes projetos.
751 |
752 | Você também pode instalar comandos executáveis localmente e rodá-los usando `npx`, mas alguns
753 | pacotes são melhores de serem instalados globalmente.
754 |
755 | Exemplos dos pacotes globais mais populares
756 |
757 | - `npm`
758 | - `create-react-app`
759 | - `vue-cli`
760 | - `grunt-cli`
761 | - `mocha`
762 | - `react-native-cli`
763 | - `gatsby-cli`
764 | - `forever`
765 | - `nodemon`
766 |
767 |
768 | Você provavelmente já tem alguns pacotes instalados globalmente no seu sistema. Você pode ver
769 | eles executando
770 | ```
771 | npm list -g --depth 0
772 | ```
773 | na sua linha de comando.
774 |
775 | ## npm dependencies e devDependencies
776 |
777 | ### Quando um pacote é uma dependência e quando é uma dependência de desenvolvedor?
778 |
779 | Quando você instala um pacote npm usando o `npm install `, você o instala como um
780 | dependencxy.
781 |
782 | O pacote é listado automaticamente no arquivo `package.json`, na lista de dependências (a partir do npm 5, você não precisa mais digitar `--save`).
783 |
784 | Quando você adiciona as flags `-D` ou `--save-dev`, você o instala como uma dependência de desenvolvedor, que a adiciona à lista `devDependencies`.
785 |
786 | As dependências de desenvolvimento são planejadas somente como pacotes de desenvolvimento, desnecessários
787 | em produção.
788 |
789 | Ao entrar em produção, se você digitar `npm install` e a pasta contiver um arquivo `package.json`, eles são instalados, pois o `npm` assume que esta é uma área de desenvolvimento.
790 |
791 | Você precisa definir o sinalizador `--production` (`npm install --production`) para evitar a instalação dessas
792 | dependências de desenvolvimento.
793 |
794 | ## npx
795 |
796 | O npx é uma maneira muito legal de executar o código Nodex e fornece recursos muito úteis
797 |
798 | Neste post, quero apresentar um comando muito poderoso que está disponível no npm
799 | a partir da versão 5.2, lançada em julho de 2017: o `npx`.
800 |
801 | Se você não deseja instalar o `npm`, pode instalar o `npx` como um pacote independente
802 |
803 | O `npx` permite executar o código criado com o Node e publicado através do registro npm.
804 |
805 |
806 | ### Execute facilmente comandos locais
807 |
808 | Os desenvolvedores do Node costumavam publicar a maioria dos comandos executáveis como pacotes globais.
809 |
810 | Isso era um problema, porque você realmente não podia instalar versões diferentes do mesmo comando.
811 |
812 | A execução de `npx commandname` localiza automaticamente a referência correta do comando dentro da
813 | pasta `node_modules` de um projeto, sem precisar conhecer o caminho exato e sem exigir que o pacote seja instalado globalmente.
814 |
815 |
816 | ## Executando algum código usando uma versão diferente do Node
817 |
818 | Use o `@` para especificar a versão e combine isso com o pacote npm `node`:
819 | ```
820 | npx node@6 -v #v6.14.3
821 | npx node@8 -v #v8.11.3
822 | ```
823 | Isso ajuda a evitar ferramentas como `nvm` ou outra versões de ferramentas de gerenciamento do Node
824 |
825 | ## Execute snippets de código diretamente de uma URL
826 |
827 | O `npx` não limita você aos pacotes publicados no registro npm.
828 |
829 | Você pode executar o código localizado em Github gist, por exemplo:
830 |
831 | ```
832 | npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32
833 | ```
834 |
835 | Obviamente, você precisa ter cuidado ao executar um código que não controla, afinal, com grandes poderes vem grandes responsabilidades.
836 |
837 |
--------------------------------------------------------------------------------
/Capitulo_5.md:
--------------------------------------------------------------------------------
1 | TRABALHANDO COM O EVENT LOOP
2 |
3 | ## O Event Loop
4 |
5 | ### O Loop de Eventos é um dos mais importantes conceitos para entender sobre JavaScript. Este post explica isso nos termos simples.
6 |
7 | - [Introdução](#introduction)
8 | - [Bloqueando o event loop](#event-loop-blocking)
9 | - [A pilha de chamadas (call stack)](#call-stack)
10 | - [Uma explicação simples do event loop](#event-loop-explanation)
11 | - [Execução das funções em fila](#queuing-function)
12 | - [A Fila de Mensagens](#message-queue)
13 | - [Fila de tarefas do ES6](#es6-job-queue)
14 |
15 | ## Introdução
16 |
17 | O **Event Loop** é um dos mais importantes conceitos para entender sobre JavaScript.
18 |
19 | > Programei por anos com JavaScript, no entanto, eu nunca entendi completamente como as coisas funcionam por baixo dos panos. É completamente normal não entender este conceito em detalhe, mas é util saber como ele funciona e você também pode estar um pouco curioso neste momento.
20 |
21 | Este post tem como objetivo, explicar os detalhes internos de como o JavaScript funciona em uma única thread e como ele lida com funções assíncronas.
22 |
23 | Seu código JavaScript é executado em uma thread única. Há apenas uma coisa acontecendo de cada vez.
24 |
25 | Está limitação é realmente muito útil, pois simplifica muito a maneira como você programa, sem se preocupar com problemas de concorrência.
26 |
27 | Você só precisa prestar atenção na forma como escreve seu código e evitar qualquer coisa que possa bloquear a thread, como chamadas de rede síncronas ou [loops](https://flaviocopes.com/javascript-loops/) infinitos.
28 |
29 | No geral, a maioria dos navegadores tem um event loop em cada aba. Isolando todos os processos e evitando que uma página Web tenha loops infinitos ou processamento pesado travando o navegador.
30 |
31 | Por exemplo, para manipular chamadas de API, o ambiente do navegador gerencia vários event loops simultâneos.
32 |
33 | Os [Web Workers](https://flaviocopes.com/web-workers/) também são executados em seu próprio event loop.
34 |
35 | Você precisa principalmente se preocupar com o fato de seu código ser executado em um único event loop e escrever o código com isso em mente para evitar bloqueá-lo.
36 |
37 | ## Bloqueando o event loop
38 |
39 | Qualquer código JavaScript que demore muito para retornar o controle ao event loop, bloqueará a execução de qualquer código JavaScript na página, bloqueando até mesmo a thread de interface do usuário, impedindo o usuário de clicar, rolar a página e assim por diante.
40 |
41 | Quase todas as primitivas de E/S em JavaScript são não bloqueantes. Solicitações de rede, operações do sistema de arquivos do [Node.js](https://flaviocopes.com/nodejs/). O bloqueio é a exceção, é por isso que o Javascript se baseia tanto em callbacks, e mais recentemente, em [Promises](https://flaviocopes.com/javascript-promises/) e [Async/Await](https://flaviocopes.com/javascript-async-await/).
42 |
43 | ## A pilha de chamadas (call stack)
44 |
45 | A pilha de chamadas é uma fila LIFO (Ultimo a entrar e primeiro a sair).
46 |
47 | O event loop verifica continuamente a pilha de chamadas para ver se há alguma função que precise ser executada.
48 |
49 | Enquanto faz isso, ele adiciona qualquer chamada de função que encontra à pilha de chamadas e executa cada uma na ordem.
50 |
51 | Você conhece a stack de erros que você normalmente usa, no debugger ou no console do navegador? O navegador consulta os nomes das funções na pilha de chamadas para informar você qual função originou a chamada atual.
52 |
53 | 
54 |
55 | ## Uma explicação simples do event loop
56 |
57 | Vamos ver este exemplo:
58 |
59 | ```javascript
60 | const bar = () => console.log('bar')
61 |
62 | const baz = () => console.log('baz')
63 |
64 | const foo = () => {
65 | console.log('foo')
66 | bar()
67 | baz()
68 | }
69 |
70 | foo()
71 | ```
72 |
73 | Este código imprime:
74 |
75 | ```
76 | foo
77 | bar
78 | baz
79 | ```
80 |
81 | como esperado.
82 |
83 | Quando esse código é executado, o primeiro `foo()` é chamado. Dentro de `foo()` primeiro chamamos `bar()`, depois chamamos `baz()`.
84 |
85 | Nesse ponto, a pilha de chamadas está assim:
86 |
87 | 
88 |
89 | O event loop em cada iteração verifica se há algo na pilha de chamadas e o executa:
90 |
91 | 
92 |
93 | até que a pilha de chamadas esteja vazia.
94 |
95 | ## Execução das funções em fila
96 |
97 | O exemplo acima parece normal, não há nada de especial nisso: JavaScript encontra coisas para executar e as executa na ordem.
98 |
99 | Vamos ver como adiar uma função até que a pilha esteje vazia.
100 |
101 | O caso de uso `setTimeout(() => {}), 0)` é para chamar uma função, mas somente executá-la quando todas as outras funções do código forem executadas.
102 |
103 | Veja este exemplo:
104 |
105 | ```
106 | const bar = () => console.log('bar')
107 |
108 | const baz = () => console.log('baz')
109 |
110 | const foo = () => {
111 | console.log('foo')
112 | setTimeout(bar, 0)
113 | baz()
114 | }
115 |
116 | foo()
117 | ```
118 |
119 | Esse código imprime, talvez surpreendentemente:
120 |
121 | ```
122 | foo
123 | baz
124 | bar
125 | ```
126 |
127 | Quando esse código é executado, o primeiro `foo()` é chamado. Dentro de `foo()`, chamamos o primeiro `setTimeout`, passando `bar` como argumento e instruímos a executar imediatamente o mais rápido possível, passando `0` para o cronômetro.
128 | Então chamamos `baz()`.
129 |
130 | Nesse ponto, a pilha de chamadas está assim:
131 |
132 | 
133 |
134 | Aqui está a ordem de execução de todas as funções em nosso programa:
135 |
136 | 
137 |
138 | Por que isso está acontecendo ?
139 |
140 | ## A Fila de Mensagens
141 |
142 | Quando `setTimeout()` é chamado, o Navegador ou o Node.js inicia o cronômetro. Quando o cronômetro expirar, neste caso imediatamente, pois colocamos `0` como tempo limite, a função callback é colocada na **Fila de Mensagens**.
143 |
144 | A Fila de Mensagens também é onde os eventos iniciados pelo usuário, como eventos de clique, teclado ou respostas da [fetch-api](https://flaviocopes.com/fetch-api/) são colocados antes que seu código tenha a oportunidade de reagiar a eles. Ou também eventos do [DOM](https://flaviocopes.com/dom/) como o `onLoad`.
145 |
146 | **O loop dá prioridade à pilha de chamadas. Primeiro, processa tudo que encontra na pilha de chamadas e, como não há nada lá, ele captura as coisas na fila de mensagens.**
147 |
148 | Não precisamos esperar por funções como `setTimeout`, `fetch` ou outras coisas façam seu próprio trabalho, porque elas são fornecidas pelo navegador e elas vivem em suas próprias threads. Por exemplo, se você definir o tempo limite de `setTimeout` para 2 segundos, não precisará esperar 2 segundos, a espera ocorrerá em outro lugar.
149 |
150 | ## Fila de tarefas do ES6
151 |
152 | O [ECMAScript 2015](https://flaviocopes.com/ecmascript/) introduziu o conceito de fila de tarefas, usada pelo `Promises` (também introduzida no ES2015). É uma maneira de executar o resultado de uma função assíncrona o mais rápido possível, em vez de ser colocada no final da pilha de chamadas.
153 |
154 | As Promises que finalizarem antes que a função atual termine, serão executadas logo após a função atual.
155 |
156 | Acho legal a analogia de uma montanha-russa em um parque de diversões: a fila de mensagens coloca você de volta na fila com todas as outras pessoas da fila, enquanto a fila de tarefas é o bilhete rápido que te permite ir de novo logo depois que você terminou a volta anterior.
157 |
158 | Exemplo:
159 |
160 | ```
161 | const bar = () => console.log('bar')
162 |
163 | const baz = () => console.log('baz')
164 |
165 | const foo = () => {
166 | console.log('foo')
167 | setTimeout(bar, 0)
168 | newPromise((resolve, reject) =>
169 | resolve('deve estar após baz e antes de bar')
170 | ).then(resolve => console.log(resolve))
171 | baz()
172 | }
173 |
174 | foo()
175 | ```
176 |
177 | Isso imprime:
178 |
179 | ```
180 | foo
181 | baz
182 | deve estar após baz e antes de bar
183 | bar
184 | ```
185 |
186 | Essa é uma grande diferença entre Promises e o Async/await, que é baseado em Promises, e explica as funções assíncronas antigas através do `setTimeout()` ou de outras plataformas de APIs.
187 |
--------------------------------------------------------------------------------
/Capitulo_6.md:
--------------------------------------------------------------------------------
1 | PROGRAMAÇÃO ASSÍNCRONA
2 |
3 | ## Callbacks
4 |
5 | ### O JavaScript é síncrono e single threaded por padrão. Isso significa que esse código não pode criar novas threads e executar em paralelo. Descubra o que código assíncrono significa e como ele se parece
6 |
7 |
8 |
9 | - Assincronicidade em linguagens de programação
10 | - JavaScript
11 | - Callbacks
12 | - Tratando erros nas callbacks
13 | - O problema com as callbacks
14 | - Alternativa as callbacks
15 |
16 | ### Assincronicidade em linguagens de programação
17 |
18 | Computadores são assíncronos por design.
19 |
20 | Assíncrono significa que as coisas podem acontecer independentemente do fluxo do programa principal.
21 |
22 | Nos computadores atuais, todos os programas são executados por um intervalo de tempo específico e, em seguida,
23 | interrompem sua execução para permitir que outro programa continue sua execução. Essa coisa roda em um ciclo tão
24 | rápido que é impossível perceber, e achamos que nossos computadores executam muitos programas
25 | simultaneamente, mas isso é uma ilusão (exceto em máquinas com multiprocessadores).
26 |
27 | Os programas usam, internamente, as interrupções, que são sinais emitidos ao processador para chamar a atenção
28 | do sistema.
29 |
30 | Eu não vou entrar fundo nisso, mas tenha em mente que é normal que os programas sejam
31 | assíncronos e interrompam sua execução até que o compoutador possa lher dar atenção. Enquanto isso, ele executa outras coisas. Quando um programa está aguardando uma resposta da
32 | rede, ele não pode parar o processador até que a solicitação seja concluída.
33 |
34 | Normalmente, as linguagens de programação são síncronas e algumas fornecem uma maneira de gerenciar
35 | assincronicidade, seja na linguagem ou através de bibliotecas. C, Java, C #, PHP, Go, Ruby, Swift,
36 | Python, todos eles são síncronos por padrão. Alguns deles lidam com assincronia usando threads,
37 | gerando um novo processo.
38 |
39 | ### JavaScript
40 |
41 |
42 | O JavaScript é síncrono por padrão e também single threaded. Isso significa que o código não pode
43 | criar novas threads e executá-las em paralelo.
44 |
45 | Linhas de código são executadas em série, uma após a outra, por exemplo:
46 |
47 | ```
48 | const a = 1
49 | const b = 2
50 | const c = a * b
51 | console.log (c)
52 | doSomething()
53 | ```
54 | Mas o JavaScript nasceu dentro do navegador, seu trabalho principal, no início, era responder a
55 | ações do usuário, como `onClick`, `onMouseOver`, `onChange`, `onSubmit` e assim por diante. Como isso pôde ser feito com um modelo de programação síncrona?
56 |
57 | A resposta estava em seu ambiente. O navegador fornece uma maneira de fazê-lo, fornecendo um conjunto de
58 | APIs que podem lidar com esse tipo de funcionalidade.
59 |
60 | Mais recentemente, o Node.js introduziu um ambiente de E/S sem bloqueio, estendendo esse conceito ao acesso de arquivos, chamadas de rede e assim por diante.
61 |
62 | ### Callbacks
63 |
64 | Você não pode saber quando um usuário clicará em um botão; portanto, o que você faz é definir um manipulador de eventos para o evento do click. Este manipulador de eventos aceita uma função, que será chamada quando
65 | o evento é acionado:
66 |
67 | ```
68 | document.getElementById('button').addEventListener('click', () => {
69 | //item clicado
70 | })
71 | ```
72 |
73 | Este é a chamada callback.
74 |
75 | Uma callbackx é uma função simples que é passada como um valor para outra função, e só será
76 | executada quando o evento acontece. Podemos fazer isso porque o JavaScript tem funções de primeira classe, que podem ser atribuídas a variáveis e passadas para outras funções (chamadas
77 | funções de ordem superior).
78 |
79 | É comum agrupar todo o código do cliente em um `load` no objeto `window`, que
80 | executa a callback somente quando a página está pronta:
81 |
82 | ```
83 | window.addEventListener('load', () => {
84 | // janela carregada
85 | // faça o que você quiser
86 | })
87 | ```
88 |
89 | Callbacks são usadas em todos os lugares, não apenas em eventos da DOM.
90 |
91 | Um exemplo comum é usando temporizadores:
92 | ```
93 | setTimeout(() => {
94 | // executa após dois segundos
95 | }, 2000)
96 | ```
97 |
98 | ### Tratando erros nas Callbacks
99 |
100 | Como você lida com erros em callbacks? Uma estratégia muito comum é usar o que o Node.js tem
101 | adotado: o primeiro parâmetro em qualquer callbaxck é o objeto de erro: *error-first callbacks*.
102 |
103 | Se não houver erro, o objeto é nulo. Se houver um erro, ele contém alguma descrição do
104 | erro e outras informações.
105 |
106 | ```
107 | fs.readFile('/file.json', (err, data) => {
108 | if (err !== null) {
109 | //tratando o erro
110 | console.log(err)
111 | return
112 | }
113 | //sem erros, processe os dados
114 | console.log(data)
115 | })
116 |
117 | ```
118 |
119 | ### O problema com as Callbacks
120 |
121 | As callbacks são ótimas para casos simples!
122 |
123 | No entanto, toda callback adiciona um nível de aninhamento e, quando você tem muitos retornos, o código
124 | começa a ficar complicado muito rapidamente, problema conhecido como *callback hell*.
125 |
126 |
127 | ```
128 | window.addEventListener('load', () => {
129 | document.getElementById('button').addEventListener('click', () => {
130 | setTimeout(() => {
131 | items.forEach(item => {
132 | //seu código aqui
133 | })
134 | }, 2000)
135 | })
136 | }
137 | ```
138 |
139 | Este é apenas um código simples de quatro níveis, mas já vi muitos níveis de aninhamento e não é nada divertido.
140 |
141 | Como solucionamos isso?
142 |
143 | - Promises (ES6)
144 | - Async/Await (ES8)
145 |
146 | ## Promises
147 |
148 | ### Promises são uma maneira de lidar com código assíncrono em JavaScript, sem precisar escrever muitas callbacks no seu código.
149 |
150 | - Introdução às promises
151 | - Como as promises funcionam, em resumo
152 | - Qual API do JavaScript usa promises?
153 | - Criando uma promise
154 | - Consumindo uma promise
155 | - Tratando erros
156 | - Cascading errors (erros em cascata)
157 | - Orquestando promises
158 | - Promise.all()
159 | - Promise.race()
160 | - Erros comuns
161 | - Uncaught TypeError: undefined is not a promise
162 |
163 | ### Introdução às promises
164 |
165 | Uma promise é geralmente definida como um proxy para um valor que acabará se tornando
166 | acessível.
167 |
168 | Promises são uma maneira de lidar com código assíncrono, sem escrever muitos callbacks em
169 | seu código.
170 |
171 | Embora existam há anos, elas foram padronizadas e introduzidas no ES2015,
172 | e agora já foram substituídos no ES2017 pelas funções assíncronas.
173 |
174 | As funções assíncronas usam a API das promises como seu componente básico, portanto, entendê-las é
175 | fundamental, mesmo que no código mais recente você provavelmente usará funções assíncronas em vez de promises.
176 |
177 | ### Como as promises funcionam, em resumo
178 |
179 | Uma vez que uma promise tenha sido chamada, ela começará no estado pendente. Isso significa que a função chamada continua a execução, enquanto aguarda a promise fazer seu próprio processamento e ar algum retorno à função de chamada.
180 |
181 | Nesse ponto, a função de chamada espera que ela retorne a promise em um estado resolvido ou
182 | em um estado rejeitado, mas como você sabe que o JavaScript é assíncrono, a função continua sua
183 | execução enquanto a promise trabalha.
184 |
185 | ### Qual API do JavaScript usa promises?
186 |
187 | Além do seu próprio código, e códigos de bibliotecas, as promises são usadas por APIs Web modernas:
188 |
189 | - Battery API
190 | - Fetch API
191 | - Service Workers
192 |
193 | É improvável que, no JavaScript moderno, você não esteja usando promises, então vamos começar
194 | mergulhando direto nelas.
195 |
196 | ## Criando uma promise
197 |
198 | Na última seção, apresentamos como uma promise é criada.
199 |
200 | Agora vamos ver como uma promise pode ser consumida ou usada
201 |
202 | ```
203 | const isItDoneYet = new Promise(
204 | //...
205 | )
206 |
207 | const checkIfItsDone = () => {
208 | isItDoneYet
209 | .then((ok) => {
210 | console.log(ok)
211 | })
212 | .catch((err) => {
213 | console.error(err)
214 | }
215 | ```
216 |
217 | A execução de `checkIfItsDone ()` executará a promessa `isItDoneYet ()` e esperará que ela
218 | esteja resolvida usando a callback `then` e, se houver um erro, ele tratará disso na callback `err`.
219 |
220 | ## Tratando erros
221 |
222 | No exemplo, na seção anterior, tivemos um `catch` que foi anexado à cadeia de
223 | promises.
224 |
225 | Quando algo na cadeia de promises falha e gera um erro, ou rejeita a promise, o controle vai para a instrução `catch()` mais próxima.
226 |
227 | ```
228 | new Promise((resolve, reject) => {
229 | throw new Error('Error')
230 | })
231 | .catch((err) => { console.error(err) })
232 |
233 | // or
234 |
235 | new Promise((resolve, reject) => {
236 | reject('Error')
237 | })
238 | .catch((err) => { console.error(err) })
239 | ```
240 |
241 | ### Cascading errors (erros em cascata)
242 |
243 | Se dentro de um `catch()` você disparar um erro, você pode adicionar um segundo `catch()` para tratá-lo, e assim por diante.
244 |
245 | ```
246 | new Promise((resolve, reject) => {
247 | throw new Error('Error')
248 | })
249 | .catch((err) => { throw new Error('Error') })
250 | .catch((err) => { console.error(err) })
251 | ```
252 |
253 | ## Orquestrando promises
254 |
255 | ### Promise.all()
256 |
257 | Se você precisar sincronizar diferentes promises, `Promise.all()`ajuda você a definir uma lista de promises e executar algo quando todas elas estão resolvidas.
258 |
259 | Exemplo:
260 |
261 | ```
262 | const f1 = fetch('/something.json')
263 | const f2 = fetch('/something2.json')
264 |
265 | Promise.all([f1, f2]).then((res) => {
266 | console.log('Array of results', res)
267 | })
268 | .catch((err) => {
269 | console.error(err)
270 | })
271 | ```
272 |
273 | A desestruturação do ES2015 permite que você faça também
274 |
275 | ```
276 | Promise.all([f1, f2]).then(([res1, res2]) => {
277 | console.log('Results', res1, res2)
278 | })
279 | ```
280 |
281 | ### Promise.race()
282 |
283 | `Promise.race()` é executado quando a primeira das promises passadas a ele é resolvida, e executa a callback anexada apenas uma vez, com o resultado daquela primeira promise resolvida.
284 |
285 | Exemplo:
286 |
287 | ```
288 | const first = new Promise((resolve, reject) => {
289 | setTimeout(resolve, 500, 'first')
290 | })
291 |
292 | const second = new Promise((resolve, reject) => {
293 | setTimeout(resolve, 100, 'second')
294 | })
295 |
296 | Promise.race([first, second]).then((result) => {
297 | console.log(result) // second
298 | })
299 | ```
300 |
301 | ## Erros comuns
302 |
303 | ### Uncaught TypeError: undefined is not a promise
304 |
305 | Se você receber `Uncaught TypeError: undefined is not a promise`no seu console, certifique-se de usar `new Promise()` ao invés de `Promise()`.
306 |
307 |
308 | ## async/await
309 |
310 | ### Descubra a abordagem moderna para funções assíncronas em JavaScript. O JavaScript evoluiu em um tempo muito curto, de callbacks a Promises, e desde a ES2017, a programação assíncrona em JavaScript se tornou ainda mais simples com o async/await.
311 |
312 | - Introdução
313 | - Por que async/await foi introduzido?
314 | - Como funciona
315 | - Um rápido exemplo
316 | - Promise para todas as coisas
317 | - O código é muito mais legível
318 | - Funções assíncronas em série
319 |
320 | ## Introdução
321 |
322 | As funções assíncronas são uma combinação de promises e generators e são basicamente uma abstração de nível superior sobre as promises. Deixe-me repetir: async/await é construído sobre promises.
323 |
324 | ## Por que async/await foi introduzido?
325 |
326 | Eles reduzem o clichê em torno das promises e a limitação "não quebre a corrente" no encadeamento de promises.
327 |
328 | Quando as Promises foram introduzidas no ES2015, elas tinham como objetivo resolver um problema com
329 | código assíncrono, e cosneguiram, mas nos 2 anos que separaram o ES2015 e o ES2017 ficou claro que as promises não poderiam ser a solução final.
330 |
331 | Promises foram introduzidas para resolver o famoso problema do callback hell, mas introduziram
332 | uma complexidade por conta própria, além de uma complexidade na sintaxe.
333 |
334 | Eles eram boas primitivas para oferecer uma sintaxe mais clara aos desenvolvedore,
335 | então, quando chegou a hora, obtivemos as funções assíncronas.
336 |
337 | Elas fazem o código parecer síncrono, mas atrás dos panos é assíncrono e sem bloqueios.
338 |
339 | ## Como funciona
340 |
341 | Uma função assíncrona retorna uma promise, como neste exemplo:
342 |
343 | ```
344 | const doSomethingAsync = () => {
345 | return new Promise((resolve) => {
346 | setTimeout(() => resolve('I did something'), 3000)
347 | })
348 | }
349 | ```
350 |
351 |
352 | Quando você desejar chamar esta função, acrescente o `await` e o código de chamada será interrompido até
353 | que a promise seja resolvida ou rejeitada. Uma ressalva: a função deve ser definida com o `async`. Aqui está um exemplo:
354 |
355 | ```
356 | const doSomething = async () => {
357 | console.log(await doSomethingAsync())
358 | }
359 | ```
360 |
361 | ## Um rápido exemplo
362 |
363 | Este é um exemplo simples do async/await sendo usado para executar uma função de forma assíncrona:
364 |
365 | ```
366 | const doSomethingAsync = () => {
367 | return new Promise((resolve) => {
368 | setTimeout(() => resolve('I did something'), 3000)
369 | })
370 | }
371 |
372 | const doSomething = async () => {
373 | console.log(await doSomethingAsync())
374 | }
375 |
376 | console.log('Before')
377 | doSomething()
378 | console.log('After')
379 | ```
380 |
381 | O código acima retornará o seguinte:
382 |
383 | ```
384 | Before
385 | After
386 | I did something //after 3s
387 | ```
388 |
389 | ## Promise para todas as coisas
390 |
391 | Anexar a palavra-chave `async` a qualquer função significa que a função retornará uma promise.
392 |
393 | Mesmo que não o faça explicitamente, fará com que ele retorne uma promise de forma interna.
394 |
395 | É por isso que este código é válido:
396 |
397 | ```
398 | const aFunction = async () => {
399 | return 'test'
400 | }
401 |
402 | aFunction().then(alert) // isso irá alertar o 'test'
403 | ```
404 |
405 | e é o mesmo que:
406 |
407 | ```
408 | const aFunction = async () => {
409 | return Promise.resolve('test')
410 | }
411 |
412 | aFunction().then(alert) // isso irá alertar o 'test'
413 | ```
414 |
415 | ## O código é mais legível
416 |
417 | Como você pode ver no exemplo acima, nosso código parece muito simples. Compare-o ao código usando
418 | apenas promises, com encadeamento e callbacks.
419 |
420 | E este é um exemplo muito simples, os principais benefícios surgirão quando o código for muito mais
421 | complexo.
422 |
423 | Por exemplo, veja como você obteria e analisaria um recurso JSON usando promises:
424 |
425 | ```
426 | const getFirstUserData = () => {
427 | return fetch('/users.json') // pega a lista de usuários
428 | .then(response => response.json()) // parse JSON
429 | .then(users => users[0]) // pega o primeiro usuários
430 | .then(user => fetch(`/users/${user.name}`)) // pega dados do usuário
431 | .then(userResponse => response.json()) // parse JSON
432 | }
433 |
434 | getFirstUserData()
435 | ```
436 |
437 | E aqui está a mesma funcionalidade fornecida usando `async/await`:
438 |
439 | ```
440 | const getFirstUserData = async () => {
441 | const response = await fetch('/users.json') //pega a lista de usuários
442 | const users = await response.json() // parse JSON
443 | const user = users[0] // pega o primeiro usuário
444 | const userResponse = await fetch(`/users/${user.name}`) // pega dados do usuário
445 | const userData = await user.json() // parse JSON
446 | return userData
447 | }
448 |
449 | getFirstUserData()
450 |
451 | ```
452 |
453 | ## Funções assíncronas em série
454 |
455 | As funções assíncronas podem ser encadeadas com muita facilidade, e a sintaxe é muito mais legível do que com
456 | promises simples:
457 |
458 | ```
459 | const promiseToDoSomething = () => {
460 | return new Promise(resolve => {
461 | setTimeout(() => resolve('Eu fiz algo'), 10000)
462 | })
463 | }
464 |
465 | const watchOverSomeoneDoingSomething = async () => {
466 | const something = await promiseToDoSomething()
467 | return something + 'e eu assisti'
468 | }
469 |
470 | const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
471 | const something = await watchOverSomeoneDoingSomething()
472 | return something + ' e eu assisti também'
473 | }
474 |
475 | watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => {
476 | console.log(res)
477 | })
478 | ```
479 |
480 | irá retornar:
481 |
482 | ```
483 | Eu fiz algo e eu assisti e eu assisti também
484 |
485 | ```
486 |
487 |
488 |
489 |
--------------------------------------------------------------------------------
/Capitulo_7.md:
--------------------------------------------------------------------------------
1 | NETWORKING
2 |
3 | ## HTTP
4 |
5 | - [HTTP](#http)
6 | - [Como as requisições HTTP funcionam](#http-requests)
7 | - [Construa um servidor HTTP](#http-server)
8 | - [Fazendo requisições HTTP](#http-requests)
9 | - [Axios](#axios)
10 | - [Websockets](#websockets)
11 | - [HTTPS, conexões seguras](#secure-connections)
12 |
13 | ## HTTP
14 |
15 | **Uma descrição detalhada de como funciona o protocolo HTTP e a Web.**
16 |
17 | O HTTP (Protocolo de Transfêrencia de Hipertexto) é um dos protocolos de aplicação do TCP/IP, o conjuto de protocolos que alimenta a Internet.
18 |
19 | Deixe me corrigir isso: Ele não é apenas um dos protocolos, ele é o mais bem sucedido e popular entre eles.
20 |
21 | HTTP é o que faz a "World Wide Web" funcionar, fornecendo aos navegadores uma linguagem para se comunicarem com os servidores remotos que hospedam as páginas da Web.
22 |
23 | O HTTP foi padronizado pela primeira vez em 1991, como resultado do trabalho que Tim Berners-Lee realizou no CERN, o Centro Europeu de Pesquisa Nuclear, criado em 1989.
24 |
25 | O objetivo era permitir que os pesquisadores trocassem e interligassem seus artigos com facilidade. Era um meio para a comunidade científica trabalhar melhor.
26 |
27 | Naquela época, as principais aplicações da Internet eram basicamente: FTP (Protocolo de Transferência de Arquivos), Email, e Usenet (Grupo de notícias, abandonado nos dias de hoje).
28 |
29 | Em 1993, Mosaic, o primeiro navegador gráfico da web, foi lançando e as coisas dispararam a partir daí.
30 |
31 | A Web se tornou a aplicação indispensável da Internet.
32 |
33 | Com o tempo, a Web e o ecossistema ao seu redor evoluíram dramaticamente, mas o básico ainda permanece. Um exemplo dessa evolução: O HTTP agora oferece, além de páginas da Web, APIs REST, um método comum de acessar programaticamente um serviço pela Internet.
34 |
35 | O HTTP sofreu uma pequena revisão em 1997 com o HTTP/1.1, e em 2015 seu sucessor, o HTTP/2, foi padronizado e agora está sendo implementado pelos principais servidores da Web usados em todo o mundo.
36 |
37 | O protocolo HTTP é considerado inseguro, como qualquer outro protocolo (SMTP, FTP...) não servido por uma conexão criptografada. É por isso que hoje em dia existe um grande empurrão no uso do HTTPS, que é um HTTP acrescentado por TLS.
38 |
39 | Dito isto, os blocos de construção do HTTP/2 e HTTPS têm suas raízes no HTTP e neste artigo vou apresentar como o HTTP funciona.
40 |
41 | ### Documentos HTML
42 |
43 | O HTTP é a maneira dos **navegadores da Web**, como Chrome, Firefox, Edge e muitos outros (daqui em diante chamados de clientes) se comunicarem com os **servidores da Web**.
44 |
45 | O nome Protocolo de Transferência de Hipertexto (HTTP) deriva da necessidade de transferir não apenas arquivos, como no FTP (Protocolo de Transferência de Arquivos), mas também hipertextos, que seriam escritos usando HTML, representados graficamente pelo navegador com uma boa apresentação e links interativos.
46 |
47 | Os links, juntamente com a facilidade de criação de novas páginas web, foram as principais causas que impulsionaram a adoção do protocolo.
48 |
49 | O HTTP é o que transfere esses arquivos de hipertexto (e, como veremos também, imagens e outros tipos de arquivos) pela rede.
50 |
51 | ### Hyperlinks
52 |
53 | Dentro do navegador Web, um documento pode apontar para outro documento usando links.
54 |
55 | Um link é composto por uma primeira parte que determina o protocolo e o endereço do servidor, através de um nome de domínio ou um IP.
56 |
57 | Está parte não é exclusiva do HTTP, é claro.
58 |
59 | Depois, há a parte do documento. Qualquer coisa anexada à parte do endereço representa o caminho do documento.
60 |
61 | Por exemplo, `https://flaviocopes.com/http/` o endereço deste documento é:
62 |
63 | - `https` é o protocolo.
64 | - `flaviocopes.com` é o nome de domínio que aponta para o meu servidor.
65 | - `http/` é a URL do documento que é relativo ao caminho da raiz do servidor.
66 |
67 | Outro exemplo de endereço: `https://flaviocopes.com/page/privacy/` e, neste caso, a URL do documento é `/page/privacy`.
68 |
69 | O servidor da Web é responsável por interpretar a requisição e, uma vez analisada, atender com a resposta correta.
70 |
71 | ### Uma requisição
72 |
73 | O que há em uma requisição?
74 |
75 | A primeira coisa é **a URL**, que já vimos antes.
76 |
77 | Quando inserimos um endereço e pressionamos enter em nosso navegador, por baixo dos panos, o servidor envia para o endereço IP correto uma requisição como esta:
78 |
79 | ```
80 | GET /a-page
81 | ```
82 |
83 | onde /a-page é o URL que você requisitou.
84 |
85 | A segunda coisa é `o método HTTP` (também chamado de verbo).
86 |
87 | Nos começo, o HTTP definiu três deles:
88 |
89 | - `GET`
90 | - `POST`
91 | - `HEAD`
92 |
93 | e o HTTP/1.1 introduziu:
94 |
95 | - `PUT`
96 | - `DELETE`
97 | - `OPTIONS`
98 | - `TRACE`
99 |
100 | Vamos vê-los em detalhes em um minuto.
101 |
102 | A terceira coisa que compõe uma requisição é um conjunto de **cabeçalhos HTTP**.
103 |
104 | Os cabeçalhos são um conjunto de pares chave:valor que são usados para se comunicar com as informações específicas predefinidas pelo servidor, para que ele possa saber o que queremos dizer.
105 |
106 | Eu os descrevi em detalhes na lista de cabeçalhos de requisição HTTP.
107 |
108 | Dê uma olhada rápida nessa lista. Todos esses cabeçalhos são opcionais, exceto `Host`.
109 |
110 | ### Métodos HTTP
111 |
112 | #### `GET`
113 |
114 | GET é o método mais usado aqui. É o que é usado quando você digita uma URL na barra de endereços do navegador ou quando você clica em um link.
115 |
116 | Ele pede ao servidor para enviar o recurso solicitado como resposta.
117 |
118 | #### `HEAD`
119 |
120 | HEAD é como o GET, mas ele diz ao servidor para não enviar o corpo da resposta de volta, apenas os cabeçalhos.
121 |
122 | #### `POST`
123 |
124 | O cliente usa o método POST para enviar dados para o servidor. Normalmente é usado em formulários, mas também é usando ao interagir com uma API REST.
125 |
126 | #### `PUT`
127 |
128 | O método PUT visa criar um recurso nessa URL específica, com os parâmetros passados no corpo da requisição. Principalmente usado em APIs REST.
129 |
130 | #### `DELETE`
131 |
132 | O método DELETE é chamado em uma URL para solicitar a exclusão desse recurso. Principalmente usado em APIs REST.
133 |
134 | #### `OPTIONS`
135 |
136 | Quando um servidor recebe uma requisição OPTIONS, ele deve enviar de volta a lista de métodos HTTP permitidos para esse URL específico.
137 |
138 | #### `TRACE`
139 |
140 | Retorna ao cliente a requisição que foi recebida. Usado para fins de diagnóstico por debug.
141 |
142 | ### Comunicação Cliente/Servidor HTTP
143 |
144 | O HTTP, como a maioria dos protocolos que pertencem ao conjunto TCP/IP, é um protocolo sem estado.
145 |
146 | Servidores não têm ideia de qual é o estado atual do cliente. Tudo o que eles se importam é em receber a requisição e atender isso.
147 |
148 | Qualquer requisição anterior não faz sentido nesse contexto, isso possibilita que um servidor da Web seja muito mais rápido, pois há menos para processar e oferecendo largura de banda para lidar com muitas solicitações simultâneas.
149 |
150 | O HTTP também é muito enxuto e a comunicação, em termos gerais, é muito rápida. Isso contrasta com os protocolos mais usados no momento em que o HTTP foi introduzido: TCP, POP/SMTP e os protocolos de correio, que envolvem muitos `handshaking` e confirmações de recebimento.
151 |
152 | Os navegadores gráficos abstraem toda essa comunicação, mas a ilustraremos aqui para fins de aprendizado.
153 |
154 | Uma mensagem é composta por uma primeira linha, que começa com o método HTTP, depois contém o caminho relativo do recurso e a versão do protocolo:
155 |
156 | `GET /a-page HTTP/1.1`
157 |
158 | Depois disso, precisamos adicionar cabeçalhos de requisição HTTP. Como mencionado acima, existem muitos cabeçalhos, mas o único obrigatório é o `Host`
159 |
160 | ```
161 | GET /a-page HTTP/1.1
162 | Host: flaviocopes.com
163 | ```
164 |
165 | Como você pode testar isso ? Usando **Telnet**. Esta é uma ferramenta de linha de comando que nos permite conectar-se a qualquer servidor e enviar-lhe comandos.
166 |
167 | Abra seu terminal e digite `telnet flaviocopes.com 80`
168 |
169 | Isto irá abrir um terminal, que informará:
170 |
171 | ```
172 | Trying 178.128.202.129...
173 | Connected to flaviocopes.com.
174 | Escape character is '^]'.
175 | ```
176 |
177 | Você está conectado ao servidor Netlify que alimenta meu blog. Agora você pode digitar:
178 |
179 |
180 | ```
181 | GET /axios/ HTTP/1.1
182 | Host: flaviocopes.com
183 | ```
184 |
185 | e apertar enter em um linha vazia para disparar a requisição.
186 |
187 | A resposta será:
188 |
189 | ```
190 | HTTP/1.1 301 Moved Permanently
191 | Cache-Control: public, max-age=0, must-revalidate
192 | Content-Length: 46
193 | Content-Type: text/plain
194 | Date: Sun, 29 Jul 2018 14:07:07 GMT
195 | Location: https://flaviocopes.com/axios/
196 | Age: 0
197 | Connection: keep-alive
198 | Server: Netlify
199 |
200 | Redirecting to https://flaviocopes.com/axios/
201 | ```
202 |
203 | Veja, está é uma resposta HTTP que recebemos do servidor. É uma requisição 301 movida permanentemente. Consulte a lista de códigos de status HTTP para saber mais sobre os códigos de status.
204 |
205 | Ela basicamente nos diz que o recurso foi movido permanentemente para outro local.
206 |
207 | Por quê? Porque nos conectamos à porta 80, que é o padrão para o HTTP, mas no meu servidor eu configurei um redirecionamento automático para HTTPS.
208 |
209 | O novo local é especificado no `Location` dentro do cabeçalho de resposta HTTP.
210 |
211 | Existem outros cabeçalhos, todos descritos na lista de cabeçalhos de resposta HTTP.
212 |
213 | Tanto na requisição quanto na resposta, uma linha vazia separa o cabeçalho de requisição do corpo da requisição. Neste caso, o corpo da requisição contém a string:
214 |
215 | `Redirecting to https://flaviocopes.com/axios/`
216 |
217 | Com o tamanho de 46 bytes de comprimento, conforme especificado no cabeçalho `Content-Length`. Isto é mostrado no
218 | navegador quando você abre a página, enquanto ele automaticamente redireciona você para a localização correta.
219 |
220 | Nesse caso, estamos usando o `telnet`, a ferramenta de baixo nível que podemos usar para conectar-se a qualquer servidor, portanto não teremos nenhum tipo de redirecionamento automático.
221 |
222 | Vamos fazer esse processo novamente, agora conectando à porta 443, que é a porta padrão do protocolo HTTPS. Não podemos usar o `telnet` por causa do `handshaking` SSL que deve acontecer.
223 |
224 | Vamos simplificar as coisas e usar `curl`, outra ferramenta de linha de comando. Não podemos digitar diretamente a requisição HTTP, mas vamos ver a resposta:
225 |
226 | `curl -i https://flaviocopes.com/axios/`
227 |
228 | é isso que receberemos em de volta:
229 |
230 | ```
231 | HTTP/1.1 200 OK
232 | Cache-Control: public, max-age=0, must-revalidate
233 | Content-Type: text/html; charset=UTF-8
234 | Date: Sun, 29 Jul 2018 14:20:45 GMT
235 | Etag: "de3153d6eacef2299964de09db154b32-ssl"
236 | Strict-Transport-Security: max-age=31536000
237 | Age: 152
238 | Content-Length: 9797
239 | Connection: keep-alive
240 | Server: Netlify
241 |
242 |
243 |
244 |
245 |
246 |
247 | HTTP requests using Axios
248 | ....
249 | ```
250 |
251 | Eu cortei a resposta, mas você pode ver que o HTML da página está sendo retornado agora.
252 |
253 | ### Outros recursos
254 |
255 | Um servidor HTTP não transfere somente arquivos HTML, transfere também muitos outros tipos diferentes de arquivos, como CSS, JS, SVG, PNG, JPG.
256 |
257 | Isso depende da configuração.
258 |
259 | O HTTP também é perfeitamente capaz de transferir esses arquivos, deixando o cliente informado sobre o tipo de arquivo, para que ele interprete-os da maneira correta.
260 |
261 | É assim que a Web funciona: quando uma página HTML é recuperada pelo navegador, ela é interpretada e qualquer outro recurso necessário para exibir as propriedades (CSS, JavaScript, imagens, ...), são recuperados por meio de requisições HTTP adicionais para o mesmo servidor.
262 |
263 | ## Como as requisições HTTP funcionam
264 |
265 | **O que acontece quando você digita uma URL no navegador, do início ao fim**
266 |
267 | - [O protocolo HTTP](#http-protocol)
268 | - [Eu analiso apenas requisições de URL](#url-requests)
269 | - [Estamos nos referindo ao macOS/Linux](#things-relate)
270 | - [Fase de pesquisa do DNS](#dns-lookup)
271 | - [gethostbyname](#gethostbyname)
272 | - [Handshaking de requisição TCP](#tcp-request-handshaking)
273 | - [Enviando a requisição](#sending-the-request)
274 | - [A linha da requisição](#request-line)
275 | - [O cabeçalho da requisição](#request-header)
276 | - [O corpo da requisição](#request-body)
277 | - [A resposta](#the-response)
278 | - [Analisar o HTML](#parse-html)
279 |
280 | > Este artigo descreve como os navegadores executam requisições usando o protocolo HTTP/1.1
281 |
282 | Se você já fez uma entrevista, pode ter sido perguntado: "o que acontece quando você digita algo na caixa de pesquisa do Google e pressiona enter".
283 |
284 | Ela é uma das perguntas mais populares. As pessoas só querem ver se você consegue explicar alguns conceitos básicos e se você tem alguma ideia de como a Internet realmente funciona.
285 |
286 | Nesta postagem, analisarei o que acontece quando você digita uma URL na barra de endereços do seu navegador e pressiona enter.
287 |
288 | É um tópico muito interessante de ser dissecado em uma postagem de blog, pois toca em muitas tecnologias nas quais posso mergulhar em postagens separadas.
289 |
290 | Essa é uma tecnologia que raramente é alterada e alimenta um dos ecossistemas mais complexos e amplos já construídos por seres humanos.
291 |
292 | ### O protocolo HTTP
293 |
294 | Primeiro, eu menciono o HTTPS em particular, porque as coisas são diferentes de uma conexão HTTPS.
295 |
296 | ### Eu analiso somente requisições da URL
297 |
298 | Os navegadores modernos tem a capacidade de saber se o que você escreveu na barra de endereço é uma URL real ou um termo de pesquisa e usarão o mecanismo de pesquisa padrão se não for uma URL válida.
299 |
300 | Suponho que você digite um URL real.
301 |
302 | Quando você insere o URL e pressiona enter, o navegador primeiro cria o URL completo.
303 |
304 | Se você acabou de inserir um domínio, como `flaviocopes.com`, o navegador por padrão irá adicionar `HTTP://` a ele, padronizando com protocolo HTTP.
305 |
306 | ### Estamos nos referindo ao macOS/Linux
307 |
308 | Apenas para sua informação. O Windows pode fazer algumas coisas de maneira ligeiramente diferente.
309 |
310 | ### Fase de pesquisa do DNS
311 |
312 | O navegador inicia a pesquisa de DNS para obter o endereço IP do servidor.
313 |
314 | O nome de domínio é um atalho útil para nós, humanos, mas a Internet está organizada de tal maneira que os computadores podem procurar a localização exata de um servidor através do seu endereço IP, que é um conjunto de números como o `222.324.3.1` (IPv4).
315 |
316 | Primeiro, ele verifica o cache local do DNS para ver se o domínio já foi consultado recentemente.
317 |
318 | O Chrome possui um prático visualizador de cache DNS, que você pode ver em `chrome://net-internals/#dns`
319 |
320 | Se nada for encontrado lá, o navegador usará o resolvedor de DNS, usando a chamada de sistema `gethostbyname` POSIX para recuperar as informações do host.
321 |
322 | #### gethostbyname
323 |
324 | O `gethostbyname` procura primeiro o arquivo de hosts local, que no macOS ou Linux está localizado em `/etc/hosts`, para verificar se o sistema fornece as informações localmente.
325 |
326 | Se ele não fornecer nenhuma informação sobre o domínio, o sistema fará uma requisição ao servidor DNS.
327 |
328 | O endereço do servidor DNS é armazenado nas preferências do sistema.
329 |
330 | Esses são 2 servidores DNS populares:
331 |
332 | - `8.8.8.8`: o servidor DNS público do Google
333 |
334 | - `1.1.1.1`: o servidor DNS do CloudFlare
335 |
336 | A maioria das pessoas usa o servidor DNS fornecido pelo provedor da Internet.
337 |
338 | O navegador executa a requisição DNS usando o protocolo UDP.
339 |
340 | TCP e UDP são dois dos protocolos fundamentais da rede de computadores. Eles ficam no mesmo nível conceitual, mas o TCP é orientado à conexão, enquanto o UDP é um protocolo sem conexão, mais leve, usado para enviar mensagens com pouca sobrecarga.
341 |
342 | >Como a requisição UDP é realizada não está no escopo deste tutorial
343 |
344 | O servidor DNS pode ter o IP do domínio na cache. Caso contrário, ele solicitará ao servidor DNS raiz. Esse é um sistema (composto por 13 servidores reais, distribuídos em todo o planeta) que impulsiona toda a Internet.
345 |
346 | O servidor DNS não sabe o endereço de todo e qualquer nome de domínio no planeta.
347 |
348 | O que ele sabe é onde estão os resolvedores de DNS de nível superior.
349 |
350 | Um domínio de nível superior é a extensão do domínio: `.com`, `.it`, `.pizza` e assim por diante.
351 |
352 | Depois que o servidor DNS raiz recebe a requisição, ele a encaminha para o servidor DNS de domínio de nível superior (`TLD`).
353 |
354 | Digamos que você esteja procurando por `flaviocopes.com`. O servidor DNS do domínio raiz retorna o IP do servidor TLD `.com`.
355 |
356 | Agora, nosso resolvedor de DNS armazenará em cache o IP desse servidor de TLD, para que ele não precise solicitar novamente o servidor DNS raiz.
357 |
358 | O servidor DNS do TLD terá os endereços IP dos Servidores de Nome com autoridade para o domínio que estamos procurando.
359 |
360 | >Como? Quando você compra um domínio, o registrador de domínios envia os servidores TDL apropriados para o mesmo nome. Quando você atualiza os servidores de nomes (por exemplo, quando altera o provedor de hospedagem), essas informações são atualizadas automaticamente pelo seu registrador de domínio.
361 |
362 | Esses são os servidores DNS do provedor de hospedagem. Eles geralmente são mais de 1, para servir como backup.
363 |
364 | Por exemplo:
365 |
366 | - `ns1.dreamhost.com`
367 | - `ns2.dreamhost.com`
368 | - `ns3.dreamhost.com`
369 |
370 | O resolvedor de DNS começa com o primeiro e tenta solicitar o IP do domínio (com o subdomínio) que você está procurando.
371 |
372 | Essa é a melhor fonte de verdade para o endereço de IP.
373 |
374 | Agora que temos o endereço IP, podemos continuar nossa jornada.
375 |
376 | ### Handshaking de requisição TCP
377 |
378 | Com o endereço de IP do servidor disponível, agora o navegador pode iniciar uma conexão TCP.
379 |
380 | Uma conexão TCP requer um pouco de `handshaking` antes de poder ser totalmente inicializada e você comece a enviar dados.
381 |
382 | Depois que a conexão for estabelecida, podemos enviar a requisição.
383 |
384 | ### Enviando a requisição
385 |
386 | A requisição é um documento de texto simples, estruturado de maneira precisa, determinada pelo protocolo de comunicação.
387 |
388 | É composto por 3 partes:
389 |
390 | - O linha da requisição
391 | - O cabeçalho da requisição
392 | - O corpo da requisição
393 |
394 | #### A linha da requisição
395 |
396 | A linha de requisição define, em uma única linha:
397 |
398 | - O método HTTP
399 | - A localização do recurso
400 | - A versão do protocolo
401 |
402 | Exemplo:
403 |
404 | `GET /HTTP/1.1`
405 |
406 | #### O cabeçalho da requisição
407 |
408 | O cabeçalho da requisição é um conjunto de pares `campo:valor` que definem determinados valores.
409 |
410 | Existem 2 campos obrigatórios, um deles é o `Host` e o outro é o `Connection`, todos os outros campos são opcionais:
411 |
412 | ```
413 | Host: flaviocopes.com
414 | Connection: close
415 | ```
416 |
417 | `Host` indica o nome do domínio que queremos atingir, enquanto `Connection` é sempre definido como `close`, a menos que a conexão precise ser mantida aberta.
418 |
419 | Alguns dos campos de cabeçalho mais usados são:
420 |
421 | - `Origin`
422 | - `Accept`
423 | - `Accept-Encoding`
424 | - `Cookie`
425 | - `Cache-Control`
426 | - `Dnt`
427 |
428 | mas existem muitos outros.
429 |
430 | A parte do cabeçalho é finalizada por uma linha em branco.
431 |
432 | #### O corpo da requisição
433 |
434 | O corpo da requisição é opcional, não usado em requisições GET, mas muito usado em requisições POST e, as vezes, em outros verbos também. Ele pode conter dados no formato JSON.
435 |
436 | Como agora estamos analisando uma requisição GET, o corpo está em branco e não o examinaremos mais.
437 |
438 | ### A resposta
439 |
440 | Depois que a requisição é enviada, o servidor a processa e manda de volta uma resposta.
441 |
442 | A resposta começa com o código de status e a mensagem de status. Se a requisição for bem-sucedida e retornar um 200, ela começará com:
443 |
444 | `200 OK`
445 |
446 | A requisição pode retornar um código de status diferente e uma mensagem, como uma dessas:
447 |
448 | ```
449 | 404 Not Found
450 | 403 Forbidden
451 | 301 Moved Permanently
452 | 500 Internal Server Error
453 | 304 Not Modified
454 | 401 Unauthorized
455 | ```
456 |
457 | Então, A resposta contém uma lista de cabeçalhos HTTP e o corpo da resposta (que, como estamos fazendo a solicitação no navegador, será HTML).
458 |
459 | ### Analisar o HTML
460 |
461 | O navegador agora recebeu o HTML e começa a analisá-lo. Ele repetirá exatamente o mesmo processo que fizemos para todos os recursos exigidos pela página:
462 |
463 | - Arquivos CSS
464 | - Imagens
465 | - O favicon
466 | - Arquivos JavaScript
467 | - ...
468 |
469 | Como os navegadores renderizam a página, ela está fora do escopo, é importante entender que o processo que descrevi não é apenas para as páginas HTML, mas para qualquer item veiculado por HTTP.
470 |
471 | ## Construindo um servidor HTTP
472 |
473 | **Como criar um servidor HTTP com Node.js**
474 |
475 | Aqui está o servidor da Web que usamos como uma aplicação Node "Olá Mundo" na [introdução do Node.js](https://flaviocopes.com/nodejs/)
476 |
477 | ```
478 | const http = require('http')
479 |
480 | const port = 3000
481 |
482 | const server = http.createServer((req, res) => {
483 | res.statusCode = 200
484 | res.setHeader('Content-Type', 'text/plain')
485 | res.end('Hello World\n')
486 | })
487 |
488 | server.listen(port, () => {
489 | console.log(`Server running at http://${hostname}:${port}/`)
490 | })
491 | ```
492 |
493 | Vamos analisar brevemente. Nós incluímos o [módulo `http`](https://nodejs.org/api/http.html).
494 |
495 | Usamos o módulo para criar um servidor HTTP.
496 |
497 | O servidor está configurado para escutar na porta especificada, `3000`. Quando o servidor está pronto, a função callback (de retorno de chamada) `listen` é chamada.
498 |
499 |
500 | A função callback que passamos é aquela que será executada a cada requisição recebida. Sempre que uma nova requisição é recebida o evento [`requisição`](https://nodejs.org/api/http.html#http_event_request) é chamado, fornecendo dois objetos: uma requisição (um objeto [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)) e uma resposta (um [http.ServerResponseobject](https://nodejs.org/api/http.html#http_class_http_serverresponse)).
501 |
502 | O `request` fornece os detalhes da requisição. Por meio dele, acessamos os cabeçalhos e os dados da requisição.
503 |
504 | O `response` é usado para preencher os dados que retornaremos ao cliente.
505 |
506 | Neste caso com:
507 |
508 | `res.statusCode = 200`
509 |
510 | definimos a propriedade statusCode como 200, para indicar uma resposta bem sucedida.
511 |
512 | Também definimos o cabeçalho Content-Type:
513 |
514 | `res.setHeader('Content-Type', 'text/plain')`
515 |
516 | e finalizamos a resposta, adicionando o conteúdo como argumento a `end()`:
517 |
518 | `res.end('Hello World\n')`
519 |
520 | ## Fazendo requisições HTTP
521 |
522 | **Como executar requisições HTTP com Node.js usando GET, POST, PUT e DELETE**
523 |
524 | >Eu uso o termo HTTP, mas HTTPS é o que deve ser usado em todos os lugares, portanto, esses exemplos usam HTTPS em vez de HTTP.
525 |
526 | ### Fazer uma requisição GET
527 |
528 | ```
529 | const https = require('https')
530 |
531 | const options = {
532 | hostname: 'flaviocopes.com',
533 | port: 443,
534 | path: '/todos',
535 | method: 'GET'
536 | }
537 |
538 | const req = https.request(options, (res) => {
539 | console.log(`statusCode: ${res.statusCode}`)
540 |
541 | res.on('data', (d) => {
542 | process.stdout.write(d)
543 | })
544 | })
545 |
546 | req.on('error', (error) => {
547 | console.error(error)
548 | })
549 |
550 | req.end()
551 | ```
552 |
553 | ### Fazer uma requisição POST
554 |
555 | ```
556 | const https = require('https')
557 |
558 | const data = JSON.stringify({
559 | todo: 'Buy the milk'
560 | })
561 |
562 | const options = {
563 | hostname: 'flaviocopes.com',
564 | port: 443,
565 | path: '/todos',
566 | method: 'POST',
567 | headers: {
568 | 'Content-Type': 'application/json',
569 | 'Content-Length': data.length
570 | }
571 | }
572 |
573 | const req = https.request(options, (res) => {
574 | console.log(`statusCode: ${res.statusCode}`)
575 |
576 | res.on('data', (d) => {
577 | process.stdout.write(d)
578 | })
579 | })
580 |
581 | req.on('error', (error) => {
582 | console.error(error)
583 | })
584 |
585 | req.write(data)
586 | req.end()
587 | ```
588 |
589 | ### PUT e DELETE
590 |
591 | Requisições PUT e DELETE usam o mesmo formato da requisição POST e apenas alteram o valor `options.method`.
592 |
593 | ## Axios
594 |
595 | **O Axios é uma biblioteca JavaScript muito conveniente para executar requisições HTTP no Node.js**
596 |
597 | - [Introdução](introduction-axios)
598 | - [Instalação](installation-axios)
599 | - [A API do Axios](axios-api)
600 | - [Requisições GET](axios-get)
601 | - [Adicionar parâmetros as requisições GET](axios-parameters)
602 | - [Requisições POST](axios-post)
603 |
604 | ### Introdução
605 |
606 | O Axios é uma biblioteca JavaScript muito popular que você pode usar para executar requisições HTTP, que funciona nas duas plataformas Browser e [Node.js](https://flaviocopes.com/nodejs/).
607 |
608 | 
609 |
610 | Ele suporta todos os navegadores modernos, incluindo o suporte para o IE8 e superior.
611 |
612 | É baseado em `Promises`, isso permite escrever código async/await para executar requisições [XHR](https://flaviocopes.com/xhr/) com muita facilidade.
613 |
614 | O uso do Axios possui algumas vantagens sobre o [Fetch API](https://flaviocopes.com/fetch-api/) nativo:
615 |
616 | - suporta navegadores mais antigos (Fetch precisa de um polyfill)
617 | - tem uma maneira de abortar uma solicitação
618 | - tem uma maneira de definir um tempo limite de resposta
619 | - possui proteção CSRF integrada
620 | - suporta o progresso do upload
621 | - executa transformação automática de dados JSON
622 | - funciona no Node.js
623 |
624 | ### Instalação
625 |
626 | Axios pode ser instalado usando [npm](https://flaviocopes.com/npm/):
627 |
628 | `npm install axios`
629 |
630 | ou [yarn](https://flaviocopes.com/yarn/):
631 |
632 | `yarn add axios`
633 |
634 | ou simplesmente adicionando na sua página usando unpkg.com:
635 |
636 | ``
637 |
638 | ### A API do Axios
639 |
640 | Você pode iniciar uma requisição HTTP a partir do objeto `axios`:
641 |
642 | ```
643 | axios({
644 | url: 'https://dog.ceo/api/breeds/list/all',
645 | method: 'get',
646 | data: {
647 | foo: 'bar'
648 | }
649 | })
650 | ```
651 |
652 | mas por conveniência, você geralmente usará:
653 |
654 | - `axios.get()`
655 | - `axios.post()`
656 |
657 | (como no jQuery, você usaria `$.get()` e `$.post()` em vez de `$.ajax()`)
658 |
659 | O Axios oferece métodos para todos os verbos HTTP, que apesar de menos populares, ainda são usados:
660 |
661 | - `axios.delete()`
662 | - `axios.put()`
663 | - `axios.patch()`
664 | - `axios.options()`
665 |
666 | e um método para obter os cabeçalhos HTTP de uma requisição, descartando o corpo:
667 |
668 | - `axios.head()`
669 |
670 | ### Requisições GET
671 |
672 | Uma maneira conveniente de usar o Axios é usar a sintaxe async/await moderna (ES2017).
673 |
674 | Esta é um exemplo de consulta em Node.js a [Dog API](https://dog.ceo/) para recuperar uma lista de todas as raças de cães usando `axios.get()`, contando as raças.
675 |
676 | ```
677 | const axios = require('axios')
678 |
679 | const getBreeds = async () => {
680 | try {
681 | returnawait axios.get('https://dog.ceo/api/breeds/list/all')
682 | } catch (error) {
683 | console.error(error)
684 | }
685 | }
686 |
687 | const countBreeds = async () => {
688 | const breeds = await getBreeds()
689 |
690 | if (breeds.data.message) {
691 | console.log(`Got ${Object.entries(breeds.data.message).length} breeds`)
692 | }
693 | }
694 |
695 | countBreeds()
696 | ```
697 |
698 | Se você não quiser usar async/await, você pode usar a sintaxe de [Promises](https://flaviocopes.com/javascript-promises/):
699 |
700 | ```
701 | const axios = require('axios')
702 |
703 | const getBreeds = () => {
704 | try {
705 | return axios.get('https://dog.ceo/api/breeds/list/all')
706 | } catch (error) {
707 | console.error(error)
708 | }
709 | }
710 |
711 | const countBreeds = async () => {
712 | const breeds = getBreeds()
713 | .then(response => {
714 | if (response.data.message) {
715 | console.log(
716 | `Got ${Object.entries(response.data.message).length} breeds`
717 | )
718 | }
719 | })
720 | .catch(error => {
721 | console.log(error)
722 | })
723 | }
724 |
725 | countBreeds()
726 |
727 | ```
728 |
729 | ### Adicionar parâmetros as requisições GET
730 |
731 | Uma requisição GET pode conter parâmetros na URL, assim: `https://site.com/?foo=bar`.
732 |
733 | Com o Axios, você pode fazer isso simplesmente usando esse URL:
734 |
735 | `axios.get('https://site.com/?foo=bar')`
736 |
737 | ou você pode usar uma propriedade `params` nas opções:
738 |
739 | ```
740 | axios.get('https://site.com/', {
741 | params: {
742 | foo: 'bar'
743 | }
744 | })
745 | ```
746 |
747 | ### Requisições POST
748 |
749 | Executar uma requisição POST é como fazer uma requisição GET, mas em vez de `axios.get`, você usa `axios.post`:
750 |
751 | `axios.post('https://site.com/')`
752 |
753 | Um objeto contendo os parâmetros POST e um segundo argumento:
754 |
755 | ```
756 | axios.post('https://site.com/', {
757 | foo: 'bar'
758 | })
759 | ```
760 |
761 | ## Websockets
762 |
763 | **Os WebSockets são uma alternativa à comunicação HTTP em aplicações Web. Eles oferecem um canal de comunicação bidirecional de longa duração entre cliente e servidor**
764 |
765 | WebSockets são uma alternativa a comunicação HTTP em aplicações Web.
766 |
767 | Eles oferecem um canal de comunicação bidirecional de longa duração entre cliente e servidor.
768 |
769 | Uma vez estabelecido, o canal é mantido aberto, oferecendo uma conexão muito rápida com baixa latência e sobrecarga.
770 |
771 | ### Suporte do navegador para WebSockets
772 |
773 | Os WebSockets são suportados por todos os navegadores modernos.
774 |
775 | 
776 |
777 | ### Como os WebSockets diferem do HTTP
778 |
779 | O HTTP é um protocolo muito diferente e uma maneira diferente de se comunicar.
780 |
781 | Ele é um protocolo de requisição/resposta: o servidor retorna alguns dados quando o cliente solicita.
782 |
783 | Diferenças do WebSocket para o HTTP:
784 |
785 | - o servidor pode enviar uma mensagem sem que o cliente solicite algo explicitamente
786 | - o cliente e o servidor podem conversar simultaneamente
787 | - pouquíssima sobrecarga de dados precisa ser trocado para enviar mensagens. Isso significa uma comunicação de baixa latência.
788 |
789 | Os WebSockets são ótimos para comunicações em tempo real e de longa duração.
790 |
791 | O HTTP é ótimo para trocas ocasionais de dados e interações iniciadas pelo cliente.
792 |
793 | O HTTP é muito mais simples de implementar, enquanto WebSockets exigem um pouco mais de estrutura.
794 |
795 | ### WebSockets seguros
796 |
797 | Sempre use o protocolo seguro e criptografado para WebSockets, `wss://`.
798 |
799 | `ws://` refere-se à versão insegura do WebSockets (o `http://` do WebSockets) e deve ser desviada por razões óbvias.
800 |
801 | ### Criar uma nova conexão WebSockets
802 |
803 | ```
804 | const url = 'wss://myserver.com/something'
805 | const connection = new WebSocket(url)
806 | ```
807 |
808 | `connection` é um objeto [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket).
809 |
810 | Quando a conexão é estabelecida com sucesso, o evento `open` é acionado.
811 |
812 | Para ouvi-lo é necessário atribuir uma função callback à propriedade `onopen` do objeto ` connection`:
813 |
814 | ```
815 | connection.onopen = () => {
816 | //...
817 | }
818 | ```
819 | Se houver algum erro, a função callback `onerror` é acionada:
820 |
821 | ```
822 | connection.onerror = error => {
823 | console.log(`WebSocket error: ${error}`)
824 | }
825 | ```
826 |
827 | ### Enviando dados para o servidor usando WebSockets
828 |
829 | Quando a conexão estiver aberta, você poderá enviar dados para o servidor.
830 |
831 | Você pode fazer isso convenientemente dentro da função callback `onopen`:
832 |
833 | ```
834 | connection.onopen = () => {
835 | connection.send('hey')
836 | }
837 | ```
838 |
839 | ### Recebendo dados do servidor usando WebSockets
840 |
841 | Ouça com uma função callback `onmessage`, que é chamado quando o evento da mensagem é recebido:
842 |
843 | ```
844 | connection.onmessage = e => {
845 | console.log(e.data)
846 | }
847 | ```
848 |
849 | ### Implementar um servidor WebSockes no Node.js
850 |
851 | [ws](https://github.com/websockets/ws) é uma biblioteca popular de WebSockets para [Node.js](https://flaviocopes.com/nodejs).
852 |
853 | Vamos usá-lo para criar um servidor WebSockets. Também pode ser usado para implementar um cliente e usar WebSockets para se comunicar entre dois serviços de back-end.
854 |
855 | Instale-o facilmente usando:
856 |
857 | ```
858 | yarn init
859 | yarn add ws
860 | ```
861 |
862 | O código que você precisa escrever é muito pequeno:
863 |
864 | ```
865 | const WebSocket = require('ws')
866 |
867 | const wss = new WebSocket.Server({ port: 8080 })
868 |
869 | wss.on('connection', ws => {
870 | ws.on('message', message => {
871 | console.log(`Received message => ${message}`)
872 | })
873 | ws.send('ho!')
874 | })
875 | ```
876 |
877 | Este código cria um novo servidor na porta 8080 (a porta padrão do WebSockets) e adiciona uma função callback quando uma conexão é estabelecida, enviando `ho!` para o cliente e registrando as mensagens que recebe.
878 |
879 | ### Veja um exemplo ao vivo no Glitch
880 |
881 | Aqui está um exemplo ao vivo de um servidor WebSockets: [https://glitch.com/edit/#!/flavio-websockets-server-example](https://glitch.com/edit/#!/flavio-websockets-server-example)
882 |
883 | Aqui está um cliente WebSockets que interage com o servidor: [https://glitch.com/edit/#!/flavio-websockets-client-example](https://glitch.com/edit/#!/flavio-websockets-client-example])
884 |
885 | ## HTTPS, conexões seguras
886 |
887 | **O protocolo HTTPS é uma extensão do HTTP, o Protocolo de Transferência de Hypertexto, que fornece uma comunicação segura**
888 |
889 | O HTTP é inseguro por design.
890 |
891 | Quando você abre o navegador e solicita que um servidor envie uma página da Web, seus dados realizam duas viagens: uma do navegador para o servidor da Web e a outra do servidor da Web para o navegador.
892 |
893 | Então, dependendo do conteúdo da página da Web, você pode precisar de mais conexões necessárias para obter os arquivos CSS, JavaScript, imagens e assim por diante.
894 |
895 | Durante qualquer uma dessas conexões, qualquer rede que seus dados estão passando podem ser **inspecionadas** e **manipuladas**.
896 |
897 | As consequências podem ser graves: você pode ter todas as suas atividades de rede monitoradas e registradas. Em uma terceira parte, você nem sabe que elas existem, algumas redes [podem injetar anúncios](https://justinsomnia.org/2012/04/hotel-wifi-javascript-injection/) e você pode estar sujeito a um ataque intermediário, uma ameaça à segurança na qual o invasor pode manipular seus dados e até mesmo se passar por seu computador na rede. É muito fácil alguém ouvir apenas pacotes HTTP sendo transmitidos por uma rede Wi-Fi pública e não criptografada.
898 |
899 | O HTTPS visa solucionar o problema na raiz: toda a comunicação entre o navegador e o servidor da Web é criptografada.
900 |
901 | Privacidade e segurança são uma das principais preocupações da Internet de hoje. Alguns anos atrás, você poderia fugir usando apenas uma conexão criptografada em páginas protegidas, ou durante um checkout de um E-Commerce. Pelo alto custo e dificuldades do certificado SSL, a maioria dos sites apenas usava HTTP.
902 |
903 | Hoje, o HTTPS é um requisito em qualquer site. Mais de 50% de toda a Web o usa agora. O Google Chrome começou recentemente a marcar sites HTTP como inseguros, apenas para fornecer uma razão válida para que o HTTPS seja obrigatório (e forçado) em todos os seus sites.
904 |
905 | Ao usar HTTP, a porta padrão do servidor é 80, no HTTPS é 443. Não é necessário adicionar de forma explicita se o servidor usa a porta padrão, é claro.
906 |
907 | Às vezes, o HTTPS também é chamado de HTTP com SSL ou HTTP com TLS.
908 |
909 | A diferença entre os dois é simples: TLS é o sucessor do SSL.
910 |
911 | Ao usar HTTPS, as únicas coisas que não são criptografadas são o domínio do servidor da web e a porta do servidor.
912 |
913 | Todas as outras informações, incluindo o caminho do recurso, cabeçalhos, cookies e parâmetros de consulta, são criptografadas.
914 |
915 | Não analisarei em detalhes como o protocolo TLS funciona por baixo dos panos, mas se você pensar que está sendo colocado uma boa quantidade adicional de dados, você estaria certo.
916 |
917 | Qualquer cálculo adicionado ao processamento de recursos de rede causa sobrecarga no cliente, no servidor e no tamanho dos pacotes transmitidos.
918 |
919 | Entretanto, o HTTPS permite o uso do mais novo protocolo **HTTP/2**, que possui uma vantagem enorme sobre o HTTP/1.1: é muito mais rápido.
920 |
921 | Por quê? Há muitas razões, uma é a compactação de cabeçalho, a outra é a multiplexação de recursos. Um deles é o envio pelo servidor: o servidor pode enviar mais recursos quando um recurso é solicitado. Portanto, se o navegador solicita uma página, ele também receberá todos os recursos necessários (imagens, CSS, JS).
922 |
923 | Detalhes à parte, o HTTP/2 é uma grande melhoria em relação ao HTTP/1.1 **e requer HTTPS**. Isso significa que o HTTPS, apesar de ter a sobrecarga de criptografia, é muito mais rápido que o HTTP, caso as coisas estejam configuradas corretamente e com uma instalação moderna.
924 |
925 |
--------------------------------------------------------------------------------
/Capitulo_8.md:
--------------------------------------------------------------------------------
1 | FYLE SYSTEM
2 |
3 | ## Descritores de arquivo
4 |
5 | ### Como interagir com descritores de arquivo usando o Node
6 |
7 | Antes de poder interagir com um arquivo que fica no seu sistema de arquivos, você deve obter um a descritor do arquivo.
8 |
9 | Um descritor de arquivo é retornado ao abrir o arquivo usando o método `open()` oferecido pelo
10 | módulo `fs`:
11 |
12 | ```
13 | const fs = require('fs')
14 |
15 | fs.open('/Users/flavio/test.txt', 'r', (err, fd) => {
16 | // fd é o nosso descritor de arquivo
17 | })
18 | ```
19 |
20 | Observe o `r` que usamos como o segundo parâmetro para a chamada `fs.open()`.
21 |
22 | Essa flag significa que abrimos o arquivo para leitura.
23 |
24 | Outras flags que você normalmente encontra são
25 |
26 | - `r+` abre o arquivo para leitura e gravação
27 | - `w+` abre o arquivo para leitura e gravação, posicionando o fluxo no início do arquivo. Esse arquivo é criado caso não exista ainda.
28 | - `a` abre o arquivo para gravação, posicionando o fluxo no final do arquivo. Esse arquivo é criado caso não exista ainda.
29 | - `a+` abre o arquivo para leitura e gravação, posicionando o fluxo no final do arquivo. Esse arquivo é criado caso não exista ainda.
30 |
31 | Você também pode abrir o arquivo usando o método `fs.openSync`, que em vez de fornecer o
32 | objeto de descritor de arquivo em uma callback, retorna:
33 |
34 | ```
35 | const fs = require('fs')
36 |
37 | try {
38 | const fd = fs.openSync('/Users/flavio/test.txt', 'r')
39 | } catch (err) {
40 | console.error(err)
41 | }
42 | ```
43 |
44 | Depois de obter o descritor de arquivo, independente de qual for a maneira usada, você poderá executar todas as
45 | operações que exigem isso, como chamar `fs.open()` e outras operações que interagem com
46 | o sistema de arquivos.
47 |
48 | ## Estatísticas do arquivo
49 |
50 | ### Como obter os detalhes de um arquivo usando o Node
51 |
52 | Cada arquivo vem com um conjunto de detalhes que podemos inspecionar usando o Node.
53 |
54 | Em particular, usando o método `stat()` fornecido pelo módulo `fs`.
55 |
56 | Você o chama passando o caminho de um arquivo e, assim que o Node obtém os detalhes do arquivo, ele invoca uma callback que você passa, com 2 parâmetros: uma mensagem de erro e as estatísticas do arquivo:
57 |
58 | ```
59 | const fs = require('fs')
60 |
61 | fs.stat('/Users/flavio/test.txt', (err, stats) => {
62 | if (err) {
63 | console.error(err)
64 | return
65 | }
66 | })
67 | ```
68 |
69 | O Node também fornece um método de sincronização, que bloqueia o encadeamento até que as estatísticas do arquivo estejam prontas:
70 |
71 | ```
72 | const fs = require('fs')
73 | try {
74 | const stats = fs.stat('/Users/flavio/test.txt')
75 | } catch (err) {
76 | console.error(err)
77 | }
78 | ```
79 |
80 | As informações do arquivo estão incluídas na variável de estatísticas. Que tipo de informação podemos extrair
81 | usando o `stat`?
82 |
83 | Muitas, por exemplo:
84 |
85 | - se o arquivo é um diretório ou um arquivo, usando `stats.isFile()` e `stats.isDirectory()`
86 | - se o arquivo é um link simbólico usando `stats.isSymbolicLink()`
87 | - o tamanho do arquivo em bytes usando `stats.size`.
88 |
89 | Existem outros métodos avançados, mas a maior parte do que você usará no seu dia-a-dia
90 | de programador são esses.
91 |
92 | ```
93 | const fs = require('fs')
94 | fs.stat('/Users/flavio/test.txt', (err, stats) => {
95 | if (err) {
96 | console.error(err)
97 | return
98 | }
99 | stats.isFile() //true
100 | stats.isDirectory() //false
101 | stats.isSymbolicLink() //false
102 | stats.size //1024000 //= 1MB
103 | })
104 | ```
105 |
106 | ## Caminhos de arquivo (file path)
107 |
108 | ### Como interagir com caminhos de arquivo e manipulá-los no Node
109 |
110 | - Obtendo informações fora da path
111 | - Trabalhando com paths
112 |
113 | Todo arquivo no sistema tem um caminho.
114 |
115 | No Linux e macOS, um caminho pode se parecer com:
116 | ```
117 | /users/flavio/file.txt
118 | ```
119 |
120 | enquanto os computadores Windows são diferentes e têm uma estrutura assim:
121 | ```
122 | C:\users\flavio\file.txt
123 | ```
124 | Você deve prestar muita atenção ao usar caminhos em seus aplicativos.
125 |
126 | Você inclui este módulo em seus arquivos usando
127 | ```
128 | const path = require ('path')
129 | ```
130 |
131 | e você pode começar a usar seus métodos.
132 |
133 | ## Obtendo informações fora da path
134 |
135 | Dado um path, você pode extrair informações usando esses métodos:
136 |
137 | - `dirname`: obtem a pasta pai de um arquivo
138 | - `basename`: obtem uma parte do nome de um arquivo
139 | - `extname`: obtém a extensão do arquivo
140 |
141 | Exemplo:
142 |
143 | ```
144 | const notes = '/users/flavio/notes.txt'
145 | path.dirname(notes) // /users/flavio
146 | path.basename(notes) // notes.txt
147 | path.extname(notes) // .txt
148 | ```
149 |
150 | Você pode obter o nome do arquivo a exntesão especificando um segundo argumento ao `basename`:
151 |
152 | ```
153 | path.basename(notes, path.extname(notes)) //notes
154 | ```
155 |
156 | ## Trabalhando com caminho (paths)
157 |
158 | Você pode unir duas ou mais partes de um caminho usando `path.join()`:
159 |
160 | ```
161 | const name = 'flavio'
162 | path.join('/', 'users', name, 'notes.txt') //'/users/flavio/notes.txt'
163 | ```
164 |
165 | Você pode obter o cálculo do caminho absoluto de um caminho relativo usando `path.resolve()`:
166 |
167 | ```
168 | path.resolve('flavio.txt') //'/Users/flavio/flavio.txt' se eu executar da minha pasta inicial
169 | ```
170 | Nesse caso, o Node simplesmente anexará `/flavio.txt` ao diretório de trabalho atual. Se vocês
171 | Para especificar uma segunda pasta de parâmetros, o `resolve` usará o primeiro como base para o segundo:
172 |
173 | ```
174 | path.resolve('tmp', 'flavio.txt')//'/Users/flavio/tmp/flavio.txt'
175 | ```
176 |
177 | Se o primeiro parâmetro começar com uma barra, isso significa que é um caminho absoluto:
178 |
179 | ```
180 | path.resolve('/etc', 'flavio.txt')
181 | ```
182 |
183 | `path.normalize()` é outra função útil, que tentará calcular o caminho real quando o comandopath.normalize('/users/flavio/..//test.txt')
184 | contém especificadores relativos como `.` ou `..`, ou barras duplas:
185 |
186 | ```
187 | path.normalize('/users/flavio/..//test.txt')
188 | ```
189 |
190 | ## Lendo arquivos
191 |
192 | ### Como ler arquivos no Node
193 |
194 | A maneira mais simples de ler um arquivo no Node é usar o método `fs.readFile()`, passando para ele o caminho do arquivo e uma callback que será chamada com os dados do arquivo (e o error):
195 |
196 | ```
197 | const fs = require('fs')
198 |
199 | fs.readFile('/Users/flavio/test.txt', (err, data) => {
200 | if (err) {
201 | console.error(err)
202 | return
203 | }
204 |
205 | console.log(data)
206 | })
207 | ```
208 |
209 | Como alternativa, você pode usar a versão síncrona `fs.readFileSync()`:
210 | ```
211 | const fs = require('fs')
212 |
213 | try {
214 | const data = fs.readFileSync('/Users/flavio/test.txt', 'utf8')
215 | console.log(data)
216 | } catch (err) {
217 | console.error(err)
218 | }
219 | ```
220 |
221 | A codificação padrão é a utf8, mas você pode especificar uma codificação personalizada usando um segundo
222 | parâmetro.
223 |
224 | `Fs.readFile()` e `fs.readFileSync()` leem todo o conteúdo do arquivo na memória antes
225 | de retornar.
226 |
227 | Isso significa que arquivos grandes terão um grande impacto no consumo de memória e diminuirão a
228 | velocidade de execução do programa.
229 |
230 | Nesse caso, uma opção melhor é ler o conteúdo do arquivo usando streams.
231 |
232 | ## Escrevendo arquivos
233 |
234 | ### Como escrever arquivos no Node
235 |
236 | A maniera mais fácil de escrever arquivos no Node é usando a API `fs.writeFile()`.
237 |
238 | Exemplo:
239 | ```
240 | const fs = require('fs')
241 |
242 | const content = 'Some content!'
243 |
244 | fs.writeFile('/Users/flavio/test.txt', content, (err) => {
245 | if (err) {
246 | console.error(err)
247 | return
248 | }
249 | })
250 |
251 | ```
252 |
253 | Alternativamente, você pode usar a versão sincrona com o `fs.writeFileSync()`:
254 |
255 | ```
256 | const fs = require('fs')
257 |
258 | const content = 'Some content!'
259 | try {
260 | const data = fs.writeFileSync('/Users/flavio/test.txt', content)
261 | } catch (err) {
262 | console.error(err)
263 | }
264 | ```
265 |
266 | Por padrão, essa API irá substituir os conteúdos do arquivo se eles já existem.
267 |
268 | Você pode modificar o padrão especificando uma flag:
269 | ```
270 | fs.writeFile('/Users/flavio/test.txt', content, { flag: 'a+' }, (err) => {})
271 | ```
272 |
273 | A flags que você deveria conhecer são:
274 |
275 | - `r+` abre o arquivo para leitura e gravação
276 | - `w+` abre o arquivo para leitura e gravação, posicionando o fluxo no início do arquivo. Esse arquivo é criado caso não exista ainda.
277 | - `a` abre o arquivo para gravação, posicionando o fluxo no final do arquivo. Esse arquivo é criado caso não exista ainda.
278 | - `a+` abre o arquivo para leitura e gravação, posicionando o fluxo no final do arquivo. Esse arquivo é criado caso não exista ainda.
279 |
280 |
281 | ## Anexando a um arquivo
282 |
283 | Um método útil para anexar conteúdo ao final de um arquivo é `fs.appendFile()` (e sua
284 | contraparte` fs.appendFileSync()`):
285 |
286 | ```
287 | const content = 'Some content!'
288 | fs.appendFile('file.log', content, (err) => {
289 | if (err) {
290 | console.error(err)
291 | return
292 | }
293 | })
294 | ```
295 |
296 | ## Usando streams
297 |
298 | Todos esses métodos gravam o conteúdo completo no arquivo antes de retornar o controle ao seu
299 | programa (na versão assíncrona, isso significa executar a callback).
300 |
301 | Nesse caso, uma opção melhor é escrever o conteúdo do arquivo usando streams.
302 |
303 | ## Trabalhando com pastas
304 |
305 | ### Como interagir com pastas usando o Node
306 |
307 | O módulo `fs` provém métodos muito úteis que você pode usar para trabalhar com pastas.
308 |
309 | ### Checando se uma pasta existe
310 |
311 | Use o `fs.access()`para checar se a pasta existe e o Node pode acessá-la.
312 |
313 | ### Criando uma nova pasta
314 |
315 | Use `fs.mkdir()` ou `fs.mkdirSync()` para criar uma nova pasta.
316 |
317 | ```
318 | const fs = require('fs')
319 |
320 | const folderName = '/Users/flavio/test'
321 | try {
322 | if (!fs.existsSync(dir)){
323 | fs.mkdirSync(dir)
324 | }
325 | } catch (err) {
326 | console.error(err)
327 | }
328 | ```
329 | ### Lendo o conteúdo de um diretório
330 |
331 | Use `fs.readdir()` ou `fs.readdirSync`para ler o conteúdo de um diretório.
332 | Esse pedaço de código lê o conteúdo de uma pasta, tanto os arquivos quanto os subarquivos, e returna o seu caminho relativo:
333 | ```
334 | const fs = require('fs')
335 |
336 | const path = require('path')
337 |
338 | const folderPath = '/Users/flavio'
339 | fs.readdirSync(folderPath)
340 | ```
341 | Você pode obter o caminho completo:
342 |
343 | ```
344 | fs.readdirSync(folderPath).map(fileName => {
345 | return path.join(folderPath, fileName)
346 | }
347 | ```
348 |
349 | Você também pode filtrar os resultados para retornar apenas os arquivos e excluir as pastas:
350 |
351 | ```
352 | const isFile = fileName => {
353 | return fs.lstatSync(fileName).isFile()
354 | }
355 |
356 | fs.readdirSync(folderPath).map(fileName => {
357 | return path.join(folderPath, fileName)).filter(isFile)
358 | }
359 |
360 | ```
361 |
362 | ### Renomeando uma pasta
363 |
364 | Use `fs.rmdir()` ou `fs.rmdirSync()` para remover uma pasta.
365 | Remover uma pasta que tenha conteúdo pode ser mais complicado do que você pensa.
366 |
367 |
368 | Nesse caso eu recomendo instalação do módulo `fs-extra`, que é muito popular e estável, além de ser uma substituição do módulo `fs`, provendo ainda mais recursos que ele.
369 |
370 | Nesse caso, o método `remove()` é o que você precisa.
371 |
372 | Instale isso usando
373 | ```
374 | npm install fs-extra
375 | ```
376 | e use isso assim:
377 | ```
378 | const fs = require('fs-extra')
379 | const folder = '/Users/flavio'
380 |
381 | fs.remove(folder, err => {
382 | console.error(err)
383 | })
384 | ```
385 | Isso também pode ser usado com promises:
386 |
387 | ```
388 | fs.remove(folder).then(() => {
389 | //done
390 | }).catch(err => {
391 | console.error(err)
392 | })
393 | ```
394 | ou com async/await:
395 | ```
396 | async function removeFolder(folder) {
397 | try {
398 | await fs.remove(folder)
399 | //done
400 | } catch (err) {
401 | console.error(err)
402 | }
403 | }
404 |
405 | const folder = '/Users/flavio'
406 | removeFolder(folder)
407 | ```
408 |
409 |
--------------------------------------------------------------------------------
/Capitulo_9.md:
--------------------------------------------------------------------------------
1 | ALGUNS MÓDULOS ESSENCIAIS
2 |
3 | ## O módulo fs
4 |
5 | ### O módulo `fs` provém funções úteis para interagir com o sistema do arquivo
6 |
7 | Não há necessidade de instalá-lo, Sendo parte do Node, isso pode ser usado simplesmente requisitando isso:
8 |
9 | ```
10 | const fs = require('fs')
11 | ```
12 |
13 | Once you do so, you have access to all its methods, which include:
14 | - `fs.access()` : verifca se o arquivo exist e o Node tem permissão para acessá-lo
15 | - `fs.appendFile()` : anexe dados ao arquivo. Se o arquivo não existe, ele será criado
16 | - `fs.chmod()` : muda as permissões de um arquivo especifico passando o nome do arquivo. Palavras-chave: `fs.lchmod()` , `fs.fchmod()`
17 | - `fs.chown()` : altere o proprietário e o grupo de um arquivo especificado pelo nome do arquivo passado. Palavras-chave: `fs.fchown()` , `fs.lchown()`
18 | - `fs.close()` : fecha o descritor de um arquivo
19 | - `fs.copyFile()` : copie um arquivocreate a readable file stream
20 | - `fs.createWriteStream()` : crie um arquivo stream de escritura
21 | - `fs.link()` : crie um novo link ao arquivo
22 | - `fs.mkdir()` : cria uma nova pasta
23 | - `fs.mkdtemp()` : cria um diretório temporário
24 | - `fs.open()` : abre o arquivo
25 | - `fs.readdir()` : leia o conteúdo de um diretório
26 | - `fs.readFile()` : leia o conteúdo de um arquivo. Palavras-chave: `fs.read()`
27 | - `fs.readlink()` : leia o valor de um link
28 | - `fs.realpath()` : transform os caminhos relativos ( `.` , `..` ) em caminhos completo
29 | - `fs.rename()` : renomeie uma pasta ou um arquivo
30 | - `fs.rmdir()` : remova uma pasta
31 | - `fs.stat()` : retorna o status de um arquivo especificado pelo nome. Relacionado: `fs.fstat()` , `fs.lstat()`
32 | - `fs.symlink()` : crie um novo link simbólico para o arquivo
33 | - `fs.unlink()` : remove um arquivo ou um link simbólico
34 | - `fs.unwatchFile()` : pare de observar mudanças
35 | - `fs.utimes()` : altere o registro de data e hora do arquivo identificado pelo nome do arquivo passado. Palavras-chave: `fs.futimes()`
36 | - `fs.watchFile()` : comece a observar mudanças no arquivo. Palavras-chave: `fs.watch()`
37 | - `fs.writeFile()` : grave dados em um arquivo. Palavras-chave: `fs.write()`
38 |
39 | Uma coisa peculiar sobre o módulo `fs` é que todos os métodos são assíncronos por padrão, mas eles também podem trabalhar de forma síncrona, basta acrescentar o `sync`.
40 |
41 | Por exemplo
42 |
43 | - `fs.rename()`
44 | - `fs.renameSync()`
45 | - `fs.write()`
46 | - `fs.writeSync()`
47 |
48 | Isso faz uma grande diferença no fluxo da sua aplicação.
49 |
50 | O Node 10 incluiu um suporte para uma API baseada em promises.
51 |
52 | Por example, vamos examinar o método `fs.rename()`. A API assíncrona é usada com uma callback:
53 |
54 | ```
55 | const fs = require('fs')
56 |
57 | fs.rename('before.json', 'after.json', (err) => {
58 | if (err) {
59 | return console.error(err)
60 | }
61 | //terminado
62 | })
63 | ```
64 | Uma API assíncrona pode ser usada assim, com um `try/catch` para tratar erros:
65 | ```
66 | const fs = require('fs')
67 | try {
68 | fs.renameSync('before.json', 'after.json')
69 | //terminado
70 | } catch (err) {
71 | console.error(err)
72 | }
73 | ```
74 |
75 | A principal diferença aqui é que a execução do seu script será bloqueada no segundo exemplo, até que a operação do arquivo seja bem sucedida.
76 |
77 | ## path module
78 |
79 | O módulo `path` do Node.js fornece funções úteis para interagir com o path (caminho) dos arquivos.
80 |
81 | Não há necessidade de instalá-lo. Sendo parte do Node, ele pode ser usado simplesmente digitando isso:
82 |
83 | ```
84 | const path = require('path')
85 | ```
86 | Esse módulo fornece o `path.sep`, que disponibiliza o separador de paths ( `\` no Windows, e `/` no Linux e no macOS), e o `path.delimiter`, que disponibiliza o delimitador do path ( `;` no Windows, e `:` no Linux e no macOS).
87 |
88 | Esses são os métodos do `
89 | path`:
90 |
91 | - `path.basename()`
92 | - `path.dirname()`
93 | - `path.extname()`
94 | - `path.isAbsolute()`
95 | - `path.join()`
96 | - `path.normalize()`
97 | - `path.parse()`
98 | - `path.relative()`
99 | - `path.resolve()`
100 |
101 |
102 | ### `path.basename()`
103 |
104 | Retorna a última parte de um caminho. Um segundo parâmetro pode filtrar a extensão do arquivo:
105 |
106 | ```
107 | require('path').basename('/test/something') //something
108 | require('path').basename('/test/something.txt') //something.txt
109 | require('path').basename('/test/something.txt', '.txt') //something
110 | ```
111 |
112 | ### `path.dirname()`
113 |
114 | Retorna a parte do diretório de um caminho:
115 |
116 | ```
117 | require('path').dirname('/test/something') // /test
118 | require('path').dirname('/test/something/file.txt') // /test/something
119 | ```
120 |
121 | ### `path.extname()`
122 |
123 | Retorna a última parte da extensão de um caminho:
124 |
125 | ```
126 | require('path').extname('/test/something') // ''
127 | require('path').extname('/test/something/file.txt') // '.txt'
128 | ```
129 |
130 | ### `path.extname()`
131 |
132 | Retorna a última parte da extensão de um caminho:
133 |
134 | ```
135 | require('path').extname('/test/something') // ''
136 | require('path').extname('/test/something/file.txt') // '.txt'
137 | ```
138 |
139 | ### `path.isAbsolute()`
140 |
141 | Retorna `true` se o caminho for absoluto:
142 |
143 | ```
144 | require('path').isAbsolute('/test/something') // true
145 | require('path').isAbsolute('./test/something') // false
146 | ```
147 |
148 | ### `path.join()`
149 |
150 | Junta duas ou mais partes de um caminho
151 |
152 | ```
153 | const name = 'flavio'
154 | require('path').join('/', 'users', name, 'notes.txt') //'/users/flavio/notes.txt'
155 | ```
156 |
157 | ### `path.normalize()`
158 |
159 | Tenta calcular o caminho atual quando esse contém especificadores relativos como `.` ou `..`, ou barras duplas
160 |
161 | ```
162 | require('path').normalize('/users/flavio/..//test.txt') ///users/test.txt
163 | ```
164 |
165 | ### `path.parse()`
166 |
167 | Analisa um caminho para um objeto com os segmentos que o compõem:
168 |
169 | - `root` : a raíz
170 | - `dir` : o caminho do arquivo a partir da raíz
171 | - `base` : o nome do arquivo + extensão
172 | - `name` : o nome do arquivo
173 | - `ext` : a extensão do arquivo
174 |
175 | Exemplo:
176 | ```
177 | require('path').parse('/users/test.txt')
178 | ```
179 |
180 | Retorna:
181 |
182 | ```
183 | {
184 | root: '/',
185 | dir: '/users',
186 | base: 'test.txt',
187 | ext: '.txt',
188 | name: 'test'
189 | }
190 | ```
191 | ### `path.relative()`
192 |
193 | Aceita 2 caminhos como argumentos. Retorna o caminho relativo do primeiro ao segundo caminho,
194 | com base no diretório de trabalho atual.
195 |
196 | Exemplo:
197 |
198 | ```
199 | require('path').relative('/Users/flavio', '/Users/flavio/test.txt') //'test.txt'
200 | require('path').relative('/Users/flavio', '/Users/flavio/something/test.txt') //'something
201 | /test.txt'
202 | ```
203 |
204 | ### `path.resolve()`
205 |
206 | Você pode calcular o caminho absoluto de um caminho relativo usando o `path.resolve()`:
207 | ```
208 | path.resolve('flavio.txt') //'/Users/flavio/flavio.txt' se eu executar do meu arquivo inicial
209 | ```
210 | Ao especificar um segundo pârametro, o `resolve` irá usar o primeiro como base para o segundo:
211 | ```
212 | path.resolve('tmp', 'flavio.txt')//'/Users/flavio/tmp/flavio.txt' se eu executar do meu arquivo inicial
213 | ```
214 | Se o primeiro pârametro iniciar com uma barra, isso significa que é um caminho absoluto:
215 | ```
216 | path.resolve('/etc', 'flavio.txt')//'/etc/flavio.txt'
217 | ```
218 | ## `os` module
219 |
220 | ### O módulo `os` fornece algumas funções úteis para interagir com o sistema subjacente
221 |
222 | Este módulo fornece muitas funções que você pode usar para recuperar informações do
223 | sistema operacional subjacente e o computador em que o programa é executado, e interagir com elas.
224 | ```
225 | const os = require('os')
226 | ```
227 | Existem algumas propriedades úteis que nos dizem algumas coisas importantes relacionadas ao manuseio de arquivos:
228 |
229 | `os.EOL` fornece a sequência do delimitador de linha. Está \n no Linux e macOS e \r\n no Windows.
230 | There are a few useful properties that tell us some key things related to handling files:
231 | os.EOL gives the line delimiter sequence. It's \n on Linux and macOS, and \r\n on
232 | Windows.
233 |
234 | `os.constants.signals` nos mostra todas as constantes relacionadas ao tratamento de sinais no processo, como
235 | SIGHUP, SIGKILL e assim por diante.
236 |
237 | `os.constants.errno` define as constantes para o relatório de erros, como EADDRINUSE, EOVERFLOW
238 | e mais.
239 |
240 | Você pode ler todos elas em https://nodejs.org/api/os.html#os_signal_constants.
241 |
242 | Vamos agora ver os principais métodos que o `os` fornece:
243 |
244 | - `os.arch()`
245 | - `os.cpus()`
246 | - `os.endianness()`
247 | - `os.freemem()`
248 | - `os.homedir()`
249 | - `os.hostname()`
250 | - `os.loadavg()`
251 | - `os.networkInterfaces()`
252 | - `os.platform()`
253 | - `os.release()`
254 | - `os.tmpdir()`
255 | - `os.totalmem()`
256 | - `os.type()`
257 | - `os.uptime()`
258 |
259 | ### `os.arch()`
260 |
261 | Retorna a string que identifica a arquitetura subjacente, como `arm`, `x64`, `arm64`.
262 |
263 | ### `os.cpus()`
264 |
265 | Retorna informações sobre as CPUs disponíveis no seu sistema.
266 |
267 | Exemplo:
268 | ```
269 | [ { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz',
270 | speed: 2400,
271 | times:
272 | { user: 281685380,
273 | nice: 0,
274 | sys: 187986530,
275 | idle: 685833750,
276 | irq: 0 } },
277 | { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz',
278 | speed: 2400,
279 | times:
280 | { user: 282348700,
281 | nice: 0,
282 | sys: 161800480,
283 | idle: 703509470,
284 | irq: 0 } } ]
285 | ```
286 |
287 | ### `os.endianness()`
288 |
289 | Retura `BE` ou `LE` dependendo se o Node foi compilado com `Big Endian` ou `Little Endian`.
290 |
291 | ### `os.freemem()`
292 |
293 | Retorna o número de bytes que representam a memória livre no sistema.
294 |
295 | ### `os.homedir()`
296 |
297 | Retorna o caminho para o diretório inicial do usuário atual.
298 |
299 | Exemplo:
300 | ```
301 | '/Users/flavio'
302 | ```
303 | ### `os.hostname()`
304 |
305 | Retorna o nome do host.
306 |
307 | ### `os.loadavg()`
308 |
309 | Retorna o cálculo de média de carga feito pelo sistema operacional.
310 |
311 | Ele retorna apenas um valor significativo no Linux e no macOS.
312 |
313 | Exemplo:
314 |
315 | ```
316 | [ 3.68798828125, 4.00244140625, 11.1181640625 ]
317 | ```
318 |
319 | ### `os.networkInterfaces()`
320 |
321 | Retorna os detalhes das interfaces de rede disponíveis no seu sistema.
322 |
323 | Exemplo:
324 | ```
325 | { lo0:
326 | [ { address: '127.0.0.1',
327 | netmask: '255.0.0.0',
328 | family: 'IPv4',
329 | mac: 'fe:82:00:00:00:00',
330 | internal: true },
331 | { address: '::1',
332 | netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
333 | family: 'IPv6',
334 | mac: 'fe:82:00:00:00:00',
335 | scopeid: 0,
336 | internal: true },
337 | { address: 'fe80::1',
338 | netmask: 'ffff:ffff:ffff:ffff::',
339 | family: 'IPv6',
340 | mac: 'fe:82:00:00:00:00',
341 | scopeid: 1,
342 | internal: true } ],
343 | en1:
344 | [ { address: 'fe82::9b:8282:d7e6:496e',
345 | netmask: 'ffff:ffff:ffff:ffff::',
346 | family: 'IPv6',
347 | mac: '06:00:00:02:0e:00',
348 | scopeid: 5,
349 | internal: false },
350 | { address: '192.168.1.38',
351 | netmask: '255.255.255.0',
352 | family: 'IPv4',
353 | mac: '06:00:00:02:0e:00',
354 | The os module
355 | 165
356 | internal: false } ],
357 | utun0:
358 | [ { address: 'fe80::2513:72bc:f405:61d0',
359 | netmask: 'ffff:ffff:ffff:ffff::',
360 | family: 'IPv6',
361 | mac: 'fe:80:00:20:00:00',
362 | scopeid: 8,
363 | internal: false } ] }
364 | ```
365 |
366 | ### `os.plataform()`
367 |
368 | Retorna a plataforma para a qual o Node foi compilado:
369 |
370 | - `darwin`
371 | - `freebsd`
372 | - `linux`
373 | - `openbsd`
374 | - `win32`
375 | - ...mais
376 |
377 | ### `os.release()`
378 |
379 | Retorna uma string que identifica o número da versão do sistema operacional
380 |
381 | ### `os.tmpdir()`
382 |
383 | Retorna o caminho para a pasta temporária atribuída.
384 |
385 | ### `os.totalmem()`
386 |
387 | Retorna o número de bytes que representam a memória total disponível no sistema.
388 |
389 | ### `os.type()`
390 |
391 | Identifica o sistema operacional:
392 |
393 | - `Linux`
394 | - `Darwin` on macOS
395 | - `Windows_NT` no Windows
396 |
397 | ### `os.uptime()`
398 |
399 | Retorna o número de segundos que o computador está executando desde a última reinicialização.
400 |
401 |
402 | ## events module
403 |
404 | ### O módulo `events` do Node.js fornece a classe EventEmitter
405 |
406 | O módulo `events` do Node.js fornece a classe EventEmitter, que é a chave para trabalhar com eventos no Node.
407 |
408 | Eu publiquei um artigo completo sobre isso, então aqui eu irei apenas descrever a API sem examples mais profundos de como usá-la.
409 | ```
410 | const EventEmitter = require('events')
411 | const door = new EventEmitter()
412 | ```
413 |
414 | O ouvinte de evento usa estes eventos:
415 |
416 | - `newListener` quando um ouvinte é adicionado
417 | - `removeListener` quando ouvinte é removido
418 |
419 | Aqui temos uma descrição detalhada dos métodos mais úteis:
420 |
421 | - `emitter.addListener()`
422 | - `emitter.emit()`
423 | - `emitter.eventNames()`
424 | - `emitter.getMaxListeners()`
425 | - `emitter.listenerCount()`
426 | - `emitter.listeners()`
427 | - `emitter.off()`
428 | - `emitter.on()`
429 | - `emitter.once()`
430 | - `emitter.prependListener()`
431 | - `emitter.prependOnceListener()`
432 | - `emitter.removeAllListeners()`
433 | - `emitter.removeListener()`
434 | - `emitter.setMaxListeners()`
435 |
436 |
437 | ### `emitter.addListener()`
438 |
439 | Pseudônimo para `emitter.on()`
440 |
441 | ### `emitter.emit()`
442 |
443 | Emite um evento. Chama de forma síncrona todos os ouvintes de eventos na ordem em que foram registrados
444 |
445 | ### `emitter.eventNames()`
446 |
447 | Retorne um array de strings que representam os eventos registrados no EventListener atual:
448 |
449 | ```
450 | door.eventNames()
451 | ```
452 |
453 | ### `emitter.getMaxListeners()`
454 |
455 | Obtenha a quantidade máxima de ouvintes que você pode adicionar a um objeto EventListener. O padrão
456 | é 10, mas pode ser aumentado ou reduzido usando `setMaxListeners()`
457 |
458 | ```
459 | door.getMaxListeners()
460 | ```
461 |
462 |
463 |
464 |
465 | ### `emitter.listenerCount()`
466 |
467 | Obtenha a contagem de ouvintes do evento passados como parâmetro:
468 |
469 | ```
470 | door.listenerCount('open')
471 | ```
472 |
473 |
474 | ### `emitter.listeners()`
475 |
476 | Obtém um array de event listeners passados como parâmetro:
477 |
478 | ```
479 | door.listeners('open')
480 | ```
481 |
482 | ### `emitter.off()`
483 |
484 | Pseudônimo para o `emitter.removeListener()`, adicionado no Node 10
485 |
486 | ### `emitter.on()`
487 |
488 | Adiciona uma callback que é chamada quando um evento é acionado.
489 |
490 | Use:
491 |
492 | ```
493 | door.on('open', () => {
494 | console.log('Door was opened')
495 | })
496 | ```
497 |
498 | ### `emitter.once()`
499 |
500 | Adiciona uma callback que é chamada quando um evento é acionado pela primeira vez. Essa callback só será chamada uma vez.
501 |
502 | ```
503 | const EventEmitter = require('events')
504 | const ee = new EventEmitter()
505 |
506 | ee.once('my-event', () => {
507 | //chama a callback uma vez
508 | })
509 | ```
510 | ### `emitter.prependListener()`
511 |
512 | Quando você adiciona um listener usando `on` ou `addListener`, ele é adicionado por último na fila de listeners e é o último a ser chamado. Usando `prependListener`, ele é adicionado e chamado antes dos outros listeners.
513 |
514 | ### `emitter.prependOnceListener()`
515 |
516 | Quando você adiciona um ouvinte usando o `once`, ele é adicionado por último na fila de ouvintes e é o último a ser chamado.
517 | Usando `prependOnceListener`, ele é adicionado e chamado antes de outros ouvintes.
518 |
519 | ### `emitter.removeAllListeners()`
520 |
521 | Remove todos os listeners de um objeto emissor de eventos que está ouvindo um evento específico:
522 |
523 | ```
524 | door.removeAllListeners('open')
525 | ```
526 |
527 | ### `emitter.removeListener()`
528 |
529 | Remova um listener específico. Você pode fazer isso atribuindo a callback a uma variável, quando
530 | adicionado, para que você possa fazer uma referência posteriormente:
531 |
532 | ```
533 | const doSomething = () => {}
534 | door.on('open', doSomething)
535 | door.removeListener('open', doSomething)
536 | ```
537 |
538 | ### `emitter.setMaxListeners()`
539 |
540 | Define a quantidade máxima de listeners que você pode adicionar a EventListener, cujo padrão é 10, mas pode ser aumentado ou diminuído.
541 |
542 | ```
543 | door.setMaxListeners(50)
544 | ```
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | :green_book: Manual do Node.js :ledger:
2 |
3 | 👨💻 Desenvolvido em parceria com o Vinicius Dias 👨💻
4 |
5 | Vale a pena dizer que tive conhecimento da existência do livro durante um curso na plataforma da [freeCodeCamp](https://www.freecodecamp.org/learn/). Os cursos são em inglês, mas são realmente muito completos e no final você ainda ganha um certificação. Durante o início da tradução fui chamado pelo Vinicius Dias, que se disponibilizou a ajudar no projeto, tudo isso visando agregar conteúdo de qualidade a comunidade.
6 |
7 |
8 | 
9 |
10 | ### Conteúdos :books:
11 |
12 | 1. [Introdução](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_1.md)
13 | 2. [Básico](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_2.md)
14 | 3. [Linha de comando](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_3.md)
15 | 4. [Node modules e npm](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_4.md)
16 | 5. [Trabalhando com o Event Loop](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_5.md)
17 | 6. [Programação Assíncrona](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_6.md)
18 | 7. [Networking](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_7.md)
19 | 8. [Fyle System](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_8.md)
20 | 9. [Alguns módulos essenciais](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_9.md)
21 | 10. [Diversos](https://github.com/ChristySchott/manual-node/blob/master/Capitulo_10.md)
22 |
23 |
24 | A corrente tradução é autorizada pelo autor Flavio Copes e iniciada por Christy Hauschild Schott e Vinicius Dias (confira o GitHub dele [aqui](https://github.com/ViniciusmDias)). A tradução é feita em caráter voluntário e tem como único objetivo disponibilizar à comunidade o conteúdo do livro em português.
25 |
26 | Com base na autorização do autor, concordamos que:
27 |
28 | - Ao contribuir com as traduções, estaríamos de acordo com a divulgação livre do conteúdo traduzido por mim no GitHub.
29 | - O conteúdo não pode ser disponibilizado fora deste ambiente sob qualquer forma, incluíndo sua venda.
30 | - Todos os direitos são reservados ao autor.
31 |
32 | ### Vantagens da tradução
33 |
34 | - Poder contribuir com a comunidade, tornando um conteúdo rico mais acessível
35 | - Aprender o conteúdo durante o processo
36 | - Aumentar nossa frequência de contribuição na plataforma
37 | - Melhorar nosso inglês
38 |
39 | ### Publicação
40 |
41 | Esse livro é publicado de forma gratuita e sua versão original (em inglês) pode ser acessada [clicando aqui](https://flaviocopes.nyc3.digitaloceanspaces.com/node-handbook/node-handbook.pdf).
42 |
43 | Para conhecer mais trabalhos do autor e contribuir com ele, visite o seu [blog](https://www.freecodecamp.org/news/author/flavio/). Tem muito conteúdo de qualidade lá!
44 |
45 |
46 | ### Licença & Copyright
47 | Todo o material aqui divulgado é (c) 2018-2020 Flavio Copes.
48 |
49 | Este trabalho está sob a licença Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
50 |
--------------------------------------------------------------------------------
/Sumário.md:
--------------------------------------------------------------------------------
1 | Manual do Node
2 |
3 | 
4 |
5 | O Manual do Node segue a regra 80/20: aprenda 80% do tópico em 20% do tempo.
6 |
7 | ### Book Index
8 |
9 | SEÇÃO 1: INTRODUÇÃO
10 |
11 | - Introdução ao Node
12 | - Uma breve história do Node
13 | - Como instalar o Node
14 | - Quanto JavaScript você deve saber para usar o Node?
15 | - Diferenças entre o Node e o Browser
16 |
17 | SEÇÃO 2: BÁSICO
18 |
19 | - Rodando scripts do Node da linha de comando
20 | - Como sair de um programa em Node
21 | - Como ler variáveis de ambiente
22 | - Opções de hospedagem Node
23 | - Composição
24 |
25 | SEÇÃO 3: LINHA DE COMANDO
26 |
27 | - Usando o Node REPL
28 | - Passando argumentos da linha de comando
29 | - Saídas para a linha de comando
30 | - Aceitando entradas da linha de comando
31 |
32 | SEÇÃO 4: NODE MODULES E NPM
33 |
34 | - Expor a funcionalidade de um arquivo Node usando imports
35 | - npm
36 | - Onde o npm instala os pacotes
37 | - O arquivo package.json
38 | - O arquivo package-lock.json
39 | - Encontrando a versão instalada de um pacote npm
40 | - Como instalar a versão antiga de um pacote npm
41 | - Como atualizar todas as dependências do Node para a última versão
42 | - Regras de versão semântica
43 | - Desinstalando pacotes npm
44 | - Pacotes globais ou locais
45 | - npm dependencies e devDependencies
46 | - npx
47 |
48 | SEÇÃO 5: TRABALHANDO COM O EVENT LOOP
49 |
50 | - O event loop
51 | - nextTick
52 | - setImmediate
53 | - Timers (temporizadores)
54 |
55 | SEÇÃO 6: PROGRAMAÇÃO ASSÍNCRONA
56 |
57 | - Callbacks
58 | - Promises
59 | - async/await
60 |
61 | SEÇÃO 7: NETWORKING
62 |
63 | - HTTP
64 | - Como requisições HTTP funcionam
65 | - Construindo um server HTTP
66 | - Fazendo requisições HTTP
67 | - Axios
68 | - Websockets
69 | - HTTPS, conexões seguras
70 |
71 | SEÇÃO 8: FYLE SYSTEM
72 |
73 | - Descritores de arquivo
74 | - Estatísticas do arquivo
75 | - Caminhos de arquivo
76 | - Lendo arquivos
77 | - Escrevendo arquivos
78 | - Trabalhando com pastas
79 |
80 | SEÇÃO 9: ALGUNS MÓDULOS ESSENCIAIS
81 |
82 | - fs module
83 | - path module
84 | - os module
85 | - events module
86 |
87 | SEÇÃO 10: DIVERSOS
88 |
89 | - Streams
90 | - Trabalhando com MySQL
91 | - Diferenças entre produção e desenvolvimento
92 |
93 |
--------------------------------------------------------------------------------
/images/Capitulo-5/browser-information.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/Capitulo-5/browser-information.png
--------------------------------------------------------------------------------
/images/Capitulo-5/callstack-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/Capitulo-5/callstack-2.png
--------------------------------------------------------------------------------
/images/Capitulo-5/callstack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/Capitulo-5/callstack.png
--------------------------------------------------------------------------------
/images/Capitulo-5/iterations-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/Capitulo-5/iterations-2.png
--------------------------------------------------------------------------------
/images/Capitulo-5/iterations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/Capitulo-5/iterations.png
--------------------------------------------------------------------------------
/images/Capitulo-7/axios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/Capitulo-7/axios.png
--------------------------------------------------------------------------------
/images/Capitulo-7/browser-support.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/Capitulo-7/browser-support.png
--------------------------------------------------------------------------------
/images/callback.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/callback.PNG
--------------------------------------------------------------------------------
/images/cowsay1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/cowsay1.PNG
--------------------------------------------------------------------------------
/images/cowsay2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/cowsay2.PNG
--------------------------------------------------------------------------------
/images/cowsay3.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/cowsay3.PNG
--------------------------------------------------------------------------------
/images/globals.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/globals.PNG
--------------------------------------------------------------------------------
/images/object.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/object.PNG
--------------------------------------------------------------------------------
/images/outdated.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChristySchott/manual-node/3e4073ab2fcd63d076604dc22617e254ee4a7222/images/outdated.PNG
--------------------------------------------------------------------------------