JavaScript

JavaScript – Ordenando Elementos por Cores

Olá Web Developer. Hoje vou mostrar como ordenar elementos por cores usando JavaScript. Isso pode ser útil caso você tenha algo como uma galeria de fotos. Além disso também vamos acabar aprendendo como fazer conversão de cores entre os modelos RGB e Hexadecimal.

Eu usei quando fui criar uma imagem para o Instagram mostrando os cursos da TreinaWeb. Criar um código para ordenar os elementos do site e tirar print da tela foi bem mais rápido do que fazer manualmente em um editor de imagem, e teve um resultado melhor do que quando tentei ordenar os elementos do HTML manualmente também.

Como definir a ordem das cores?

O modo mais comum de se ordenar cores é usando o Círculo Cromático, mostrado na imagem abaixo:

Eu já falei sobre ele e sobre como combinar cores aqui no blog. Não se esqueça de dar uma conferida!

É muito comum em programação utilizarmos os modelos RGB ou Hexadecimal para declarar cores, porém, o que vem depois de rgb(32, 15, 59)?.

Desenvolvedor Front-end Sênior
Formação: Desenvolvedor Front-end Sênior
HTML, CSS e JavaScript são a base de toda a web. Tudo o que você está vendo aqui agora depende deste tripé.Nesta formação aprenderemos Sass, Google Analytics, empacotar nossas aplicações com Webpack, criação de aplicações Desktop com Electron, UX/UI e uma introdução aos frameworks mais utilizados no mercado: Angular, React, Vue e Ember.
CONHEÇA A FORMAÇÃO

Também temos o modelo HSL (Hue – Matiz/Tonalidade, Saturation – Saturação, Lightness – Brilho). As cores (vermelho, verde, azul, etc) são definidas pela matiz, a qual é indicada por um ângulo no círculo. Começamos no topo, 0º, que indica o vermelho, e podemos ir mudando de cores conforme vamos indo aos 360º. Isso é bem melhor para usarmos na ordenação, depois de 121 vem 122, simples assim.

Então a primeira coisa que vamos fazer é converter nossas cores para o modelo HSL.

Convertendo Cores para HSL

É mais simples fazer a conversão para HSL a partir do modelo RGB, que possui números de 0 a 255. Se você estiver com cores em Hexadecimal, que utiliza valores entre 00 e FF, basta converter para RGB primeiro.

Hexadecimal para RGB

Os valores entre 00 e FF são basicamente 0 a 255 em hexadecimal. Isso é fácil de converter. Vamos criar uma função que vai pegar cada par de cores do código hexadecimal e retornar como números na base decimal. Então um FF deve retornar 255.

// exemplo de cor: #15FA3D
function hexToRGB(color){
    color = color.replace('#', ''); // vamos remover o #
    // e pegar os valores de Red, Green e Blue
    let red = color.substr(0, 2),
        green = color.substr(2, 2),
        blue = color.substr(4, 2);
    // agora vamos converter a string em número com o parseInt
    // por estar em hexadecimal, indicamos a base 16
    red = parseInt(red, 16);
    green = parseInt(green, 16);
    blue = parseInt(blue, 16);
    // e vamos retornar como um array
    return [red, green, blue];
}
// saída esperada: [21, 250, 61]

Formatando cores RGB

Já temos nossa cor hexadecimal em RGB em um formato de Array, o que nos facilita na hora de pegar cada uma das cores. Mas e se inicialmente já tivermos uma cor em RGB? Vamos criar uma função para formatar cores RGB para o formato que estamos usando.

É comum tanto o uso do RGB quanto o RGBA, então vamos primeiro deixar apenas os números, separar pelas vírgulas e pegar os valores de Red, Green e Blue.

// exemplo de cor: rgba(25, 15, 200, 0.8)
function formatRGB(color){
    // removemos as letras e parênteses
    color = color.replace(/[rgba()]/gi, '');
    // separamos por vírgulas
    color = color.split(',');
    // agora teríamos algo como ["25", " 15", " 200", " 0.8"]
    // vamos pegar cada um dos valores das strings e converter para números
    const red = parseInt(color[0]),
        green = parseInt(color[1]),
        blue = parseInt(color[2]);
    return [red, green, blue];
}
// saída esperada: [25, 15, 200]

Convertendo RGB para HSL

Para chegarmos na parte de ordenação precisamos das cores em HSL. Essa parte é um pouco mais complexa, então eu vou montar a função aos poucos para ir explicando melhor cada pedaço, e no final eu mostro a função inteira. Para não ficar repetindo, as partes já explicadas serão substituídas por ....

Vamos começar simplesmente declarando a função, que vai receber separadamente os valores de Red, Green e Blue.

function RGBToHSL(r, g, b){

}

Os valores de R, G e B sempre serão um número entre 0 e 255. Primeiro temos que transformar esses números em um valor entre 0 e 1. Para isso, basta dividí-los por 255.

function RGBToHSL(r, g, b){
    r /= 255;
    g /= 255;
    b /= 255;
    // lembrando que
    // r/= 255 é igual a
    // r = r / 255;
}

Agora vamos pegar qual o maior e o menor valor entre esses três números. Para isso utilizamos Math.min e Math.max.
Também vamos declarar uma variável chamada delta, que vai indicar a diferença entre o maior e o menor valor, e por último já vamos declarar as variáveis h, s e l, que terão os valores para termos as cores no modelo HSL.

function RGBToHSL(r, g, b){
    ...
    let min = Math.min(r, g, b),
        max = Math.max(r, g, b),
        delta = max - min,
        h = 0,
        s = 0,
        l = 0;
}

Cálculo da Matiz

Agora podemos começar a calcular cada uma das propriedades. Primeiro vamos calcular Hue (matiz). Temos algumas regrinhas para isso:

  • Se todos os valores (r, g e b) são iguais, h deve ser 0.
  • Se a maior cor for Red, a fórmula deve ser ((g – b) / delta) % 6
  • Se a maior cor for Green, a fórmula deve ser (b – r) / delta + 2
  • Se a maior cor for Blue, a fórmula deve ser (r – g) / delta + 4

Podemos utilizar o delta para saber se todas as cores são iguais. Afinal, se o maior valor e o menor são iguais, isso significa que todos os valores são iguais, fazendo o delta ser 0. Então agora, seguindo essas regras, teremos:

function RGBToHSL(r, g, b){
    ...
    if(delta === 0){
        h = 0;
    }else if(max === r){
        h = ((g - b) / delta) % 6;
    }else if(max === g){
        h = (b - r) / delta + 2;
    }else{
        h = (r - g) / delta + 4;
    }
}

Depois de definir o valor de h, multiplicamos por 60 e arrendondamos. Como precisamos de um valor entre 0 e 360, precisamos arrumar caso apareça um valor negativo. Para isso, basta somar 360. Isso significa que -90 resultaria em 270.

function RGBToHSL(r, g, b){
    ...
    h = Math.round(h * 60);
    if(h < 0){
        h += 360;
    }
}

Cálculo do Brilho

Agora vamos calcular Lightness (brilho), já que a saturação depende dele. O cálculo do brilho é a soma do maior valor e do menor valor dividido por 2.

function RGBToHSL(r, g, b){
    ...
    l = (max + min) / 2;
}

Cálculo da Saturação

Agora vamos usar o delta para calcular Saturation (saturação). Se o delta for 0, a saturação também deve ser 0.
Se o valor for diferente de 0 devemos pegar 1 e subtrair o valor absoluto do dobro do brilho menos 1. Valor absoluto é basicamente deixar um número negativo na forma positiva. Então -45 ficaria 45.

function RGBToHSL(r, g, b){
    ...
    s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
}

Finalizando a conversão para HSL

Agora que temos os valores de S e L, mas eles estão entre 0 e 1. Para converter para valores entre 0% e 100% basta multiplicar por 100. Vamos usar .toFixed(1) para limitar um número depois da vírgula. Assim um valor 0.3752 vai se tornar 37.5.

function RGBToHSL(r, g, b){
    ...
    s = +(s * 100).toFixed(1);
    l = +(l * 100).toFixed(1);
}

Nossa função completa ficará assim:

function RGBToHSL(r, g, b){
    r /= 255;
    g /= 255;
    b /= 255;

    let min = Math.min(r, g, b),
        max = Math.max(r, g, b),
        delta = max - min,
        h = 0,
        s = 0,
        l = 0;

    if(delta === 0){
        h = 0;
    }else if(max === r){
        h = ((g - b) / delta) % 6;
    }else if(max === g){
        h = (b - r) / delta + 2;
    }else{
        h = (r - g) / delta + 4;
    }

    h = Math.round(h * 60);
    if(h < 0){
        h += 360;
    }

    l = (max + min) / 2;
    s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));

    s = +(s * 100).toFixed(1);
    l = +(l * 100).toFixed(1);

    return [h, s, l];
}

Como temos nossas cores em um Array, como [25, 15, 200], podemos usar o operador spread para passar esses valores para a função, como:

const color = [25, 15, 200];
RGBToHSL(...color); // retorno: [243, 86, 42.2]
Desenvolvedor React Sênior
Formação: Desenvolvedor React Sênior
Nesta formação conheceremos a Arquitetura Flux, muito utilizada nas aplicações modernas e que nos trás muitos benefícios em relação às arquiteturas clássicas como o MVC. Aprenderemos a sua principal implementação, o Redux. Também veremos a trabalhar com código assíncrono com Redux Thunk e conceito de programação funcional com Redux-Saga.
CONHEÇA A FORMAÇÃO

Ordenando Cores

Agora que temos cores, tanto Hexadecimal quanto RGB, no formato HSL, podemos ordená-las. Como vimos, a matiz é definida pelo primeiro valor no modelo HSL. Então podemos usá-lo para ordenar nossas cores. Para isso basta utilizar o método .sort() dos Arrays e passar uma função para fazer a comparação entre as cores.

let colors = [
    "#fbb735", "#e98931", "#eb403b", "#b32E37", "#6c2a6a",
    "#5c4399", "#274389", "#1f5ea8", "#227FB0", "#2ab0c5",
    "#39c0b3"
];
// convertendo de hexadecimal para hsl
colors = colors.map(color => {
    // de hexadecimal para rgb
    color = hexToRGB(color);
    // de rgb para hsl
    return RGBToHSL(...color);
})

// ordenação pela matiz
colors.sort((a, b) => a[0] - b[0] > 0 ? 1 : -1 );

Resultado

Veja abaixo a implementação. Use os botões para gerar cores e depois para ordenar.

Você vai notar que a ordenação não é 100% perfeita. Isso porque utilizamos apenas a matiz para a ordenação, e o brilho e saturação também são muito importantes para a definição de uma cor. Mas para coisas mais simples esse código funciona muito bem, além de ter servido para aprendermos muitas coisas.

Para mais precisão, prefira utilizar bibliotecas como o color-sorter, onde podemos passar um Array de cores em qualquer formato, até mesmo misturando formatos. Ele também leva em conta coisas como saturação, brilho e transparência.

Veja como o resultado com essa biblioteca é mais preciso:

Há muitas maneiras de ordenar cores, e dependendo do que você quer pode ser necessário dar mais importância para uma propriedade ao invés de outra.

O que é Babel?

Transpilador JavaScript de código aberto e gratuito, o Babel foi lançado sobre a licença MIT e possui como uma das principais características converter código JavaScript atual em uma versão que o navegador possa executar.

Multiplataforma, é amplamente utilizado por desenvolvedores que necessitarem converter recursos da linguagem JavaScript para uma versão que o navegador compreenda.

JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO

Desde que surgiu, em 2015, tornou-se uma ferramenta indispensável para o desenvolvimento front-end.

Como ele funciona?

Basicamente, em palavras mais simples, o transpilador funciona da seguinte forma:

Como podemos verificar na imagem acima, ao se deparar com um código ES2015, que trata-se da versão mais atual do JavaScript, o transpilador o converte, gerando assim um novo código, porém, desta vez, em ES5, versão mais antiga do javaScript que se tornará compreensível para o navegador.

Na imagem abaixo, dispomos de um outro exemplo, onde o primeiro código não seria compatível em navegadores ou ambientes de produção. Desta forma, o código de saída tornaria compreensível após ter sido realizada sua conversão utilizando o transpilador Babel.

Concluindo

Com as recentes atualizações do JavaScript, é cada vez mais comum que o desenvolvedor deseje as utilizar. Porém, nem sempre o navegador irá conseguir executar o código JavaScript mais recente. Para isso, o Babel é de suma importância para desenvolvedores front-end, com ele conseguimos utilizar os recursos mais atuais do JavaScript em navegadores que só conseguem executar códigos mais antigos utilizando o processo de transpilação.

O que é JSX?

Criado pela equipe de desenvolvimento do React, o JSX é uma forma de criar elementos para serem utilizadas como templates de aplicações React. Basicamente, os elementos criados com o JSX são bem similares com código HTML e fornecem aos desenvolvedores uma forma mais simples e intuitiva de criar os componentes de uma aplicação.
Porém, apesar de muito similar ao HTML, o JSX não é interpretado pelo navegador. Por este motivo, deve-se utilizar um “transpilador” para essa conversão. Atualmente, o mais conhecido deles é o Babel, do qual falaremos em outro artigo.

React - Introdução
Curso de React - Introdução
CONHEÇA O CURSO

Sintaxe do JSX

Como dito anteriormente, o JSX possui uma sintaxe muito semelhante ao HTML. O código abaixo demonstra claramente esta característica. Apesar de muito parecido, o código a seguir não é HTML e sim um trecho de código JSX.

const nav = (
  <nav>
    <ul>
      <li><a href="#">Início</a></li>
      <li><a href="#">Sobre</a></li>
      <li><a href="#">Contato</a></li>
    </ul>
  </nav>
)

Porém, como dito acima, este código não conseguirá ser lido pelo navegador, e é papel do “transpilador” convertê-lo para a sintaxe do React. Sendo assim, o código acima será “transpilado” para o seguinte código:

var nav = React.createElement(
  "nav",
  { className: "links" },
  React.createElement(
    "ul",
    null,
    React.createElement(
      "li",
      null,
      React.createElement(
        "a",
        { href: "#" },
        "Inicio"
      )
    ),
    React.createElement(
      "li",
      null,
      React.createElement(
        "a",
        { href: "#" },
        "Sobre"
      )
    ),
React.createElement(
      "li",
      null,
      React.createElement(
        "a",
        { href: "#" },
        "Contato"
      )
    )
  )
);

Todo este processo facilita a criação de aplicações React, já que é muito mais simples criar um código similar ao HTML do que vários elementos React. A partir daí, é papel do React exibir a estrutura no navegador.

Vídeos Picture-in-Picture com JavaScript

Olá Web Developers! Hoje vamos ver como permitir o usuário assistir a um vídeo da sua página web fora do navegador.

O que é PIP?

Picture-in-Picture (PIP), também conhecida aqui como Imagem sobre Imagem, é quando temos a imagem de uma tela sendo exibida em cima de outra imagem.

Um exemplo são monitores para computador que também possuem funcionalidade de TV. Com PIP você pode trabalhar e ao mesmo tempo deixar a imagem da TV no canto da tela.

Monitor - TV - PIP

PIP no HTML5

A API de Picture-in-Picture permite que páginas da web peguem um vídeo qualquer presente em seu corpo e o exiba em uma pequena janela flutuante que ficará sempre em cima das outras janelas. Assim o usuário poderá continuar assistindo enquanto faz outras tarefas.

Na imagem abaixo estamos com um vídeo comum no YouTube:

Ao ativar o PIP o vídeo passa a ser reproduzido em uma janela flutuante que você pode mover e redimensionar. Mesmo que você abra outras janelas, o vídeo continua em cima de todas as outras janelas.

Na imagem abaixo vemos um exemplo de navegação em nosso blog enquanto o vídeo do YouTube permanece visível. Claro que você pode minimizar as janelas do navegador e abrir qualquer outro programa.

Esta funcionalidade está sendo adotada também em smartphones, o que nos permite continuar assistindo a um vídeo do navegador enquanto utilizamos outros aplicativos.

Como iniciar o PIP?

Para iniciar o Picture-in-Picture é necessário acessar o elemento HTML <video> que está com o vídeo que você quer que flutue. Imagine que a gente tenha o seguinte HTML:

<button onclick="iniciarPIP()">Picture in Picture</button>

<video src="./meu-video.mp4" id="meu-video" controls></video>

Criamos um botão para iniciar o PIP e adicionamos um vídeo. Agora basta pegar o elemento <video> e executar o método .requestPictureInPicture(). Este método retorna uma Promise.

async function iniciarPIP(){
    const video = document.querySelector('#meu-video');
    await video.requestPictureInPicture();
}

Você pode ver o resultado abaixo:

React: Conheça o Poder dos Hooks

Olá Web Developers! Vamos conhecer o poder dos Hooks do React.

O que são React Hooks?

Até a versão 16.7 era necessário criar classes para utilizar todas as funcionalidades do React em um componente, como estado e lifecycle.

Era possível criar componentes a partir de funções, mas esses componentes apenas recebiam propriedades, não possuindo lifecycles, estados e outras funcionalidades do React.

Os Hooks foram introduzidos na versão 16.8, e nos permitem utilizar vários recursos do React dentro de funções de forma bem simples.

Por que usar Hooks?

Os Hooks nos ajudam a organizar a lógica que será usada em um componente. Podemos até criar nossos próprios Hooks para reutilizar a lógica em vários componentes. A própria comunidade está criando Hooks muito interessantes que podemos utilizar em nossos projetos.

React - Tópicos Avançados
Curso de React - Tópicos Avançados
CONHEÇA O CURSO

Hooks

Vamos conhecer os dois principais Hooks, useState e useEffect.

useState

O useState nos permite criar estados em um componente criado a partir de uma função, assim como o state presente em componentes criados a partir de classes.

Veja o exemplo da seguinte classe:

class Treinaweb extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            nome: 'TreinaWeb'
        }
    }

    render(){
        return {
            <div>
                <p>{this.state.nome}</p>
                <button onClick={() => this.setState({nome: 'React'})} >CLICK</button>
            </div>
        }
    }
}

Com os Hooks nós teremos o seguinte código:

function Treinaweb (props){
    const [nome, setNome] = useState('TreinaWeb');

    render(){
        return {
            <div>
                <p>{nome}</p>
                <button onClick={() => setNome('React')} >CLICK</button>
            </div>
        }
    }
}

Bem menos código, não é mesmo? Vamos entender o que o useState() está fazendo.

O useState() cria uma variável que controlará o estado do componente. Se quiser outra variável execute outro useState().

Para este Hook nós passamos o valor inicial do estado, em nosso exemplo, a String “TreinaWeb”. Como retorno temos a variável com o valor do estado, que demos o nome de nome, e uma função que serve unicamente para atualizar o valor desta variável, que demos o nome de setNome.

Veja que no clique do botão apenas chamamos esta função setNome(), passando o novo valor.

Por estar tudo declarado dentro da própria função, não temos mais a necessidade de utilizar o this, que pode ser complicado de ser compreendido no JavaScript para iniciantes, causando erros no código.

useEffect

O useEffect é um Hook que serve para lidar com os efeitos. Podemos usá-los como os lifeCycles componentDidMount, componentDidUpdate e componentWillUnmount.

Imagine que a gente tenha uma API que nos retorna uma lista de produtos baseado no nome que passarmos.

function Treinaweb (props){
    const [produto, setProduto] = useState('Leite');

    useEffect(() => {
        Produtos.buscar(produto);
    })

    render(){
        return {
            <div>
                <p>{produto}</p>
                <button onClick={() => setProduto('Chocolate')} >CLICK</button>
            </div>
        }
    }
}

O useEffect() recebe como primeiro parâmetro uma função que será executada assim que o componente renderizar. Então é um ótimo lugar para fazer requisições.

Dessa maneira como escrevemos, a função passada ao useEffect() será executada sempre que o componente for atualizado.

React - Dominando Componentes
Curso de React - Dominando Componentes
CONHEÇA O CURSO

A beleza deste Hook é que podemos definir facilmente quando queremos que esta função seja executada novamente. Basta passar como segundo parâmetro ao useEffect() um Array com as variáveis que controlarão esse Hook.

Vamos supor que queremos que a função seja executada apenas quando a variável produto for alterada. Ficaria assim:

    useEffect(() => {
        Produtos.buscar(produto);
    }, [produto])

E se quisermos que a função seja executada apenas uma vez, que é quando o componente é inserido na tela, basta passar um Array vazio.

    useEffect(() => {
        Produtos.buscar(produto);
    }, [])

Você pode executar quantos useEffects() quiser, o que nos dá mais controle sobre o que e quando algo deve ser executado.

Reutilização de Hooks

Podemos criar nossos próprios Hooks. Basta criar uma função que utilize outros Hooks e retorne algum valor. Assim poderemos ter uma lógica fora dos componentes e reutilizá-la onde quisermos. Essas funções também devem ter seu nome iniciado com use.

O site https://usehooks.com/ possui vários exemplos de Hooks interessantes que podem ser muito úteis em seu projeto, como carregar imagens apenas se estiverem visíveis na tela, criar funcionalidade de desfazer, criar atalhos de teclado, etc. Também é uma ótima fonte para entender melhor os Hooks na prática, vendo os códigos disponíveis.

Os Hooks nos permitem trabalhar de forma limpa e simples no React, nos dando um grande poder. Com ajuda da comunidade estamos vendo várias possibilidades interessantes.

Já criou um Hook? Compartilhe aqui com a gente pelos comentários!

O que são aplicações SPA?

Neste artigo, vamos abordar o que são as aplicações baseadas em tecnologias SPA e o porquê de estas fazerem tanto sucesso nos dias atuais.

A sigla SPA vem de Single Page Applications, ou Aplicações de Página Única. Apesar de o nome permitir a dedução, isso não significa que a aplicação terá apenas uma única página.

JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO

O que muda na verdade é a forma com que a página irá ser carregada. Estamos acostumados com aplicações onde as páginas são renderizadas do lado do servidor, independente da tecnologia utilizada. Isso traz um efeito: cada nova página que precisa ser carregada se traduz em uma nova requisição para o servidor, requisição esta para que o browser consiga carregar o HTML, o CSS e o JavaScript da nova página requisitada. Por isso, em várias aplicações web, vemos o browser levando um “tempinho” para carregar a nova página, ou vemos a nova página ficar em branco inicialmente para ser carregada em seguida. Estes comportamentos ocorrem por causa do tempo entre o browser fazer a requisição para carregar a nova página e o servidor responder com as novas estruturas a serem renderizadas.

Aplicações baseadas em frameworks SPA funcionam de maneira diferente, pois nelas não há a necessidade de se fazer requisições para carregamento de novas páginas. A aplicação seria “carregada” por inteiro na primeira requisição, onde todo o HTML, CSS e JavaScript necessários seriam carregados de uma vez. A partir deste momento, quando novas páginas precisassem ser carregadas, estas seriam carregadas através de rotinas JavaScript, retirando a necessidade de requisições para o servidor com a finalidade de obter o novo conteúdo a ser renderizado.

Aplicações SPA de maneira geral nos permitem obter algumas vantagens. Uma delas é a possibilidade de otimização em geral da performance da aplicação ao deslocar todo o esforço de renderização para o cliente e permitir um tráfego de dados mais leve entre cliente e servidor. Outra é o reaproveitamento de código através de tecnologias como React/React Native e Angular/Ionic, o que possibilita o desenvolvimento com menor esforço e mais padronizado até mesmo de aplicações mobile. Porém, aplicações SPA têm a tendência de possuírem alguns pontos fracos, como justamente o deslocamento do esforço de renderização para o cliente e, em alguns casos, questões de SEO.

Como aplicações SPA funcionam?

De maneira geral, em uma aplicação SPA, o carregamento dos recursos (como CSS, JavaScript e HTML das páginas) ocorre apenas uma única vez: na primeira vez em que o usuário acessa a aplicação. Nesse primeiro acesso, todo o conteúdo HTML, CSS e JavaScript já é transferido para o cliente. A partir deste momento, quando o usuário transitar pelas páginas da aplicação, não será necessário mais fazer requisições para o servidor para a carga dessas novas páginas: o conteúdo relacionado a elas já foi baixado no primeiro acesso. O que acontece nesse momento é que o conteúdo da página é carregado via JavaScript, código este que é justamente gerado com base nos frameworks SPA, como Angular, React e Vue.js. Por isso, dizemos que o processamento do carregamento das páginas e seus respectivos recursos passa para o cliente, já que JavaScript é uma linguagem majoritariamente client side (existem algumas exceções, como quando trabalhamos com Node.js).

JavaScript Intermediário
Curso de JavaScript Intermediário
CONHEÇA O CURSO

Neste momento, o servidor fica responsável não mais por renderizar e processar a renderização do conteúdo, mas sim por lidar com os dados a serem manipulados pela aplicação. As operações de persistência em bancos de dados ou a devolução de conteúdo para ser renderizado (como uma lista de clientes, por exemplo) passam a ser exclusivamente da aplicação hospedada do lado do servidor. Atualmente, o que é comum é que o servidor exponha uma API RESTful para ser consumida por uma aplicação SPA. A aplicação SPA se comunica com essa API RESTful através de chamadas HTTP, trafegando dados em formatos como XML e JSON. A aplicação do lado do servidor fica responsável por responder a estas chamadas HTTP, realizando os processos de negócio e de persistência que sejam pertinentes na situação. Essa arquitetura traz uma vantagem muito clara: a separação e isolamento completos do back-end e do front-end. Isso possibilita que duas equipes trabalhem nas duas frentes em paralelo por exemplo, além de permitir esforços mais focados: uma pessoa que lida melhor com aspectos ligados ao front-end pode direcionar todo o seu esforço para tarefas relacionadas ao front-end. O mesmo vale para quem tem mais aptidão ao back-end.

Como e onde utilizar?

Atualmente, aplicações SPA podem ser utilizadas em praticamente todas as situações, o que explica bastante a popularização de frameworks SPA como Angular, React, Vue.js e Ember na atualidade. Porém, existem algumas situações onde frameworks SPA podem não ser tão adequados hoje:

• Aplicações que precisem de SEO extremo podem ter problemas se forem desenvolvidas com frameworks SPA. A maioria dos indexadores hoje conseguem entender aplicações SPA, além de dispormos de uma grande quantidade de meta-tags para melhorar este ponto. Porém, é um trabalho adicional frente à clássica renderização de páginas múltiplas no servidor (também chamado de multi-page application). Esse “probleminha” acontece justamente porque o conteúdo não é renderizado no servidor,, sendo renderizado completamente no cliente. Por isso, os mecanismos de busca podem encontrar dificuldade para indexar o conteúdo das páginas, tendo em vista que eles não podem indexar conteúdo gerado do lado do cliente. Isso explica porque a maioria dos frameworks SPA hoje contam com soluções SSR (Server-Side Rendering), onde pelo menos uma parte do conteúdo é carregado do lado do servidor para favorecer os mecanismos de indexação;

• Aplicações SPA podem ser um pouco mais lentas, principalmente na inicialização. Isso ocorre porque todo o conteúdo precisa ser baixado de uma vez para o cliente no primeiro acesso. Além disso, como todo o processo de renderização passa a ser de responsabilidade do cliente, a aplicação passa a sofrer um pouco com possíveis limitações de hardware de quem a acessa. Porém, obviamente, existem técnicas para mitigar este ponto, como o lazy loading;

• De maneira geral, aplicações SPA precisam que o JavaScript no browser esteja habilitado, embora não seja tão comum hoje em dia que o mesmo seja desabilitado. Também existem técnicas que podem mitigar este ponto, como o próprio SSR;

• Há uma ligeira tendência a aplicações SPA serem menos seguras do que aplicações multi-page renderizadas no servidor, principalmente no que diz respeito a ataques XSS. Porém, de fato, isso na verdade está mais atrelado ao conhecimento do desenvolvedor sobre técnicas para evitar estes tipos de ataques; precauções estas que deveriam ser tomadas inclusive em aplicações renderizadas do lado do servidor;

JavaScript Avançado
Curso de JavaScript Avançado
CONHEÇA O CURSO

• Atenção à fragilidade do ecossistema JavaScript. Esse é um ponto bem polêmico, mas é fato que a “instabilidade” de frameworks JavaScript é algo a se considerar. É relativamente comum que você desenvolva uma aplicação com uma determinada versão de um framework SPA, mas seja obrigado a reescrever uma quantidade considerável de código quando precisar atualizar a versão do framework utilizada inicialmente no projeto. Esse é, sem sombra de dúvidas, um fator importante a ser colocado na balança; não só no que diz respeito a utilizar um framework SPA ou um framework MPA, mas também no que diz respeito à decisão sobre qual framework SPA deverá ser utilizado, se for o caso.

O que é Ionic?

O Ionic é um Framework Open Source gratuito sobre a licença MIT para desenvolvimento de aplicações mobile híbridas.

Aplicações híbridas são aplicativos móveis construídos de maneira alternativa a aplicações nativa. São construídos, geralmente, utilizando HTML+CSS+JavaScript, desta maneira se tornaram extremamente populares, pois permite o desenvolvimento multiplataforma, utilizando o mesmo HTML para diferentes sistemas operacionais.

Aqui no Blog possuímos um artigo “App Nativo x App Híbrido: existe o melhor?” onde você pode conferir mais detalhes.

Ionic - Criação de aplicações mobile
Curso de Ionic - Criação de aplicações mobile
CONHEÇA O CURSO

Caso você não saiba o que é um Framework

O framework é um facilitador no desenvolvimento de diversas aplicações e, sem dúvida, sua utilização poupa tempo e custos para quem utiliza, pois de forma mais básica, é um conjunto de bibliotecas utilizadas para criar uma base onde as aplicações são construídas, um otimizador de recursos. Tem como principal objetivo resolver problemas recorrentes com uma abordagem mais genérica. Ele permite ao desenvolvedor focar nos “problemas” da aplicação, não na arquitetura e configurações.

Aqui no blog também possuímos um artigo sobre “Para que serve um Framework”.

Sendo assim, o que é o Ionic?

Desenvolvido por Max Lynch, Ben Sperry e Adam Bradley da Drifty Co., sua primeira versão teve seu lançamento em 2013 e atualmente encontra-se na versão 4.

Como dito acima, é um Framework para criação de aplicações móveis e desktop de alto desempenho e qualidade, que utiliza as tecnologias web HTML, CSS e JavaScript.

Como diz em seu site, o Ionic ajuda as equipes a criarem e distribuírem belos aplicativos híbridos em várias plataformas, possuindo foco na experiência do usuário ou interação do usuário com o aplicativo (controles, interação, gestos, animações).

Projetado para funcionar e ser exibido em diferentes plataformas, possui um design limpo, simples e funcional, com componentes padrões, tipografia, paradigmas interativos e diversos templates.

Além disso, possui um cliente de linha de comando (CLI) para gerenciar todo projeto criado com o Ionic. O CLI é uma ferramenta que cria aplicativos Ionic de forma rápida e fornece vários comandos úteis para facilitar o desenvolvimento utilizando o Framework. Possui um servidor de desenvolvimento integrado, ferramentas de compilação e depuração, entre outros benefícios.

Para instalar o Ionic CLI basta clicar aqui.

Por que aprender Ionic?

Além da principal vantagem no desenvolvimento de aplicações híbridas, muitas outras vantagens podem ser listadas quando pensamos no Ionic, dentre elas:

  • Estabilidade na criação de aplicações híbridas: Apesar de utilizar HTML, CSS e JS para o desenvolvimento das aplicações, o Ionic entrega um produto altamente estável e com desempenho similar ao de aplicativos nativos;

  • Multiplataforma: Com o Ionic, podemos desenvolver um único código que seja executado em diferentes sistemas operacionais, diminuindo o tempo de desenvolvimento de novas aplicações.

  • Menor tempo de desenvolvimento: Por criar aplicações multiplataforma, o tempo no desenvolvimento dessa aplicação se torna algo vantajoso em relação às aplicações nativas, uma vez que todo código criado será reutilizado para qualquer sistema operacional móvel, diminuindo assim o tempo de desenvolvimento;

  • Menor custo: Uma vez que poupamos o tempo em seu desenvolvimento, estamos poupando os custos desta aplicação, fazendo com que, criar aplicações multiplataforma torne-se algo mais rentável e menos custoso;

  • Prototipação: Criar telas no Ionic é extremamente fácil, pois possui uma ferramenta para esta finalidade, o Ionic Creator, que é uma ferramenta de “arrasta e solta” para facilitar as ideias de criação de suas aplicações que pode ser acessada neste link;

  • Documentação: Além de possuir uma grande comunidade, a documentação do Ionic é bastante completa, entre outras.

