leo95batista
leo95batista

Reputation: 767

Vue.js Auto register Vuex modules in a specific way

I have just started with Vue.js and I am trying to use Vuex. I have the following structure inside my directory: src/store/

store
├── index.js
└── modules
    ├── app
    │   └── index.js
    └── auth
        └── index.js

Within each module, I have only one file called index.js, and within those files I define the getters, actions, mutations, etc of each module.

My question is the following: How can I auto register all these modules in the src/store/index.js file without having to register one by one. This will become a tedious task as my application grows. I also need that when each of these modules self-register, self-define the property namespaced: true

What I have tried so far:


import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const context = require.context('./modules', true, /index.js/); //only files with the name index.js

const modules = context.keys()
  .map(file => [file.replace(/(^.\/)|(\.js$)/g, ''), context(file)])
  .reduce((modules, [name, module]) => {
    if (module.namespaced === undefined) {
      module.namespaced = true;
    }

    return { ...modules, [name]: module };
  }, {});

const store = new Vuex.Store({
  modules: modules
});

export default store;

Thank you very much in advance.

Upvotes: 4

Views: 1907

Answers (1)

Excalibaard
Excalibaard

Reputation: 2073

From what I can gather, the issue resides in mapping the modules with context(file). For default exports I've gotten success with context(file).default, falling back on context(file) if that is undefined. I also don't see you stripping the '/index' part from your file's directory path.

Using reduce makes the code more complicated than it needs to be, IMHO. You could just as easily do this with a forEach method:

const context = require.context('./modules', true, /index.js/);
const modules = {};

context.keys().forEach((file) => {

  // create the module name from file
  const moduleName = file.replace(/(\.\/|\/index\.js$)/g, '');

  // register file context under module name
  modules[moduleName] = context(file).default || context(file);

  // override namespaced option
  modules[moduleName].namespaced = true;
});

const store = new Vuex.Store({
  modules, // ES6 shorthand for modules: modules
})

export default store;

Upvotes: 2

Related Questions