Vuex: estruturando grandes projetos e trabalhando com módulos

O Vuex é uma biblioteca oficial e bem documentada de gerenciamento de estado de aplicativos, projetada especificamente para o Vue.js. O autor do material, cuja tradução publicamos hoje, acredita que o uso desta biblioteca é muito mais agradável que o Redux, porque, em primeiro lugar, o Vuex requer menos código padrão e, em segundo lugar, pelo fato de funcionar com mecanismos assíncronos, nenhuma biblioteca adicional é necessária aqui. Além disso, como a biblioteca Vuex foi criada pela mesma equipe que trabalha no Vue, essa biblioteca se integra muito bem a essa estrutura. Infelizmente, ao trabalhar com o Vuex, você ainda pode encontrar uma dificuldade, que consiste em preparar adequadamente a estrutura dos projetos nos quais planeja usar esta biblioteca.



Neste artigo, você encontrará uma descrição da metodologia para estruturar grandes projetos usando o Vuex e um script projetado para automatizar o processo de criação dos módulos do Vuex.

Padrão Vue-enterprise-clichê e questão da estrutura do projeto


Um dos desenvolvedores do Vue, Chris Fritz, criou um excelente modelo para o Vue, a estrutura do projeto apresentada na qual foi projetada para usar o Vuex. Em particular, esse modelo permite que o Vuex registre automaticamente módulos com base nos arquivos da pasta de modules . A estrutura de pastas do projeto pode se parecer com a figura a seguir.


Estrutura do projeto e colocação de código inconveniente

Ao usar este modelo, é necessário que o estado, getters, ações e mutações estejam no mesmo arquivo. Pessoalmente, prefiro mantê-los em arquivos separados, o que permite, dado que os módulos Vuex às vezes são bastante grandes, é conveniente navegar pelos programas, sem ter que percorrer enormes pedaços de código. Seguindo essa idéia, alteraremos o código do modelo para que o que se relacione com os módulos individuais possa ser classificado em pastas destinadas a esses módulos. Ou seja, a estrutura do projeto mudará e será semelhante à mostrada abaixo.


A estrutura do projeto com a decomposição dos materiais dos módulos em arquivos separados que estão nas pastas dos módulos

Desenvolvimento de um modelo que suporta uma estrutura de projeto conveniente


Então, vamos organizar o trabalho com o Vuex para que possamos usar estruturas de pastas e arquivos semelhantes às mostradas na figura anterior em nossos projetos. Para fazer isso, primeiro crie um novo projeto usando o Vue CLI 3 .

Depois de ter um modelo de projeto pronto para trabalhar com ele, instale o Vuex e o Lodash executando o npm install vuex lodash -save no terminal. Para trabalhar com módulos, precisamos da função camelCase da Lodash, projetada para converter seqüências de caracteres no estilo camel.

Agora crie uma pasta e uma estrutura de arquivos semelhante à mostrada na figura anterior.

Vamos começar com o arquivo store.js . Aqui está o código dele:

 import Vue from 'vue' import Vuex from 'vuex' import modules from './modules' Vue.use(Vuex) const store = new Vuex.Store({ modules, strict: process.env.NODE_ENV !== 'production' }) //    `init`     for (const moduleName of Object.keys(modules)) { if (modules[moduleName].actions.init) {   store.dispatch(`${moduleName}/init`) } } export default store 

O Vue e o Vuex são importados aqui, pois não podemos ficar sem eles. Além disso, importamos módulos de /modules/index.js . Em seguida, inicializamos o armazenamento e percorremos todos os módulos. Se o módulo tiver uma ação init , inicializamos o módulo. Isso acaba sendo muito útil para os módulos que precisam ser inicializados quando o aplicativo é iniciado. Como resultado, é claro, exportamos a store , após a qual, geralmente, é importada para o arquivo main.js e adicionada à instância do Vue.

