🚩 Vuex Pattern: Smart Module Registration
Tags: vue, webdev, showdev, javascript
Published: 2018-07-30 15:53:49

---
title: 🚩 Vuex Pattern: Smart Module Registration
published: true
description: Vue-Vuex pattern. Clean modules index.js with this smart module registration way.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/tzk0p9lzjp80q87cfzwb.jpg
tags: vue, webdev, showdev, javascript
---
Vue Experience: ⚫️⚫️⚫️⚫️⚪️
Vuex Experience: ⚫️⚫️⚫️⚫️⚫️

Have your ever tried to manage your's application state? 
Large applications can often grow in complexity, due to multiple pieces of state scattered across many components and the interactions between them. So, Vue offers **Vuex** but as official [documentation](https://vuex.vuejs.org/guide/modules.html) says:
> Vuex is using a single state tree, all state of our application is contained inside one big object. However, as our application grows in scale, the store can get really bloated.

To help with that, Vuex allows us to divide our store into modules. Each module can contain its own state, mutations, actions, getters, and even nested modules.
***
I think you have already got confused, so let's go into code.
```text
# This is a classic store structure with modules
├── index.html
├── main.js
├── components
└── store
    ├── index.js    # where we assemble modules and export the store
    └── modules
        ├── auth.js
        ├── posts.js
        └── comments.js
```
As you can see we have a store folder with an `index.js` and a subfolder named `modules`, which contains all modules. But module registration can start to get tedious.
`index.js` in `store/`
```javascript
import Vue from 'vue'
import Vuex from 'vuex'
import auth from './modules/auth'
import posts from './modules/posts'
import comments from './modules/comments'
// ...

Vue.use(Vuex)
export default new Vuex.Store({
	modules: {
		auth,
		posts,
		comments,
		// ...
	}
})
```
Example scaffolding for Vuex modules.
```javascript
export default {
  namespaced: true,
  state: {},
  getters: {},
  mutations: {},
  actions: {}
}
```
This is the standard way for registering modules. If you know what namespacing is, go on. 
> By default, actions, mutations and getters inside modules are still registered under the global namespace - this allows multiple modules to react to the same mutation/action type.
If you want your modules to be more self-contained or reusable, you can mark it as namespaced with `namespaced: true`

Let's see Module Registration as mentioned by Chris Fritz(Vue core member) in a VueConf.

🚩 Firstly, let's add a `index.js` file in `store/modules/`

```text
# This is our store structure with modules
├── index.html
├── main.js
├── components
└── store
    ├── index.js      # where we assemble modules and export the store
    └── modules
        ├── index.js  # this is the js file that solves the problem
        ├── auth.js
        ├── posts.js
        └── comments.js
```

🚩 Then let's modify this `index.js` in `store/modules/index.js`
```javascript
import camelCase from 'lodash/camelCase'
// Storing in variable a context with all files in this folder
// ending with `.js`.
const requireModule = require.context('.', false, /\.js$/)
const modules = {}

requireModule.keys().forEach(fileName => {
	if (fileName === './index.js') return
	// filter fullstops and extension 
  // and return a camel-case name for the file
	const moduleName = camelCase(
		fileName.replace(/(\.\/|\.js)/g, '')
	)
  // create a dynamic object with all modules
	modules[moduleName] = {
    // add namespace here
		namespaced: true,
		...requireModule(fileName).default
    // if you have exported the object with name in the module `js` file
    // e.g., export const name = {};
    // uncomment this line and comment the above
		// ...requireModule(fileName)[moduleName]
	}
})
export default modules
```
🚩 Let's delete namespacing from every module js file.
```javascript
// export const name = { if you want to export an object with name
export default {
  // namespaced: true,   delete this line 
	state: {},
	getters: {},
	mutations: {},
	actions: {}
}

```
🚩 Finally the code from above, where we had to import all the modules can change to:
`index.js` in `store/`
```javascript
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules'

Vue.use(Vuex)
export default new Vuex.Store({
	modules
})
```
I think we have done an ''automated'' system that includes every file in modules folder. A smarter and cleaner code.

*Until next time...Happy coding!*