Os seres humanos têm dificuldade em ver o panorama geral de um problema sem dedicar muito tempo e esforço. Isto acontece especialmente quando se trabalha com aplicações grandes e complexas. Quais são os efeitos secundários das minhas alterações? Porque é que esta linha aqui está a afetar os testes de uma parte remota da base de código? Não existe uma solução perfeita ou completa, mas a Shopify lançou uma ferramenta que provavelmente o ajudará a si e à sua equipa.
Introdução
Para falar sobre PackwerkPara isso, é necessário introduzir alguns conceitos.
- Coesãorefere-se à medida de quanto os elementos de um módulo ou classe pertencem uns aos outros.
- Acoplamentorefere-se ao nível de dependência entre módulos ou classes.
- Limites: refere-se a barreiras entre código. Neste caso, uma fronteira de código refere-se a diferentes domínios de interesse dentro da mesma base de código.
- ModularizaçãoProcesso de divisão de um sistema de software em vários módulos separados, em que cada módulo funciona de forma independente.
Problemas
Como sabemos, Rubi não fornece uma boa solução para impor limites de código. Podemos especificar a visibilidade, mas todas as dependências serão carregadas no espaço de nomes global. Em aplicações grandes ou monolíticas, essa falta de limites produz os seguintes problemas.
- Baixa coesão,
- Acoplamento elevado,
- Código esparguete.
Numa tentativa de modularizar o monólito da Shopify e impor limites, tentaram diferentes soluções sem obter os resultados esperados:
- Definição de constantes privadas,
- Estabelecer limites através de gemas,
- Utilizar testes para evitar associações entre componentes,
- Utilizando a gema Modulation do Ruby,
- Criação de microsserviços.
Com todos os conhecimentos adquiridos em tentativas anteriores, decidiram criar a sua própria ferramenta: Packwerk.
Packwerk
O que é o Packwerk?
Packwerk é uma ferramenta de análise estática utilizada para impor limites entre grupos de Rubi ficheiros chamados pacotes.
O que é um pacote?
A pacote é uma pasta que contém código carregado automaticamente. A pasta equipa incentiva a utilização das melhores práticas de conceção na criação de pacotes.
- Devemos juntar coisas que tenham um elevado nível de funcionalidade coesão,
- Os pacotes devem ser acoplados de forma relativamente flexível uns aos outros.
Tipos de controlos de fronteira
Podemos impor limites de privacidade e de dependência, verificar as violações dos limites e as dependências cíclicas.
Packwerk na prática
Não existe uma única forma específica de estruturar ou reestruturar a sua aplicação ao criar pacotes. Neste artigo, vamos seguir a abordagem sugerida por
Stephan Hagemann em Modularização gradual para Ruby on Rails.
Escolher o projeto
É possível criar um novo projeto ou escolha um dos seus projectos. Decidi utilizar um projeto de código aberto chamado CodeTriage. É importante referir que precisamos de um Carris 6 aplicações desde Packwerk utiliza Zeitwerk.
Inicializar o Packwerk
Primeiro, precisamos adicionar a gem ao nosso Gemfile como gem 'packwerk' e, em seguida, executar feixena consola. Em seguida, estamos prontos para inicializar a gem executando packwerk init.
Depois disso, verificamos que Packwerk gerou três ficheiros para nós:
-
packwerk.yml
-
package.yml
-
inflexões.yml
packwerk.yml é o ficheiro de configuração do Packwerk onde definiremos os ficheiros incluídos e excluídos, listaremos os caminhos de carregamento, definiremos o ficheiro de inflexões, entre outras coisas;
package.yml é o ficheiro de configuração de um pacote. Neste ficheiro, iremos adicionar a configuração para os limites do nosso pacote. Qualquer pasta com package.yml será reconhecida como um pacote pelo Packwerk. É isso mesmo, Packwerk criou o nosso primeiro
e chamamos-lhe o pacote raiz pacote.
inflexões.yml é onde colocaremos as nossas inflexões e acrónimos personalizados, caso os estejamos a utilizar.
Pode obter mais informações sobre os ficheiros e a sua configuração em
Packwerk.
Packwerk propriedades
Para que a modularização funcione, são necessárias três propriedades básicas: um contentor nomeado, o seu conteúdoe explícito dependências noutros contentores. Então vamos definir essas propriedades em Packwerk:
-
Nome: O nome de um pacote é o seu caminho relativo a partir da raiz do diretório
aplicação.
-
Conteúdo: Quando colocamos um package.yml numa pasta, todos os ficheiros na pasta são agora o conteúdo do pacote.
-
Dependências: Podemos definir dependências de outros pacotes adicionando a chave de dependências ao package.yml.
Outro ficheiro que não é incluído por defeito mas é recomendado é o README. Ele é importante para fornecer informações sobre o uso do pacote.
O Fim do Episódio I

Ler mais
Ruby GraphQL. E quanto ao desempenho?
Carris e outros meios de transporte
Desenvolvimento Rails com TMUX, Vim, Fzf + Ripgrep