Agora é hora de trabalhar com o arquivo index.js , localizado na pasta /store/modules .

 //    Vuex     ,    . import camelCase from 'lodash/camelCase'; //    const requireModule = require.context( //      '.', //     true, //   index.js,    ,    //   'actions', 'mutations',  'getters' . //  ,      .js /^(?!.*(actions|mutations|getters|index)).*\.js$/ ); const modules = {}; requireModule.keys().forEach(fileName => { //     if (/\.unit\.js$/.test(fileName)) return; //            modules[camelCase(fileName.split('/')[1].replace(/(\.\/|\.js)/g, ''))] = {   namespaced: true,   ...requireModule(fileName).default }; }); export default modules; 

Nesse código, primeiro importamos a função camelCase do Lodash. Em seguida, usamos o método require.context para conectar os módulos. Como terceiro parâmetro, passamos uma expressão regular para filtrar o arquivo index.js , além de arquivos cujos nomes contêm as actions , mutations e getters das linhas. Eles serão importados para o arquivo de status, por exemplo, em auth.js e depois exportados. Por exemplo, aqui está como o arquivo auth.js da auth.js src/store/modules/auth/ pode parecer no início do trabalho:

 import actions from './actions'; import mutations from './mutations'; import getters from './getters'; const state = {   user: null }; export default {   state,   mutations,   getters,   actions }; 

Agora resta apenas percorrer todos os módulos e formar um único objeto com todos eles. Aqui, você precisa excluir todos os arquivos nos quais existe uma unit linha, pois eles são necessários apenas para testes, e não para desenvolvimento ou implantação de um projeto em produção. Depois disso, adicionamos uma nova propriedade ao objeto modules , que terá o nome do arquivo de estado, por exemplo, auth ou users . Além disso, usamos a função camelCase para tornar os nomes das propriedades consistentes. Em seguida, preenchemos o objeto modules , requireModule através do requireModule e usando a construção ...requireModule(fileName).default e exportamos os modules .

De fato, é assim que um projeto pode ser estruturado em qual estado, getters, ações e mutações são armazenados separadamente e organizados de maneira conveniente. Agora vamos falar sobre como escrever um script para criar automaticamente módulos Vuex.

Script para criar automaticamente módulos Vuex


Crie uma nova pasta na pasta do projeto com os scripts name, nela crie o arquivo generateVuexModule.js . Para este projeto, precisaremos do Node.js; portanto, se você não tiver esta plataforma instalada, agora é a hora de corrigi-la . Nosso script tem apenas uma dependência - o pacote de chalk , que é usado para criar materiais exibidos no console. Você pode instalar este pacote com o npm install -save-dev chalk .

1Etapa 1


No arquivo generateVuexModule.js , é necessário conectar três módulos: fs , path e chalk . Também aqui você precisa de uma constante com o caminho para a pasta modules ( src/store/modules ) e outra constante - args , que obterá os argumentos passados ​​para o script quando ele foi executado.

 const fs = require('fs'); const path = require('path'); const chalk = require('chalk'); const modulesPath = 'src/store/modules'; const args = process.argv.slice(2); const error = (...args) => { console.log(chalk.red(...args)); }; const success = (...args) => { console.log(chalk.green(...args)); }; if (!args.length) { error('You must provide a name for the module!'); return; } 

Como você pode ver, escrevemos todos os argumentos para os args exceto os dois primeiros, pois representam o caminho para o node.exe e o arquivo de script, e não precisamos dessas informações. Estamos interessados ​​apenas no terceiro parâmetro - o nome do novo módulo. Além disso, existem algumas funções, error e success , que usam o pacote de chalk mencionado acima para exibir mensagens com textos de cores diferentes.

Aqui você precisa verificar o comprimento da matriz args para descobrir se o nome do módulo foi passado para o nosso script e, se não for, forneça uma mensagem de erro. Portanto, se você tentar executar esse script usando o comando node generateVuexModule.js do node generateVuexModule.js , sem passar mais nada, verá uma mensagem de erro no terminal.

2Etapa 2


