Base para um grande SPA modular no Laravel + Vue + ElementUI com gerador CRUD

imagem

Nos últimos anos, consegui trabalhar em vários projetos grandes e não muito, usando diferentes estruturas de back-end e front-end. Diante de vários problemas que surgiram à medida que o aplicativo cresceu.

Agora posso concluir a partir de quais soluções foram bem-sucedidas e quais não foram muito bem-sucedidas.
Usando a experiência acumulada, decidi coletar todas as melhores soluções, na minha opinião, e criar minha própria base para o SPA.

Como criar um site no Laravel ou o que é o SPA, não vou contar. Há informações suficientes na Internet. Este artigo é destinado a desenvolvedores mais ou menos experientes, por isso vou perder alguns detalhes.

Quem não pode esperar, no final do artigo, há um link para meu repositório do github.

As principais tecnologias foram selecionadas pelo Laravel e Vue.js + Vuex, pois esta é minha pilha principal.

Para um rápido desenvolvimento, usei o UI Kit - ElementUI .

o objetivo principal


Para criar uma base para um projeto de médio e grande porte que:

  • ajudará a evitar a coesão rígida dos módulos
  • compreensível para um programador com pouca experiência
  • ajudar a evitar a duplicação de código
  • será fácil expandir
  • reduzir a hora de início do projeto
  • reduzir o tempo de suporte ao projeto e navegação de código

Para tornar a vida o mais fácil possível, para não se confundir no projeto, você precisa estruturar adequadamente o seu ego. Inicialmente, o aplicativo deve ser dividido em níveis de responsabilidade, como interface do usuário, banco de dados, lógica de negócios.

Além disso, cada camada deve ser dividida primeiro pela funcionalidade e, em seguida, cada módulo funcional deve ser dividido de acordo com o padrão selecionado.

Inspirado na filosofia DDD, decidi dividir o front-end e o back-end em módulos semânticos. Mas esses não são os domínios clássicos que Evans descreve. Seu modelo também não é perfeito. Em qualquer aplicativo, ao longo do tempo, os relacionamentos entre os componentes sempre aparecem - os mesmos relacionamentos entre os modelos.

Ele deixou os modelos como uma camada separada, porque eles pareciam duplicar o banco de dados, com todas as suas conexões.

Criou um diretório na frenterecursos / js / modules , nos quais diferentes módulos serão localizados. Cada um terá API - métodos para trabalhar com o back-end, componentes - todos os componentes e páginas, armazenamento - armazenamento e rotas .

{moduleName}/
├── routes.js
├── api/
│   └── index.js
├── components/
│   ├── {ModuleName}List.vue
│   ├── {ModuleName}View.vue
│   └── {ModuleName}Form.vue
└── store/
    ├── store.js
    ├── types.js
    └── actions.js

Em resources / js , a pasta principal é criada , onde estão localizados os principais componentes do sistema.
Também há autoinicialização e inclui pastas para configurar bibliotecas e utilitários adicionais, respectivamente.

O projeto utiliza carregamento dinâmico de modelos. Ou seja, no núcleo / rotas e no núcleo / estados, carregamos os arquivos de roteamento e armazenamento correspondentes automaticamente (nada precisa ser registrado).

Aqui está um exemplo de como store.js foram carregados de diferentes módulos automaticamente.

// Load store modules dynamically.
const requireContext = require.context('../../modules', true, /store\.js$/) 
 
let modules = requireContext.keys() 
    .map(file => 
        [file.replace(/(^.\/)|(\.js$)/g, ''), requireContext(file)] 
    )
    .reduce((modules, [path, module]) => { 
        let name = path.split('/')[0] 
        return { ...modules, [name]: module.store } 
    }, {})
 
modules = {...modules, core} 
 
export default new Vuex.Store({
    modules
})
 

No back-end no diretório do aplicativo, haverá módulos semelhantes. Cada módulo conterá pastas Controladores, Solicitações, Recursos . O arquivo com rotas também foi movido para cá - routes_api.php .

{ModuleName}/
├── routes_api.php
├── Controllers/
│   └──{ModuleName}Controller.php
├── Requests/
│   └──{ModuleName}Request.php
└── Resources/
    └── {ModuleName}Resource.php
 

Outros padrões de design, como eventos, trabalhos, políticas, etc. não serão incluídos nos módulos, pois eles são usados ​​com menos frequência e é mais lógico mantê-los em uma camada separada.

Todas as manipulações com o carregamento dinâmico dos módulos são feitas para que o engajamento mínimo seja superado entre eles. Isso permite adicionar e remover módulos sem consequências. Agora você pode fazer com que o artesão faça o comando para criar esse módulo. Com sua ajuda, podemos preencher rapidamente o projeto com as entidades necessárias, juntamente com a funcionalidade CRUD.

Após a execução do comando php artisan make:module {ModuleName}, teremos todos os arquivos necessários, incluindo o modelo e as migrações, para que o CRUD completo funcione. Você só precisa concluir a migraçãophp artisan migratee tudo vai funcionar. Provavelmente, você precisará adicionar campos adicionais; portanto, antes da migração, não esqueça de adicioná-los ao modelo, migração e também a saída para o vue.



Neste modelo, a tecnologia JWT-Auth foi usada para autenticação , mas pode ser redundante e deve ser refeita no Laravel Sanctum. Por sua vez, o vue-auth é usado no front-end , facilita o gerenciamento de autorização e funções do usuário.

No futuro, eu gostaria de melhorar o sistema. Adicione um barramento de eventos global, conecte websockets. Adicione testes. É possível criar uma opção de gerenciamento de função em ramificações separadas ou criar ramificações com outro kit de interface do usuário. Seria bom ouvir recomendações, comentários.

Inicialmente, este modelo foi desenvolvido para suas necessidades, mas agora espero que seja útil para outros usuários.

Todo o código pode ser visualizado no meu repositório do github .

All Articles