├── 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 |

 JavaScript object

52 | 53 | ### Explorando objetos globais 54 | 55 | Você pode inspecionar os globais aos quais tem acesso digitando `global.` e pressionando `tab`: 56 | 57 |

 JavaScript object

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 |

Cowsay example image

286 | 287 | Há uma pasta .bin oculta, que contém links simbólicos para os binários do cowsay: 288 | 289 |

Cowsay example image

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 |

Cowsay example image

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 |

outdate example

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 | ![Informação do Browser](/images/Capitulo-5/browser-information.png) 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 | ![Call Stack](./images/Capitulo-5/callstack.png) 88 | 89 | O event loop em cada iteração verifica se há algo na pilha de chamadas e o executa: 90 | 91 | ![Iteração](./images/Capitulo-5/iterations.png) 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 | ![Pilha de chamadas](./images/Capitulo-5/callstack-2.png) 133 | 134 | Aqui está a ordem de execução de todas as funções em nosso programa: 135 | 136 | ![Iterações](./images/Capitulo-5/iterations-2.png) 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 |

callbacks

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 | ![Axios](/images/Capitulo-7/axios.png) 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 | ![Browser Support](/images/Capitulo-7/browser-support.png) 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 --------------------------------------------------------------------------------