Neste ponto, temos um nome para o módulo e o caminho fornecido pela constante modulesPath . No entanto, ainda temos que trabalhar com esses dados. Ou seja, extraia o nome da matriz args e colete o caminho completo para o módulo, sem mencionar a formação de seu conteúdo.

 const moduleName = args[0]; const modulePath = path.join(__dirname, '../', modulesPath, moduleName); if (fs.existsSync(modulePath)) { error(`${moduleName} directory already exists!`); return; } const stateContent = `import getters from './getters'; import actions from './actions'; import mutations from './mutations'; const state = {}; export default { state, getters, actions, mutations }; `; const exportFileContent = `import * as types from '@/store/types'; export default { }; `; 

O nome do módulo estará no elemento da matriz args com o índice 0. Nesse estágio do programa, podemos contar com a presença desse elemento, pois anteriormente tentamos extraí-lo de process.argv e verificamos o comprimento da matriz args . Além disso, preparamos o caminho completo usando o módulo path e o método join . Obtivemos o diretório atual usando a construção __dirname , __dirname um nível acima, pois o arquivo generateVuexModule.js está localizado na pasta do projeto de scripts . Em seguida, adicionamos ao resultado o conteúdo da constante modulesPath e o nome do módulo. Nesse ponto, a constante modulePath deve conter algo como pathToYourProject/project/src/store/modules/moduleName . É aqui que o módulo será criado. Agora, como temos o caminho completo, podemos verificar se esse diretório existe. Não queremos substituir acidentalmente os arquivos de um módulo existente. Como resultado, se o diretório em que você planeja criar um novo módulo, exibiremos uma mensagem de erro em letras vermelhas, graças ao chalk .


Exemplo de mensagem de erro

Em seguida, você precisa criar constantes nas quais haverá dados para os arquivos. Como você pode imaginar, stateContent usado para o arquivo de estado, por exemplo, para auth.js , e exportFileContent é usado para getters.js , getters.js e mutations.js . Se necessário, você pode adicionar a esta lista tudo o que é necessário em seu projeto.

3Etapa 3


Agora só precisamos criar caminhos para os arquivos do módulo e criá-los.

 const statePath = `${path.join(modulePath, `${moduleName}.js`)}` const gettersPath = `${path.join(modulePath, 'getters.js')}` const actionsPath = `${path.join(modulePath, 'actions.js')}` const mutationsPath = `${path.join(modulePath, 'mutations.js')}` fs.mkdirSync(modulePath); fs.appendFileSync(statePath, stateContent); fs.appendFileSync(gettersPath, exportFileContent); fs.appendFileSync(actionsPath, exportFileContent); fs.appendFileSync(mutationsPath, exportFileContent); success('Module', moduleName, 'generated!'); 

Primeiro, declaramos quatro constantes, cada uma das quais contém um caminho para o arquivo correspondente. Em seguida, precisamos criar uma pasta para o módulo. Já verificamos se existe uma pasta e, se for o caso, comemos um erro. Portanto, não deve haver problemas com a criação de uma pasta. E, finalmente, usamos os fs.appendFileSync , colocando os novos arquivos com o conteúdo especificado no processo de criação deles no diretório recém-criado. No final, o script exibe uma mensagem sobre a conclusão bem-sucedida da operação.

Para usar esse script, basta ir para a pasta scripts do seu projeto no terminal e executar um comando do node generateVuexModule.js yourModuleName do formulário node generateVuexModule.js yourModuleName . Após a conclusão bem-sucedida do script, você verá uma mensagem sobre a criação de um módulo.

Sumário


Depois de revisar este material, você aprendeu sobre um modelo para estruturar grandes projetos em que planeja usar o Vuex e um script que simplifica a criação dos módulos do Vuex. Esperamos que você ache esse conhecimento útil. O código do projeto, exemplos dos quais examinamos, pode ser encontrado aqui .

Caros leitores! Como você estrutura grandes aplicativos Vue que usam o Vuex?

Source: https://habr.com/ru/post/pt420357/


All Articles