O futuro do Ionic

Como dito acima, o Ionic Framework encontra-se na versão 4, lançado no ano de 2019. Esta versão mais recente foi reprojetada para funcionar como uma biblioteca independente de componentes da web, com integrações para os mais recentes frameworks JavaScript, como o Angular, Vue e React. Ou seja, com a nova versão do Ionic, podemos criar aplicativos híbridos utilizando qualquer framework javascript, como Vue, Angular e React.

O Ionic é um excelente framework que, com certeza, poderá ser utilizado para criar aplicativos dos mais diversos segmentos. Sendo assim, este framework é um forte candidato a ser o seu próximo queridinho no desenvolvimento de aplicativos móveis.

JavaScript: você sabe o que são e por que usar Symbols?

Olá web developers!

Desde o ES2015 nós temos um novo tipo primitivo no JavaScript, os Symbols. Este tipo já existe em outras linguagens como o Ruby, onde é muito utilizado (no JavaScript seu funcionamento é um pouco diferente). Porém, no JavaScript ele ainda é pouco conhecido. Vamos conhecer melhor os Symbols e onde eles podem ser usados.

O que são Symbols?

De modo bem simples e direto, Symbol (símbolo) é um tipo primitivo que armazena um valor único. Seu propósito é esse, servir como um identificador único.

Pense neles como as suas digitais: até irmãos gêmeos idênticos possuem o mesmo DNA mas possuem digitais diferentes, significando que cada dedo é único.

Como os Symbols funcionam?

Para declarar um Symbol basta usar a função Symbol().

const meuSymbol = Symbol();

Também podemos passar para esta função um parâmetro que indica uma descrição do Symbol. Isso serve apenas para nos ajuda na hora de debugar o código, para sabermos melhor sobre do que se trata aquele Symbol. Não muda nada em sua criação.

const meuSymbol = Symbol('meu simbolo');

Como Symbols são únicos, mesmo que a gente os crie de forma igual teremos Symbols diferentes.

Symbol('meu simbolo') === Symbol('meu simbolo'); // false

Onde usar Symbols?

E por que usar Symbol? Onde seria interessante o seu uso? Vamos ver alguns casos:

JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO

Eficiência no uso de memória

Imagine que a gente tenha um objeto com uma propriedade nome:

const meuObjeto = {'nome': 'TreinaWeb'};

Sempre que chamarmos meuObjeto['nome'] estaremos criando uma String nova na memória, 'nome'. Em um sistema grande com várias chamadas a propriedades de objetos, onde a otimização do uso de memória é essencial, usar Symbols poderia ajudar, já que cada Symbol é único e, portanto, ocupa um único lugar na memória.

const nome = Symbol();
const meuObjeto = {[nome]: 'TreinaWeb'};

Agora sempre que acessarmos a propriedade nome iremos usar o Symbol que está armazenado na variável nome, nos ajudando a melhorar o consumo de memória.

Porém, a gente poderia fazer isso com Strings salvas em constantes, não é mesmo? Acessando a mesma variável também teremos acesso ao mesmo elemento na memória.

const nome = 'nome';
const meuObjeto = {[nome]: 'TreinaWeb'};

Vamos ter o mesmo resultado, mas como agora estamos usando String, um outro programador pode muito bem escrever direto meuObjeto["nome"] para acessar a propriedade, criando uma nova String na memória e jogando no lixo a melhoria que tentamos fazer.

Com Symbols o programador seria forçado a usá-los para acessar as propriedades pois, por serem únicos, não tem como criar um outro idêntico.

Sim, eu sei que o programador poderia escrever meuObjeto.nome e não estaria criando uma nova String, mas isso é só para o exemplo.

Mesmo sendo um caso de uso, não fica muito bonito ter que ficar declarando várias propriedades antes, seja por Symbols ou constantes com Strings. Mas há momentos em que realmente precisamos declarar vários valores que serão constantes, e é aí que entra algo comum em várias linguagens, Enums.

Enums

Enuns são muito usados quando precisamos definir várias constantes.

Imagine que a gente vai desenvolver um jogo e queremos criar constantes para definir as direções que o nosso personagem poderá andar.

// nosso Enum de direções
const directions = {
    RIGHT: Symbol('Right'),
    LEFT: Symbol('Left')
}

/* função a ser chamada
quando o jogador
apertar algum botão,
recebendo a tecla que
foi pressionada
*/
function onButton(key){
    /* lógica para movimentar
    o personagem */
    switch(key){
        case directions.RIGHT: x++; break;
        case directions.LEFT: x--; break;
    }
}

Com Symbols nós obrigamos o programador a utilizá-los. Se usássemos Strings ele poderia escrever em algum lugar case "RIGHT", o que criaria uma nova String. Para termos de manutenção, testes e performance, é melhor evitar ficar escrevendo valores literais pelo código.

Colisão de Nomes

Como Symbols são únicos, é impossível haver colisão de nomes.

Imagine que a gente tenha um módulo JavaScript com um objeto. Esse objeto possui uma propriedade contador que foi criada com Symbol e temos uma função que incrementa o nosso contador.

const contador = Symbol();
export const meuObjeto = {
    [contador]: 1,
    incrementar(){
        meuObjeto[contador]++;
    }
};

Podemos importar nosso objeto e executar o método incrementar(). Porém, mesmo se criarmos uma outra variável contador com Symbol(), não estaremos sobrescrevendo o contador do módulo. Como todo Symbol é único, nossa variável contador de um módulo é diferente da variável contador do outro módulo.

import { meuObjeto } from 'meuArquivo';

meuObjeto.incrementar(); // podemos incrementar

const contador = Symbol();
meuObjeto[contador] = 55; // esta propriedade será outra

Assim evitamos colisões de nomes acidentalmente. Isso pode acontecer caso você utilize duas bibliotecas que armazenam algo no escopo global.

Outro uso interessante para isso é poder acrescentar algo a um objeto já existente em um código, como uma biblioteca. Se você simplesmente alterar algo em um objeto de uma biblioteca, corre o risco de sobrescrever algo importante deste objeto e fazer a biblioteca parar de funcionar corretamente. Mesmo que você escolha um nome que não esteja em uso, há o risco de lançarem uma atualização utilizando exatamente este nome de propriedade.

Há bibliotecas que criam variáveis com "@@" ou "__" como prefixo de nomes de propriedades que não devem ser usados. Com Symbols não há como haver esse perigo de algo ser acessado ou sobrescrito sem querer, pois ao criar seu Symbol ele será único.

Separar propriedades do objeto

Quando criamos propriedades em objetos usando Symbols podemos dizer que estas propriedades são “escondidas”. Onde isso poderia ser interessante?

Imagine que a gente possua os seguintes objetos com algumas informações:

const minhaLista = [
    {nome: 'maçã', total: 15, ativo: true},
    {nome: 'banana', total: 28, ativo: true}
];

Object.keys(minhaLista[0]); // ['nome', 'total', 'ativo']

Agora pense que a gente queira jogar os campos “nome” e “total” em uma tabela usando um código que gera uma tabela automaticamente. Cada coluna da tabela deve ser uma propriedade do objeto, então basta pegar um dos objetos e passar para Object.keys() que receberemos um Array com o nome das propriedades. Porém isso nos trará o campo ativo junto, que é um campo que não queremos.

Se criarmos esse campo ativo com Symbols ele não será retornado.

const ativo = Symbol();

const minhaLista = [
    {nome: 'maçã', total: 15, [ativo]: true},
    {nome: 'banana', total: 28, [ativo]: true}
];

Object.keys(minhaLista[0]); // ['nome', 'total']

Esse é um exemplo bem simples, mas que pode ser muito interessante caso você esteja trabalhando com metaprogramação. Para obter uma lista com os Symbols podemos usar a função Object.getOwnPropertySymbols().

Erros sobre Symbols

Propriedades Privadas? NÃO!

Há um certo engano sobre Symbols. Como eles são únicos, algumas pessoas pensam que podemos tentar usá-los para evitar que algo seja acessado.

Imagine que a gente crie um objeto dentro de um módulo. Esse objeto possui uma propriedade criada com um Symbol.

const contador = Symbol();
export const meuObjeto = {
    [contador]: 1
};

/*aqui conseguimos
acessar a propriedade
criada com o Symbol
*/
meuObjeto[contador];

Como o Symbol não foi exportado, não conseguiremos acessar a propriedade de fora do módulo (será mesmo?).

import { meuObjeto } from 'meuArquivo';

meuObjeto[?????]; // não tem como acessar

Mas lembre-se que podemos obter os Symbols de um objeto, então há sim como conseguirmos acessar as propriedades “ocultas”.

import { meuObjeto } from 'meuArquivo';

const meuSymbol = Object.getOwnPropertySymbols(meuObjeto)[0];
meuObjeto[meuSymbol]; // conseguimos pegar o Symbol e acessar a propriedade que armazena o contador

Devido ao fato de podermos recuperar Symbols, eles não garantem propriedades privadas. Há outros meios para se fazer isso.

É impossível haver conflito de Symbols? Nem sempre

Se você criar Symbols como mostrado nesse post (utilizando a função Symbol()), realmente você terá um Symbol único. Mas há outra forma de criá-los.

Symbol('a') === Symbol('a'); // false
Symbol.for('a') === Symbol.for('a'); // true

Symbol.for() é um outro meio de se criar Symbols, mas ele os cria em um tipo de registro global. Então se você criar algo com Symbol.for() e passar um mesmo valor pelo parâmetro tanto em um Service Worker e um iFrame, por exemplo, teremos exatamente o mesmo Symbol.

Então, já que a ideia dos Symbols é serem únicos, prefira evitar o uso de Symbol.for().

Conclusão

A função de Symbols é apenas uma: servir como um identificador único.

Então podemos usá-los muito bem com objetos onde usaríamos alguma String para criar certas propriedades (como os Enums), utilizá-los para inserir metadados ou acrescentar algo em um objeto já existente sem o perigo de sobrescrever algo que possa ser importante para seu funcionamento.

10 Truques do NPM – Você conhece todos?

Olá Web Developers!
Se você trabalha com JavaScript, provavelmente já teve que usar o NPM. Mas normalmente as pessoas usam essa ferramenta apenas para baixar bibliotecas ou frameworks.

Vamos ver alguns truques que podemos fazer com o NPM.

Npm - Gerenciador de pacotes para JavaScript
Curso de Npm - Gerenciador de pacotes para JavaScript
CONHEÇA O CURSO

1 – Crie ferramentas executadas diretamente da linha de comando

Com o NPM nós podemos criar ferramentas executadas diretamente do terminal inteiramente com JavaScript.
Já tivemos um post aqui ensinando como fazer isso, que você pode conferir neste link.

2 – Atalhos para os comandos mais comuns

É sempre bom saber o nome curto de um comando, permitindo escrever menos:

ComandoAtalho
installi
listls
testt
--global-g
--save-S
--save-dev-D

3 – Abrir o site do projeto

O comando home permite abrir o site de alguma biblioteca ou framework em seu navegador.

O código abaixo irá abrir o site do jQuery em seu navegador:
$ npm home jquery.

4 – Abrir o repositório do projeto

O comando repo permite abrir o site do repositório de alguma biblioteca ou framework em seu navegador.

O código abaixo irá abrir o repositório do lodash em seu navegador:
$ npm repo lodash.

5 – Procurar por pacotes não declarados no package.json

É um grande problema quando alguém esquece de indicar uma dependência no package.json. Mas não tem problema, pois com o seguinte comando você poderá ver quais são os pacotes utilizados no seu projeto que não estão listados:
$ npm prune

6 – Inicie um pacote rapidamente

O comando $ npm init nos permite iniciar um pacote, criando o arquivo package.json de acordo com certas respostas que damos às perguntas feitas.

Mas você pode pular as perguntas, fazendo com que o arquivo package.json seja criado imediatamente. Basta adicionar -y ao comando:
$ npm init -y

7 – Analisar dependências desatualizadas

Também podemos verificar se há dependências desatualizadas em nosso projeto. Basta executar o comando
$ npm outdated

8 – Trave a versão de suas dependências

Se quiser travar a versão das dependências do seu projeto, simplemente execute o comando
$ npm shrinkwrap

Isso irá criar um arquivo npm-shrinkwrap.json. Ao instalar as dependências do projeto, as versões definidas neste arquivo que serão levadas em consideração.

9 – Instalação de produção

No package.json nós podemos salvar as dependências em dependencies e devDependencies. Esta última é a lista de dependências usadas apenas durante o desenvolvimento.

Caso você não vá desenvolver nada onde está instalando seu projeto, com o seguinte comando é possível instalar as dependências do projeto, ignorando as dependências de desenvolvimento:
$ npm install --production

10 – Lista de pacotes instalados

Podemos ver uma lista de pacotes instalados com o comando:
$ npm ls --depth 0

Esse comando é ainda mais útil quando queremos saber quais módulos globais possuímos instalado em nossa máquina:
$ npm ls -g --depth 0

Conclusão

O NPM é uma ferramenta que muitos usam mas poucos sabem usar totalmente o seu poder. Para mais informações, confira nosso Curso de NPM.

Npm - Gerenciador de pacotes para JavaScript
Curso de Npm - Gerenciador de pacotes para JavaScript
CONHEÇA O CURSO

