Vuex 모듈 등록 자동화하기
작성일: 2020-09-05 13:29
- Vuex에서 module을 사용하다보면 직접 state, gettets, mutations, actions를 등록해주는게 귀찮을때가 많습니다.
- 모듈 경로에 있는 js 파일들을 읽어 모듈을 자동으로 등록할 수 있도록 하는 방법을 발견하여 공유하고자 합니다.
# 기존의 Vuex 모듈 등록 방법
- 우선 예시에서 사용할 모듈을 정의해보겠습니다.
// module/post.js
export const state = {
title: 'Post Title'
};
export const getters = {
getTitle(state) {
return state.title;
}
};
export const mutations = {
};
export const actions = {
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// module/user.js
const state = {
name: 'User Name'
};
const getters = {
getName(state) {
return state.name;
}
};
const mutations = {
};
const actions = {
};
export default {
state,
getters,
mutations,
actions,
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- 보통 Vuex에서 모듈을 사용하기 위해선 보통 사용할 모듈의 이름.js로 파일을 만들어 Vuex를 위한 4가지 속성을 정의합니다.
- export하는 방식은 첫 번째 코드인 post.js와 같이 각각을 export 해줄 수도 있고 혹은 user.js와 같이 export default를 활용하여 방식 모두 가능합니다.
// index.js
import Vue from 'vue';
import Vuex from 'vuex';
import user from './module/user.js'
import * as post from './module/post.js'
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
user,
post,
}
});
export default store;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- export한 모듈들은 Vuex를 등록하는 곳에서 import하여 modules 내부에 넣어주면 모듈을 등록할 수 있습니다.
- 하지만 보통 모듈을 사용하면 namespaced를 활용하기 때문에 아래와 같이 namespaced를 true로 등록해주어야 합니다.
// index.js
import Vue from 'vue';
import Vuex from 'vuex';
import user from './module/user.js'
import * as post from './module/post.js'
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
user: {
namespaced: true,
...user
},
post: {
namespaced: true,
...post
},
}
});
export default store;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- Vuex를 사용할 때 Vuex 모듈에 정의한 네 가지 속성에 필요한 기능을 구현하는 것이 중요하며 모듈을 등록하는건 단순히 반복적인 작업입니다.
- 모듈 등록을 자동화 해놓으면 귀찮고 반복적인 작업을 하지도 않고 모듈 등록을 까먹을 일도 없을 것입니다.
# 자동으로 Vuex 모듈 등록하기
- 사용할 모듈은 위에서 정의한 user, post를 동일하게 사용합니다.
- 자동으로 Vuex를 등록하는 방법은 webpack에서 제공하는 require.context를 활용할 수 있습니다.
- require.context를 활용하면 지정된 파일경로와 그 파일이 js일 경우 export된 값을 얻을 수 있습니다.
# require.context가 제공해주는 정보
// module/index.js
const requireContext = require.context(
'./', // 탐색할 root 폴더
true, // 하위 폴더까지 탐색
/[^(index)]\.js$/ // 탐색할 정규 표현식 (index를 제외한 js 파일들을 탐색합니다)
);
console.log(requireContext.keys()); // ["./post.js", "./user.js"]
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- requre.context에 폴더 및 정규 표현식을 정의하면 원하는 context들을 가져올 수 있습니다.
- 가져온 context들의 key 값들은 경로를 포함한 해당 파일의 이름으로 구성되어 있습니다.
const requireContext = require.context(
'./',
true,
/[^(index)]\.js$/
);
requireContext.keys().forEach(filePath => {
console.log(requireContext(filePath));
})
/* ./auth.js
Module {__esModule: true, …}
actions: {}
getters:
getTitle: ƒ getTitle(state)
mutations: {}
state:
title: "Post Title"
*/
/* ./user.js
Module {default: {…}, __esModule: true, Symbol(Symbol.toStringTag): "Module"}
default:
actions: {}
getters:
getName: ƒ getName(state)
mutations: {}
state:
name: "User Name"
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- requireContext의 value들을 출력해보면 각 js 파일의 export 값을 가지고 있는 것을 알 수 있습니다.
- user와 같이 default로 export한 경우 내부에 default안에 exprot된 값을 가지고 있습니다.
const getExportValues = (requireContextValue) => requireContextValue.default || requireContextValue;
1
- 즉 requireContextValue에서 export 값들은 requireContextValue의 default값 혹은 그 값 자체가 됩니다.
- 보통 파일명에 맞춰 Vuex 모듈명을 지정하므로 filePath로 모듈명을 구하고 exportValues를 통해 모듈을 등록할 수 있으므로 이를 활용하여 Vuex에 등록할 모듈을 생성해보겠습니다.
# modules 생성하기
const getExportValues = (requireContextValue) => requireContextValue.default || requireContextValue;
const getModuleName = (filePath) => filePath
.replace(/^\.\//, '') // 파일 경로 앞단의 ./ 제거
.replace(/\.js$/, '') // .js 제거
const requireContext = require.context(
'./', // 탐색할 root 폴더
true, // 하위 폴더까지 탐색
/[^(index)]\.js$/ // 탐색할 정규 표현식 (index를 제외한 js 파일들을 탐색합니다)
);
const modules = {};
requireContext.keys().forEach(filePath => {
const exportValues = getExportValues(requireContext(filePath));
const moduleName = getModuleName(filePath);
modules[moduleName] = {
namespaced: true,
...exportValues
}
})
export default modules;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- 지정된 폴더의 js 파일들을 모두 탐색한 후 context를 만들어 filePath와 exportValues를 추출합니다.
- filePath를 통해 moduleName을 가져오고 moduleName과 exportValues를 활용하여 modules을 생성할 수 있습니다.
# 생성한 modules 등록하기
import Vue from 'vue';
import Vuex from 'vuex';
import modules from "@/store/module";
Vue.use(Vuex);
const store = new Vuex.Store({
modules,
});
export default store;
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- module 폴더 내부의 js파일을 탐색하여 모듈을 자동으로 생성하기 때문에 해당 modules를 등록하기만 하면 됩니다.
- Vuex에 새로운 모듈을 정의하더라도 직접 모듈을 등록할 필요가 없어졌습니다.
# 정리
- Vuex의 모듈 등록은 단순히 반복되는 작업으로 자동화를 할 수 있습니다.
- webpack에서 제공하는 require.context를 활용하면 js파일을 탐색하여 export 값들을 가져올 수 있고 이를 통해 모듈을 자동으로 생성할 수 있습니다.
Vuex 중첩 모듈을 자동으로 등록하는 방법은 GitHub 코드 (opens new window)를 참고하시면 확인할 수 있습니다.