https://a.storyblok.com/f/270183/26686/e4c795fc02/blog_next-cli_part2_1200x600.png

Comparando bibliotecas de construção da CLI

Publicado em April 20, 2021

Tempo de leitura: 6 minutos

A Nexmo possui um CLI, que usamos como alternativa ao Painel de Controle. Ela permite que você gerencie sua conta da Nexmo e utilize os produtos da Vonage a partir da linha de comando. Já temos essa ferramenta há cerca de 4 anos, e ela foi desenvolvida em Node.js.

Na semana passada escrevi sobre por que estamos dedicando tempo para reescrevê-loe falei um pouco sobre o processo que estamos usando para reescrever a CLI do Nexmo.

Hoje, vou entrar em mais detalhes, compartilhar as estruturas que analisamos e os critérios que utilizamos para isso. Também vou mostrar a vocês alguns prós e contras das que escolhemos para desenvolver nossas provas de conceito.

Critérios de referência

Depois de realizarmos nossa retrospectiva interna sobre a CLI e identificarmos um conjunto de requisitos, elaboramos uma lista de comandos de exemplo. Esses comandos nos ajudaram a definir um conjunto de critérios para avaliar as bibliotecas utilizadas na criação de interfaces de linha de comando. Nossos critérios visavam responder a algumas perguntas:

  • Qual linguagem a biblioteca suporta?

  • Ele é mantido ativamente?

  • Ele suporta subcomandos? Ou seja, nexmo app list

  • Ele possui suporte integrado para vários formatos de saída?

  • Ele possui um mecanismo de plug-ins?

  • Os comandos podem ter vários aliases?

  • Ele consegue gerar arquivos binários?

  • Como funciona o gerenciamento de configurações?

  • É multiplataforma?

  • Ele possui autocompletar de comandos?

  • Ele pode ter comandos interativos?

  • É possível definir variáveis globais?

Munidos dessa lista de questões urgentes, partimos em uma busca para identificar o maior número possível de bibliotecas de construção de CLI que atendessem à maioria dos requisitos e comparamos seus recursos com nossa lista de critérios de qualificação. No final, reduzimos a lista a seis bibliotecas — para JavaScript, TypeScript e Go — com base nos conhecimentos de linguagem disponíveis na equipe: oclif, gluegun, ink, caporal, cli e cobra.

Comparação de recursos

Analisamos a página inicial de cada framework e identificamos os recursos que eles ofereciam, criando uma matriz de análise. Usamos o símbolo ✓ para indicar que o framework oferece suporte total a esse recurso, ❎ para indicar que não oferece suporte e ✳️ para indicar que há apenas suporte parcial. Veja a seguir como ficou nossa matriz para os seis frameworks que identificamos:

Framework oclif gluegun ink caporal cli cobra
Language JS/TS JS React JS Go Go
Maintained ✳️
Sub-command
Output Formats ✳️ ? ?
Plugins ✅✅ ? ?
Alias
Bin ? ?
Config Management ? ?
Windows Support ✳️
Autocomplete plugin
Interactivity ✳️ ? ?
Global flag definition

Ao analisar a lista de recursos, não conseguimos identificar um vencedor claro, especialmente porque ainda havia algumas incertezas. Por isso, decidimos escolher três frameworks e desenvolver uma prova de conceito com cada um deles.

PoCs

Nossa primeira escolha para criar uma prova de conceito foi oclif. O principal motivo pelo qual o escolhemos foi porque ele parecia atender à maioria dos nossos requisitos, alguns até duas vezes (ele oferecia suporte a plug-ins e contava com um plug-in para criar outros plug-ins).

A segunda escolha foi caporal porque a biblioteca parecia razoavelmente semelhante à nossa estrutura atual, commander. Isso significaria que a curva de aprendizado e o tempo necessário para reescrevê-la teriam sido consideravelmente menores.

Por fim, nossa última escolha para as provas de conceito foi ink, e a escolhemos porque atendia a critérios suficientes para valer a pena e conta com um ecossistema enorme por trás.

Depois de identificarmos as estruturas, definimos o escopo para as provas de conceito. Queríamos algo que fosse representativo da CLI final, em vez de criar um Hello World exemplo. Ao mesmo tempo, precisava ser pequeno o suficiente para que não nos sentíssemos mal em descartar a prova de conceito ao final deste exercício. Decidimos construir a versão atual nexmo setup e nexmo number:list . Isso significava que poderíamos testar sinalizadores globais, gerenciamento de configuração, subcomandos, formatos de saída, interatividade e várias estruturas de linguagem.

