ばべるとかうえぶぱっくとか諸々verupしたら、以下のようなエラーを吐いてコンパイルができなくなってしまったので、その解決方法を記しておきます。
✘ https://google.com/#q=import%2Fno-cycle Dependency cycle via ../utils/httpCommon:1=>../stores:4=>./modules/root:4
src/stores/modules/timer.js:1:1
Dependency cycle via ...?
Circular Dependencyということみたいです。(初めて知った!w)
なにが起きているのかと言うと、ぐるぐるimportし続けてしまう連鎖が起きているっていうことみたいです。
ここの説明が僕的にとてもわかりやすかった。。
https://stackoverflow.com/questions/38042130/what-is-a-circular-dependency-and-how-can-i-solve-it
こうなたっときのストラクチャー
1) timerモジュールがTimerApiをimportする
// stores/modules/timer.js
import TimerApi from '../../api/timer';
const state = { ... }
const getters = { ... }
const actions = {
:
async hoge({ commit }, data) {
const res = await TimerApi.create(data);
if (res.status) {
const time = res.data.hoge
commit('HOGE', { time })
}
},
:
}
const mutations = { ... }
export default {
state,
getters,
actions,
mutations,
};
2) TimerApiがhttpCommonをimportする
// api/timer.js
import HTTP from '../utils/httpCommon';
export default {
create(data) {
const formData = {
'hoge': { ...data },
};
return HTTP({
method: 'POST',
url: '/XXX/YYY/ZZZ',
data: formData,
});
},
:
};
3) httpCommonがstoreをimportする
// utils/httpCommon.js
import axios from 'axios';
import router from '../router';
import store from '../stores';
const HTTP = axios.create({ baseURL: process.env.API_ENDPOINT });
HTTP.interceptors.request.use((config) => {
config.headers = getHeader();
return config;
});
:
4) storeがmodules/rootをimportする
// stores/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import {
modules, getters, mutations, actions
} from './modules/root';
Vue.use(Vuex);
:
const store = new Vuex.Store({
modules,
getters,
mutations,
actions,
});
export default store;
5) modules/rootがtimerモジュールをimportする ==> 1に戻る⁉️
// modules/root.js
:
import TIMER from '/timer'
:
const modules = {
:
TIMER
:
}
:
export {
modules, xxx, yyy, zzzz,
}
解決方法 => Dependency Injection
We use a form of dependency injection in the API file, where instead of importing the store, it exports an init function which takes the store as an argument. Then in main.js, the init function is called and passed the store.
実装
今回routerでもcircular dependecyが起こっていたので引数はstoreとrouter二つをとるようにしています
1) httpCommonjs
- storeとrouterをimportする記述を消す
- storeとrouterを引数とし受け取るinit functionとしてexportする記述に変更
import axios from 'axios';
const HTTP = axios.create({ baseURL: process.env.API_ENDPOINT });
export default function init(store, router) {
HTTP.interceptors.request.use((config) => {
config.headers = getHeader();
return config;
});
:
if (store.method !== undefined) {
return HTTP(store);
}
:
}
2) main.js
:
import router from './router';
import store from './stores';
import init from './utils/httpCommon';
init(store, router);
: