DEV Community

Steve Edwards
Steve Edwards

Posted on

Dynamically Importing Vuex Store Modules From Directory Structure

This is a continuation of my previous post, where I went through the details of how to define Vue router route definitions in files throughout the app directory structure, and then import them into the main router index.js file. In this post, I'm going to be showing the same process for Vuex store modules. There are a couple small variations from the router import code, but nothing major.

First, here is the structure of a store module:

import * as types from '@/store/types';

const state = {
  events: [],
};

// getters
const getters = {
  getEvents: state => state.events,
};

// actions
const actions = {

};

// mutations
const mutations = {
  [types.SET_EVENTS](state, shifts) {
    state.events = shifts;
  }
};

export default {
  namespaced: true,
  name: 'event',
  state,
  getters,
  actions, 
  mutations
}

There is one small addition to this file for import purposes, and that is the name key in the exported object. This is because during the import process, since stores are separated by namespaces, a name property is needed. However, in looking through all of the available information returned from require.context(), I didn't see the value of the parent directory name, so I just added that value to the exported object.

With those defined, here is the store index.js file:

import Vue from 'vue';
import Vuex from 'vuex';
import Auth from '@/store/modules/auth'

Vue.use(Vuex);

const debug = process.env.NODE_ENV !== 'production';

Vue.config.devtools = true;

// Import all of the resource store files.
function loadStores() {
  const context = require.context('@/resources', true, /store.js$/i);
  return context.keys()
    .map(context)         // import module
    .map(m => m.default)  // get `default` export from each resolved module
}

const resourceModules = {};
loadStores().forEach((resource) => {
  resourceModules[resource.name] = resource;
});

resourceModules.auth = Auth;

export default new Vuex.Store({
  modules: resourceModules,
  strict: debug,
});

You can see where I use the exported name property in the call to loadStores(). Then, once all of the store modules under the /resources directory are adde to the resourceModules object, I manually add the store for the Auth module (since it's outside of the /resources directory), and then pass it all to the modules key in the new Vuex.Store() constructor. After verifying in the Vue Dev tools that the store exist, I'm off and running.

Top comments (0)