Criando módulos globais do NPM

Olá Web Developers!

Que tal criar seus próprios programas que rodem diretamente do terminal usando JavaScript?
Com o NPM é muito simples de se fazer isso!

O que é NPM?

Se você trabalha com JavaScript, provavelmente já teve (ou terá em algum momento) que usar o Node.js. O gerenciador de bibliotecas mais comum é o NPM, que também pode servir para outras coisas, como mostramos em nosso curso de NPM.

Npm - Gerenciador de pacotes para JavaScript
Curso de Npm - Gerenciador de pacotes para JavaScript
CONHEÇA O CURSO

O que são módulos globais?

Além de códigos de terceiros, o NPM também nos permite instalar em nossa máquina programas que são executados a partir do terminal feitos inteiramente com JavaScript.

Esses programas, que podem ser executados pelo terminal de qualquer parte de seu computador, são chamados de módulos globais.
Os mais comuns são ferramentas como o Angular CLI, que nos ajudam a criar e gerenciar projetos Angular.

Imagine então poder criar um programa feito com JavaScript que pode ser facilmente instalado com o NPM e executado pelo terminal?
Você pode criar coisas como um servidor, um conversor de arquivos, um automatizador de tarefas, etc.

São várias possibilidades que vão depender da sua imaginação. Vamos criar um exemplo bem simples em 5 passos!

1 – Crie seu código principal

Vamos começar pelo código que será executado. Será bem simples: ele irá imprimir o texto “Olá Web Developers!”.

Para já deixarmos tudo organizado, vamos criar um diretório para nosso módulo. Eu vou chamar de meu-modulo.

Dentro deste diretório crie um outro diretório para guardar seus códigos. Isso não é obrigatório, mas nos ajuda a deixar tudo mais organizado.
Vamos criar um diretório chamado lib.

Dentro de lib vamos finalmente criar o arquivo que terá nosso código. Você pode dar qualquer nome. Vamos chamá-lo de index.js.
Terá o seguinte código:

function ola(nome){
    const texto = `Olá ${nome || 'web developer'}!`;
    console.log(texto);
}

exports.ola = ola;

Criamos um arquivo comum para Node.js. Temos uma função ola() que ao ser executada imprime “Olá web developer!” caso nenhum nome seja passado. Se tivermos algum nome, ele substituirá “web developer”.

No final exportamos esta função para poder utilizá-la em outro arquivo.

2 – Prepare o seu módulo

Vamos preparar nosso módulo agora.
No diretório raiz (meu-modulo), execute o comando $ npm init -y. Isso irá criar automaticamente o arquivo package.json para nós. Ele é muito importante para a sua biblioteca saber o que ela precisa instalar e os comandos disponíveis para serem executados.

Você pode editar o package.json para arrumar algumas coisas e adicionar mais informações. Ele ficará com o conteúdo parecido com o mostrado a seguir:

{
  "name": "meu-modulo",
  "version": "1.0.0",
  "description": "meu modulo global",
  "main": "./lib/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "hanashiro",
  "license": "MIT"
}
Npm - Gerenciador de pacotes para JavaScript
Curso de Npm - Gerenciador de pacotes para JavaScript
CONHEÇA O CURSO

3 – Crie os arquivos do módulo global

Agora chegou o momento de criarmos o arquivo que o terminal irá executar quando chamarmos nosso programa.

Primeiro crie um novo diretório chamado bin dentro de meu-modulo. Lembrando que isso não é obrigatório, estamos seguindo isso para tudo ficar mais organizado.

Dentro de bin crie o arquivo meu-modulo-legal.js com o seguinte conteúdo:

#!/usr/bin/env node

const ola = require('../lib/index.js').ola;
ola();

Nós simplesmente importamos a nossa função e a executamos. O que temos de diferente aqui é a primeira linha com o #!/usr/bin/env node.
Esta linha é fundamental para que o NPM gere um executável corretamente.

Lembre-se que este arquivo meu-modulo-legal.js que será executado.

4 – Configure a instalação global

Precisamos indicar qual o nome do comando ficará exposto para ser chamado no terminal e qual arquivo este comando deverá executar.

Para isso, adicione o seguinte código ao package.json:

{
    ...
    "bin": {
      "diga-ola": "./bin/meu-modulo-legal.js"
    },
    ..-
}

Isso permitirá que quando a gente abrir o terminal, possamos executar o comando diga-ola, e ele irá executar o arquivo meu-modulo-legal.js.

Lembre-se que as pessoas podem acabar instalando o seu módulo localmente. Se a sua ferramenta for algo que é melhor utilizada como um módulo global, você pode adicionar a seguinte linha ao package.json:

{
    ...
    "preferGlobal": true,
    ..-
}

Com esta linha o usuário ainda poderá instalar o seu módulo localmente, mas ele receberá um aviso indicando que é melhor instalar globalmente.

5 – Instale seu módulo globalmente para testá-lo

Agora só falta testarmos. Acalme-se, pois você não precisa publicar o seu módulo em algum repositório como o NPM ou Github para poder fazer o teste.

Para instalar globalmente o seu módulo, basta executar o comando npm install -g junto com o caminho do diretório que criamos (meu-modulo).

Ex: $ npm install -g C:\Users\seu-usuario\Desktop\meu-modulo

Ao instalar você já estará pronto para executar diretamente de seu terminal (de qualquer parte de seu computador) o comando $ diga-ola.

Extra: Parâmetros

Algo muito comum em programas executados pela linha de comando é permitir que a gente passe alguns parâmetros para configurar a função que será executada.

Lembra que nossa função permitia receber um nome? Pois vamos permitir que o usuário escreva o nome que ele quiser pela linha de comando.

Mude o arquivo meu-modulo-legal.js para ficar da seguinte maneira:

#!/usr/bin/env node

const args = process.argv.splice(process.execArgv.length + 2),
    nome = args[0];

const ola = require('../lib/index.js').ola;
ola(nome);

Primeiro pegamos os parâmetros passados no comando, e então pegamos o primeiro parâmetro e jogamos em uma constante chamada nome, passando-a para a nossa função ola().

Agora instale o seu módulo novamente para que o módulo instalado globalmente seja atualizado.

Se executar $ diga-ola você terá a resposta “Olá web developer!”, mas se executar $ diga-ola TreinaWeb terá “Olá TreinaWeb!”.

Conclusão

Agora você já sabe como criar seus próprios módulos globais, permitindo criar ferramentas com JavaScript e executá-las diretamente do terminal.

Agora basta você publicar no repositório do NPM para que outras pessoas possam usar.

Criou alguma ferramenta? Nos conte aí nos comentários!

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200