Friday, April 6, 2018

Módulos JavaScript no servidor e no navegador

Aplicações web, mais especialmente as que são de maior porte, necessitam de bibliotecas javascript e de outros recursos como folhas de estilo (Bootstrap é um exemplo típico) e outras páginas html ou de texto plano, para funcionarem a contento. Alguns desses recursos devem ser carregados sequencialmente à medida que a página vem sendo carregada, daí colocarmos elementos como <script> e <link> (esse último para folhas de estilo), mas muitos desses programas só serão necessários bem adiante. Alguns podem ser carregados em background, e em paralelo, vários deles ao mesmo tempo. Isso acelera consideravelmente a apresentação da página web para o cliente, que aguarda ansiosamente. Além de usar os elementos acima (<script> e <link>), podemos efetuar chamadas XHR, ou seja, XMLHttpRequest, ou usando o padrão mais moderno do Fetch API. O problema nos elementos já mencionados é que o navegador precisa carregá-los sequencialmente, pois ele não tem idéia das dependências contidas nos scripts. Se soubéssemos que não há dependência entre os scripts, poderíamos fazer a carga em paralelo, daí a terminologia “Asynchronous Module Definition” ou AMD, que é um dos padrões para a definição de módulos cuja dependência é explicitamente identificada e que pode ser carregado sob demanda pelo navegador. Isso é explorado por carregadores de módulos como RequireJS (http://requirejs.org/) e muitos outros que visam a otimização da carga de módulos no navegador.

O formato AMD (Asynchronous Module Definition, em inglês) é uma tentativa de fornecer uma solução para módulos javascript que pode ser usada atualmente por desenvolvedores web do lado do cliente (navegador). Ele veio da experiência real do grupo do Dojo (https://dojotoolkit.org/) em modularizar seu código. O desenvolvimento desse padrão foi passado para o grupo AMDjs (https://github.com/amdjs). Ele é uma proposta para a definição de módulos onde tanto os módulos como suas dependências (em relação a outros módulos) podem ser carregados de forma independente, assincronamente. AMD representa também um passo certo na direção do sistema de módulos proposto para a padronização futura nos padrões do ECMAscript (javascript). Apesar de ter sido inicialmente definido como um formato para o CommonJS, ele é um padrão separado deste último.
Para criar módulos, usamos alguns padrões possíveis no javascript. O primeiro destes é o “immediately invoked function expression (IIFE)”, ou seja, uma expressão que define uma função e permite ela ser invocada imediatamente. Conseguimos isso colocando a definição da função (anônima) entre parênteses. Se não fosse assim, a definição não seria uma expressão e a tentativa de executá-la de imediato resultaria num erro.
(function(){
 // definição da função
})()

Os dois parênteses ( ) no final são responsáveis pela invocação imediata da função. Poderíamos incluir no interior destes, argumentos a serem passados para a função.
Esse padrão (IIFE) nos permite encapsular código no interior da função, de modo que não precisamos conhecer detalhadamente o que a função IIFE faz, mas podemos usar esse código externamente. Ademais, como o interior de uma função é uma closure, podemos criar variáveis no seu interior, sem poluir o espaço global. Podemos ter múltiplas definições de funções inclusive, retornando um objeto com as várias funções que queremos exportar, todas invisíveis de outra maneira, por estarem numa closure. Isso nos conduz ao segundo padrão útil, o “revealing module pattern”.
var globModulo = function(){
 function ola(){
   console.log('Olá, módulo!');
 }
 return {
   ola: ola
 }
}()

Após salvar o retorno em globModulo, podemos executar globModulo.ola( ) para invocar a função definida internamente. Obviamente, várias outras funções poderiam ser definidas no interior desse bloco. Observe que a definição da função não está entre parênteses como acima. Isso não é necessário porque a função não é a primeira declaração na linha, que começa por uma atribuição a uma variável. Nesse caso, a inclusão da definição da função entre parênteses não é necessária e ela pode ser invocada imediatamente.

Os formatos mais comuns para módulos são o CommonJS, o AMD e o UMD, além do novo formato padronizado pelo ES6.


Módulos CommonJS

Os módulos padronizados pelo CommonJS são definidos como arquivos js regulares, incluindo a atribuição de exports ou module.exports no seu conteúdo. O sistema de módulos então adicionará um wrapper que conterá essas variáveis como parâmetro, além de algumas outras, como veremos.

Um exemplo de módulo, usando a implementação do commonjs contida no NodeJS, é a seguinte:
// saudacoes.js
exports.bomdia = function() {
return "Bom dia!";
};
exports.boanoite = function() {
return "Boa noite!";
};

No programa principal, ou em outro módulo qualquer que precise utilizar esse módulo “saudacoes”, teremos:
var saudacoes = require("./saudacoes.js");
Ou simplesmente,
var saudacoes = require("saudacoes");
E após essa definição, podemos usar as funções saudacoes.bomdia() e saudacoes.boanoite(). Entretanto, nessa segunda forma (sem conter um caminho para um arquivo js diretamente, mas o nome do módulo, precisaremos de um arquivo package.json, que pode ser criado pelo comando “npm init”, num subdiretório do “node_modules”.


Todas as funções e variáveis criadas no módulo e não exportadas serão completamente invisíveis, graças ao wrapper introduzido.


(function(exports, require, module, __filename, __dirname) {
   module.exports = exports = {};
   // o conteúdo do arquivo com o módulo reside aqui
});


Para nossa conveniência, __filename e __dirname são respectivamente o nome do arquivo fonte e o diretório onde ele se encontra. A variável ‘module’ é um objeto com alguns ítens como “id”, “exports”, “parent”, “paths”, “children” (array com outros módulos). Ele tem referências circulares, o que o impede de ser visualizado por JSON.stringify(). Nesse caso, podemos dispor do módulo “json-stringify-safe” para essa função.

Módulos AMD

No navegador é mais interessante definirmos módulos AMD (assíncronos). Uma vantagem explícita desse tipo de módulos é que a carga destes pode ser feita independentemente, sem nos preocuparmos com a ordem de carga dos módulos. A definição de um módulo AMD é realizada num simples função:
  define(id?, dependencias?, factory);
onde o id do módulo é uma string opcional, bem como é opcional o array de dependências de outros módulos. O parâmetro “factory” é uma função que efetivamente cria o módulo, como por exemplo, se o módulo fosse jQuery, retornaria a tão familiar função “$”.
Vejamos um exemplo com a página html, um módulo (amdmod.js), um script inicial (main.js), usando o carregador RequireJS (http://requirejs.org/) feito especialmente para carregar módulos AMD no navegador.

index.html
-------------
<!DOCTYPE html>
<html>
    <head>
        <title>Uma pagina html</title>
        <!-- o atributo data-main attribute indica a require.js
             para carregar o script main.js depois que require.js
             é carregado -->
        <script data-main="main" src="require.js"></script>
    </head>
    <body>
        <h1>Texto do header h1</h1>
    </body>
</html>


amdmod.js
--------------
define(['jquery'] , function ($) {
    return function () {
        console.log("FACTORY em amdmod.js");
        // usa jquery para obter o texto do elemento h1
        console.log($("h1").text());
    };
});

main.js
---------
requirejs(["amdmod"], function(amdfun) {
    console.log("LOADED amdmod.js");
    amdfun();
});

Módulos UMD

Como desenvolvedores de software, nos deparamos frequentemente com a possibilidade de usar um determinado módulo no ambiente do navegador, e também no servidor (nodejs). Os métodos de inclusão funcionam de maneira diferente nos dois casos. Quando você inclui um módulo ou biblioteca usando um tag <script>, usualmente você estará criando variáveis globais que outros scripts poderão acessar, porém uma das vantagns de se usar RequireJS (ou outros carregadores de módulos) é que ele elimina a necessidade de dependermos de variáveis globais. Como podemos ter a mesma biblioteca carregada de ambas as maneiras? A resposta pode ser encontrada em módulos UMD (Universal Module Definition). Praticamente, o procedimento consiste em encapsular o código em uma espécie de boilerplate que tenta definir os tipos de módulos existentes na biblioteca e no sistema, escolhendo o que dá mais certo.

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // foi encontrada uma função define e esta parece ser
        // AMD, então crie um módulo AMD anônimo
        define(['b'], factory);
     } else if (typeof exports === 'object') {
        // parece ser nodejs (tipo commonjs)





        module.exports = factory(require('b'));
    } else {
        // nada suportado, defina 
        // como um global (root == window)
        root.returnExports = factory(root.b);
    }
}(this, function (b) {
    // use ‘b’ da forma apropriada
    // então retorne o que deve ser exportado pelo módulo
    // Pode ser um objeto ou simlesmente uma função.
    return {};
}));




Aqui está um vídeo mostrando como usar módulos CommonJS no NodeJS (servidor javascript)

Monday, February 19, 2018

Programação Reativa

A programação reativa é uma das formas mais modernas de desenvolvermos aplicações com partes visuais, interativas, na web, seja em desktops ou smartphones, onde todos os navegadores suportam versões modernas do javascript.

Esse artigo é uma transcrição do vídeo disponível no Youtube que eu gravei há algum tempo.  Assista ao vídeo, se preferir.


Olá,  pessoal.  Vamos hoje falar um pouco sobre a programação reativa. Esse novo paradigma de programação, que não é nem tão novo assim, está muito em voga, especialmente no uso de programação de páginas web interativas, ou aplicações web. Isso também val para os celulares, os smartphones.

Qual a vantagem dessa programação reativa? Vejamos. Todo mundo aqui já teve algum contato com planilhas (spreadsheets). As planilhas funcionam da maneira seguinte: digamos que numa determinada célula eu coloque uma expressão matemática a = b + c, ou seja, a célula "a" (não precisa ser essa letra extamente, só para simplificar) depende da letra "b" e da letra "c". Quando a letra "b" se alterar, ou quando a letra "c" se alterar, a célula com a letra "a" estará errada, precisa ser atualizada. É exatamente esse o princípio da programação reativa. Criamos as dependências. A célula "A", no caso, reagiria à qualquer alteração na célula "b" e "c". Isso pode ser implementado de muitas maneiras, inclusive por eventos, que é uma forma tradicional de implementarmos em javascript. Então vamos elaborar um pouco mais sobre isso.

Os desenvolvedores resolveram criar um manifesto sobre a reatividade. Então esse manifesto tem 4 princípios básico de reatividade, que qualquer biblioteca que for escrita deve seguir para manter a compatibilidade. Esses princípios seriam a responsividade, ou a interatividade, porque a responsividade significa a velocidade com que a aplicação deveria reagir a qualquer evento, podemos dizer assim, mas qualquer modificação feita pelo usuário. (O usuário clicou em determinado lugar.) Se espera que a aplicação responda rapidamente. Então isso é a responsividade.

A resiliência que seria ele ser tolerante a determinados erros e responder da maneira esperada, àquele erro que aonteça. Por exemplo, digamos que pedimos uma determinada aplicação que não está disponível (o servidor dessa aplicação) então ela deve ficar lá quieta, e não "sujar" a página toda ou deixar de funcionar por causa daquele módulo (digamos que fosse um módulo de tempo/clima). Então o resto da página está funcionando, mostrando notícias ou outras coisas, mas aquela parte que mostraria o clima, a temperatura, a pressão, a previsão nas próximas horas, etc, o servidor pode estar fora do ar o que não impede que o resto da página funcione. Então isso seria  resiliência.
Ele deve ser escalável, se a gente fizer uma ágina mais complexa ou uma aplicação web mais complexa, com mais recursos, ele não deve ficar mais lento só porque está mais complexo. Ou se a quantidade de dados aumentar porque nós estamos "pescando" dados de vários servidores ao mesmo tempo, então isso não deve oferecer resistência na velocidade, ou seja, a velocidade deve permanecer alta.

E o princípio básico, gerenciado por mensagens, ou por eventos. Significa o que? O usuário clica, a aplicação responde. O usuário bate uma tecla, a aplicação responde. E assim por diante.
Um outro princípio interessante, embutido nesses quatro aí, mas a gente não falou ele explicitamente, é que o mundo é assíncrono.  Vamos pegar um exemplo. A genta vai fazer um cafezinho, pega o pó do café, bota na máquina, ou na cafeteira elétrica, aí descobrimos logo depois que não tem açúcar.  Tem duas maneiras da gente fazer isso.  Ah! Não tem açṹcar então não iremos fazer café. Primeiro vou comprar o açúcar, depois quando voltar, eu ponho o pó do café na cafeteira, ligo a máquina, espero que ela termine, ao terminar o café está pronto, eu ponho o açúcar e tomo. Isso aí vai me fazer gastar mais tempo.  Seria mias natural, daí a gente dizer que o mundo é assíncrono, se eu digo: não, vou colocar o pó do café, vou ligar a cafeteira, vou no supermercado comprar o açúcar e enquanto isso a cafeteira está lá funcionando, ao mesmo tempo que eu estou comprando o açúcar. Quando eu voltar, o café já deve estar pronto, ou quase pronto, eu aguardo só um pequeno intervalo de tempo a mais para que ele seja concluido, adoço e tomo o café.  Então vou ficar muito mais satisfeito com essa segunda alternativa.
Isso também é uma explicação de como o mundo é assíncrono.

 Outra maneira de pensar em reatividade é com streams. O que são streams? Uma espécie de array, só que dinâmicos. Uma fila que tem cabeça, cauda, onde se inserem na cabeça os novos dados, e da cauda vai se retirando os dados já inseridos. Por exemplo, seu eu tivesse uma série de eventos que eu quisesse ordena-los, colocar nessa stream e do outro lado, ficar processando evento por evento, mantendo o histórico, inclusive a órdem que eles ocorreram. Isso é muito prático.  Digamos que eu tenha um arquivo muito grande na memória. Não vamos pensar em eventos diretament, mas digamos que eu tenha um arquivo bastante grande na memória e minha memória inteira não daria para colocar os dados contidos nesse arquivo. Então eu teria que ler por partes ele, e ir processando, depois ler outra parte e processar.  Em vez de ficar quebrando ele em pedaços, eu transformo ele numa stream, quer dizer, "venha um parte dele" e enquanto está vindo eu já estou processando. Então eu estou processando de uma forma reativa. Enquanto estão vindo os dados eu estou lendo filtrando esses dados, fazendo alguma ordenação, digamos por exemplo, eu poderia estar contando a ocorrência de caracteres, a frequência com que cada caractere acontece naquele texto (letra a, tantas vezes...). Então eu estaria contando, guardando estados (status) desse texto, mesmo que o texto seja maior que a minha memória, porque eu estou lendo à medida que eu estou necessitando. Então, transformando ele numa stream, eu posso processar de uma maneira como se fosse sequencial a leitura disso aí. Eu não tenho que parar, ler um pedaço, marcar onde eu li, etc.

Agora, muitas bibliotecas existem para a programação reativa em javascript. Algumas delas são famosas porque a maioria (essas famosas) são associadas a GUIs, ou seja, interface gráficas do usuário. Uma delas é a Meteor, automatiza (toma conta de tudo) o desenvolvimento de aplicações web completas, lado servidor e lado cliente. Inclusive, tenho um livro escrito sobre isso (voces podem encontrar aí em baixo).
Outra coisa, aproveitando que estou falando sobre a inclusão, não deixem de dar um "like" no vídeo e também se inscrevam no canal, caso ainda não sejam inscritos.

O Meteor seria uma dessas bibliotecas famosas usando programação reativa. Outra interessante é o React, da Facebook, que é uma biblioteca que só cuida da visão(view), ou seja, da aparência do programa na web, o DOM que é onde a gente desenha o que vai aparecer na tela do navegador. (as caixinhas de entrada, botões, caixas de texto, e por aí...ícones, imagens, parágrafos, etc.)  Bom, então o React que cuida só da parte visual, não cuida da parte de trás, o servidor, etc. E tem muitas, na realidade, eu contei mais de 20 bibliotecas que são um tanto quanto populares, algumas muito modularizadas.  Eu particularmente, gosto muito do Vue.js (acredito que se pronuncie assim porque é meio "francês"). Então essa Vue se dedica só à parte da visão também, a parte do navegador, mas ela é muito flexivel e é bem mais simples do que o Angular. por exempl. O Angular é uma outra reativa também, mas programada pensando de outra maneira.  Normalmente essa reatividade, esse processamento de dados em forma de streams é um fluxo só. Entram os caracteres e eles são processados no caso, são "displayados", colocados na DOM, no caso do React na DOM virtual, no Vue também. A maioria das bibliotecas reativas é assim, elas manem uma cópia do DOM (que é um DOM virtual) e esse DOM exportado, refletido no DOM real (o que está aparecendo realmente), porque esse DOM virtual deixa o acesso mais rápido.

Mas já estamos estendendo muito o nosso vídeo, então vou deixar mais discussões para uma outra oportunidade. Agradeço muito a visualização de vocês.
Até logo.

Thursday, February 15, 2018

Livros publicados

Livros publicados

Tenho alguns livros publicados que podem interessar aos leitores.
Visite minha página de autor na Amazon, ou veja os links abaixo.

Página de autor:  https://www.amazon.com/Rildo-Pragana/e/B01LYZ2TM4

Livros:

Curso Intensivo de JavaScript.  Ideal para principiantes na linguagem.
https://www.amazon.com/Curso-Intensivo-JavaScript-Portuguese-Pragana-ebook/dp/B077Z86X6Y/ref=asap_bc?ie=UTF8

NodeJS: JavaScript no Servidor.  Javascript, dedicado à programação dos servidores utilizando NodeJS, baseado no engenho V8.
https://www.amazon.com/Nodejs-javascript-no-servidor-Portuguese-ebook/dp/B01LZMH242/ref=asap_bc?ie=UTF8

Programando aplicações com AngularJS.  Utilizando o framework Angular (versão 1).
https://www.amazon.com/Programando-aplica%C3%A7%C3%B5es-com-AngularJS-Portuguese-ebook/dp/B0189PK16U/ref=asap_bc?ie=UTF8

Meteor Prático.  Utilizando o framework Meteor, que funciona no lado cliente mas também no servidor.
https://www.amazon.com/Meteor-pr%C3%A1tico-Portuguese-Rildo-Pragana-ebook/dp/B01H7J6NHA/ref=asap_bc?ie=UTF8

Curso Rápido da Lingaugem C.  Bom para complementar os textos utilizados nos cursos de engenharia ou onde C é ensinada a universitários, mas também serve para principiantes em C.
https://www.amazon.com/Curso-r%C3%A1pido-linguagem-C-Portuguese-ebook/dp/B078WKK8KQ/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1518702260&sr=1-1&keywords=curso+rapido+de+C

Tradução do livro do NodeJS acima para o inglês.
https://www.amazon.com/NodeJS-server-side-javascript-Rildo-Pragana-ebook/dp/B01M1NHIE5/ref=asap_bc?ie=UTF8

Vários outros livros têm traduções, todos disponíveis na Amazon.  (dica: Procure por Rildo Pragana.)