Aventuras com Flow + Atom (JavaScript)

Flow é um static type checker criado pelo Facebook que ajuda bastante no desenvolvimento JS :D. Mais informações no site oficial.
O Flow pode ser utilizado tanto como uma ferramenta CLI quanto integrado à IDEs. Veremos como usá-lo dentro do Atom.

O post segue o formato “receita-de-bolo” e é destinado ao “eu-do-futuro-que-esqueceu-isso”. Mas pode ser útil para terceiros que sabem o que é um static type checker e conheçam JavaScript :D.

O suporte ao Flow dentro do Atom é mais completo utilizando o pacote Nuclide que é desenvolvido também pelo Facebook e visa oferecer um ótimo suporte às tecnologias da empresa (como React, react-native, flow, …). Portanto, instalaremos tanto o Flow quanto o Nuclide.

Nota: Atualmente o Flow não funciona em Windows. Apenas GNU/Linux e Mac. O Nuclide funciona apenas parcialmente em Windows.

Instalação

  1. Instalar Flow:
  2. Baixar o binário em http://flowtype.org/
  3. Extrair o pacote para um dir desejado. Ex: unzip ./path/flow-linux64-v0.22.1.zip. Pronto! Será criado o dir flow com o binário flow dentro.
  4. Basta agora criar um link do binário para /usr/local/bin ou de alguma outra forma inserir o binário no $PATH do user ou sistema.
  5. (OPCIONAL) Instalar o Nuclide (apenas para uso no Atom):
  6. Instale o pacote nuclide via interface do Atom.
  7. (OPCIONAL) É recomendado desabilitar o pacote linter (caso esteja instalado), deixando o Nuclide utilizar sua solução própria (nuclide-diagnostics) e que é compatível com todos os plugins que dependem do linter.

Nota: A instalação do nuclide pode ser objeto de alguns cuidados posteriores para uma experiência mais completa: http://nuclide.io/docs/editor/setup/

Utilização

  • Para utilizarmos o flow necessitamos que o projeto atenda dois requisitos:

    1. Possuir um arquivo de configuração do flow (.flowconfig).

    O mesmo pode ser criado sem conteúdo ($ touch ./projeto/.flowconfig) ou através do comando “$ flow init“ que criará no dir em que for invocado um arquivo com as seções básicas de configuração do flow vazias.

    Ao ser invocado, o flow irá buscar pelo .flowconfig no dir em que for invocado, caso não encontre, tentará nos dirs pais.
    2. Somente serão checados os arquivos JavaScript que possuam o comentário “// @flow“ no topo do arquivo. Isso permite utilizarmos o flow de forma incremental em projetos.

  • Para utilizar o flow via prompt, basta invocarmos no dir do projeto: $ flow. Se desejarmos um arquivo em específico: $ flow arquivo.js. Mais informações na documentação oficial.

  • Para utilizar o flow via Atom, tendo o projeto atendido as 2 necessidades elencadas acima, basta ter instalado o Nuclide.

Configuração

Saber configurar o .flowconfig é essencial para que o flow funcione de forma rápida e sem jogar uma avalanche de alertas caso suas dependências também sejam passíveis de análise pela ferramenta.

Em meu caso, ao desenvolver utilizando o react-native houve sérios problemas de performance pois o .flowconfig oferecido varria todas as dependências do projeto. A solução foi ignorar os arquivos existentes em projeto/node_modules e adicionar interfaces para que o flow não reclamasse dos módulos importados de node_modules em meu código (e que o mesmo não estava apto a encontrar pois eu forçava que fossem ignorados).

A configuração do .flowconfig foi feita da seguinte forma:

  • Na seção ignore foi adicionado o dir node_modules:
1
2
3
[ignore]

.*/node_modules/*
  • Na seção libs foi apontado o dir contendo as declarações de interfaces para módulos que o flow não irá encontrar (pq são códigos de terceiros localizados em node_modules que optamos por ignorar):
1
2
[libs]
flow-interfaces

No dir projeto/flow-interfaces adicionamos o arquivo react-native.js com interface para o módulo react-native. O arquivo ficou assim:

1
2
3
4
5
6
7
declare module "react-native" {
declare var AppRegistry: any;
declare var Component: any;
declare var StyleSheet: any;
declare var Text: any;
declare var View: any;
}

Essa é só uma passada superficial pelo .flowconfig, mais informações sobre o mesmo na documentação oficial e, mais especificamente, como lidar com código de terceiros aqui.

Ps: Atenção que se o .flowconfig possuir a sessão [version], a versão do flow deve ser atendida, caso contrário o mesmo não será executado.

Obs: Versões utilizadas na confecção do post:

  • flow: 0.22.1
  • nuclide: 0.124.0
  • atom: 1.5.3