Escolhendo nossa próxima biblioteca para desenvolvimento de CLI

Lorna, Dwane e eu escolhemos, cada um, uma das três estruturas e começamos a desenvolver nossas provas de conceito. Assim que terminamos, apresentamos alguns dos prós e contras de trabalhar com cada biblioteca e como isso se relaciona com alguns de nossos outros requisitos.

Caporal

Lorna criou o caporal PoC. A maior vantagem disso foi que foi possível migrar nossa CLI atual de commander para caporal sem precisar reescrevê-la por completo. Isso nos pouparia bastante tempo.

As desvantagens eram, em grande parte, semelhantes às nossas commander limitações, e o projeto não é mantido tão ativamente quanto gostaríamos. Provavelmente teríamos que criar um fork do projeto e manter uma comunidade em torno dele, o que anularia parte da agilidade que ganhamos por não precisarmos reescrever o código. Isso também significaria que alguns de nossos requisitos, como plug-ins, precisariam ser desenvolvidos do zero.

Tinta

Dwane desenvolveu o ink PoC. A maior vantagem era que ele usava o React como framework, o que traz consigo uma enorme comunidade e um ecossistema robusto. Havia muitos plug-ins disponíveis para a maioria das funcionalidades que queríamos para nossa próxima CLI, mas alguns deles ainda não eram compatíveis com a versão mais recente ink . Ele também oferecia comparação de código semelhante ao React para a saída do terminal, o que significava que poderíamos não apenas criar comandos interativos, mas também ter uma saída dinâmica. As desvantagens não eram poucas; uma delas era o fato de ser baseado no React, e a equipe precisava estar familiarizada com ele. Outra desvantagem era que ink por si só não era adequado para uma CLI grande como a nossa.

pastel, por outro lado, era uma estrutura mais adequada, desenvolvida com base em ink, que nos oferecia as mesmas vantagens; por isso, o Dwane desenvolveu uma prova de conceito (PoC) usando essa estrutura. pastel No entanto, ele apresentava suas próprias desvantagens, principalmente o fato de não ter recebido manutenção ativa no último ano, com o último lançamento ocorrido há 10 meses.

Oclif

Eu criei o oclif PoC. A maior vantagem foi que oclif atendeu à maioria dos nossos requisitos, e funcionou conforme prometido. Assim, não precisaríamos desenvolver grande parte da funcionalidade para os requisitos que não são voltados ao usuário, como um sistema de plug-ins. Ele também era mais adequado para a criação de grandes interfaces de linha de comando (CLIs). As convenções de estrutura de código que ele utiliza facilitam a manutenção do código.

No entanto, isso também trouxe uma série de desvantagens. Embora o site anuncie que tanto o JavaScript quanto o TypeScript são suportados, a documentação era bastante voltada para o TypeScript, a ponto de a maioria dos casos de uso avançados não estar documentada em JavaScript.

O fato de eu ter escolhido o TypeScript para desenvolver o PoC também significou que a importação do SDK do Nexmo para Node.js tal como está seria problemático; por isso, precisaríamos dedicar algum tempo para adicionar suporte ao TypeScript a ele primeiro.

E agora?

Depois de analisar cuidadosamente como todos esses prós e contras nos afetavam, decidimos seguir em frente e desenvolver a próxima CLI do Nexmo usando oclif.

Escolhemos essa opção porque o suporte e a documentação eram excelentes, além da crescente comunidade de usuários. Ela também recebe manutenção ativa. Além disso, estamos adicionando suporte completo ao TypeScript ao nosso SDK do Node.js, então nos pareceu uma boa ideia manter a mesma pilha de tecnologias tanto no nosso SDK quanto na CLI.

Enquanto trabalhamos para aprimorar nossa CLI do Nexmo, você pode acompanhar nosso progresso em https://github.com/nexmo/nexmo-cli. Se você tiver alguma sugestão ou problema, sinta-se à vontade para relatá-los no GitHub ou em nossa Slack da comunidade.

Compartilhar:

https://a.storyblok.com/f/270183/384x384/dabe7c5397/laka.png
Alex LakatosEx-funcionários da Vonage

Alex Lakatos é um Developer Advocate de JavaScript na Nexmo. Em seu tempo livre, ele atua como voluntário na Mozilla como palestrante técnico e mentor do programa Reps. Como desenvolvedor de JavaScript que trabalha na web aberta, ele vem ampliando seus limites a cada dia. Quando não está programando em Londres, ele gosta de viajar pelo mundo; por isso, é provável que você o encontre em um lounge de aeroporto.