Open JCHappytime opened 3 years ago
(1) entry-client.js: import Vue from 'vue'; import 'es6-promise/auto'; import { createApp } from './app';
const { app, router, store } = createApp();
Vue.mixin({ beforeRouteUpdate(to, from, next) { const { asyncData } = this.$options; if (asyncData && to.path !== from.path) { Promise.resolve(asyncData(store, to)).then(next).catch(next); } else { next(); } }, });
// prime the store with server-initialized state. // the state is determined during SSR and inlined in the page markup. if (window.INITIALSTATE) { store.replaceState(window.INITIALSTATE);
// set i18n local at client const lang = store.state.lang || 'en-US'; store.commit('CHANGE_LANGUAGE', lang);
app.$i18n.locale = lang; }
// wait until router has resolved all async before hooks // and async components... router.onReady(() => { // Add router hook for handling preFetch. // Doing it after initial route is resolved so that we don't double-fetch // the data that we already have. Using router.beforeResolve() so that all // async components are resolved. router.beforeResolve((to, from, next) => { const matched = router.getMatchedComponents(to); const prevMatched = router.getMatchedComponents(from); let diffed = false; const activated = matched.filter((c, i) => { if (!diffed) { diffed = prevMatched[i] !== c; }
return diffed;
});
const asyncDataHooks = activated.map((c) => c.preFetch || (c.options || {}).preFetch).filter((_) => _);
if (!asyncDataHooks.length) {
return next();
}
return Promise.all(asyncDataHooks.map((hook) => hook(store, to)))
.then(() => {
next();
})
.catch(next);
});
// actually mount to DOM app.$mount('#app'); }); (2) entry-server.js: import _ from 'lodash'; import axios from 'axios'; import { createApp } from './app'; import { PORTAL_API_URL, PORTAL_URL, EDU_PORTAL_URL } from './constants';
const isDev = process.env.NODE_ENV !== 'production';
function getCoutryCodeList(store, context) {
const lang = context.req.cookies.ncp_lang || 'ko-KR';
return axios(${PORTAL_API_URL}/fe/v1/countryCode/getPhoneCodeList
, {
headers: {
'X-NCP-LANG': lang,
},
})
.then(({ data }) => {
store.commit('SET_COUNTRY_CODE_LIST', data);
})
.catch((e) => {
console.error(e);
});
}
// This exported function will be called by bundleRenderer
.
// This is where we perform data-prefetching to determine the
// state of our application before actually rendering it.
// Since data fetching is async, this function is expected to
// return a Promise that resolves to the app instance.
export default (context) => {
const s = isDev && Date.now();
const { app, router, store } = createApp({});
const fns = [];
const lang = context.req.cookies.ncp_lang || 'ko-KR';
// set i18n local at server store.commit('CHANGE_LANGUAGE', lang); store.commit('SET_PORTAL_URL', PORTAL_URL); store.commit('SET_EDU_PORTAL_URL', EDU_PORTAL_URL); app.$i18n.locale = lang;
return new Promise((resolve, reject) => { // set router's location router.push(context.req.url);
// wait until router has resolved possible async hooks
router.onReady((to) => {
const matchedComponents = router.getMatchedComponents();
// no matched routes
if (!matchedComponents.length) {
reject({ code: 404 });
}
if (to) {
const meta = _.assign({}, to.meta);
store.commit('CHANGE_ROUTER_META', meta);
}
fns.push(getCoutryCodeList);
// Call preFetch hooks on components matched by the route.
// A preFetch hook dispatches a store action and returns a Promise,
// which is resolved when the action is complete and store state has been
// updated.
Promise.all([...fns.map((fn) => fn(store, context, reject))])
.then(() => {
return Promise.all([
...matchedComponents.map((component) => {
const preFetch = component.preFetch || (component.options && component.options.preFetch);
return preFetch && preFetch(store, context.req);
}),
]);
})
.then(() => {
isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`);
// After all preFetch hooks are resolved, our store is now
// filled with the state needed to render the app.
// Expose the state on the render context, and let the request handler
// inline the state in the HTML response. This allows the client-side
// store to pick-up the server-side state without having to duplicate
// the initial data fetching on the client.
context.state = store.state;
resolve(app);
})
.catch(reject);
}, reject);
}); };
入口文件: