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.

Flow

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:
    1. Baixar o binário em http://flowtype.org/
    2. 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.
    3. 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.
  2. (OPCIONAL) Instalar o Nuclide (apenas para uso no Atom):
    1. Instale o pacote nuclide via interface do Atom.
    2. (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
[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
[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
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