From df2af66355712b78245203f6980557e1c9ef0537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Chopin?= Date: Mon, 16 Oct 2017 10:40:08 +0200 Subject: [PATCH] Refacto client app --- lib/app/client.js | 115 +++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 68 deletions(-) diff --git a/lib/app/client.js b/lib/app/client.js index b4087f8129..5cc56ad020 100644 --- a/lib/app/client.js +++ b/lib/app/client.js @@ -4,10 +4,11 @@ import { createApp, NuxtError } from './index' import { applyAsyncData, sanitizeComponent, + resolveRouteComponents, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, - getContext, + setContext, middlewareSeries, promisify, getLocation, @@ -96,40 +97,25 @@ function mapTransitions(Components, to, from) { } async function loadAsyncComponents (to, from, next) { - // Check if route hash changed + // Check if route hash changed (this._hashChanged) const fromPath = from.fullPath.split('#')[0] const toPath = to.fullPath.split('#')[0] this._hashChanged = fromPath === toPath <% if (loading) { %> if (!this._hashChanged && this.$loading.start) { - this.$loading.start() + this.$loading.start() } <% } %> try { - await Promise.all(flatMapComponents(to, (Component, _, match, key) => { - // If component already resolved - if (typeof Component !== 'function' || Component.options) { - const _Component = sanitizeComponent(Component) - match.components[key] = _Component - return _Component - } - - // Resolve component - return Component().then(Component => { - const _Component = sanitizeComponent(Component) - match.components[key] = _Component - return _Component - }) - })) - + await resolveRouteComponents(to) next() } catch (err) { - if (!err) err = {} - const statusCode = err.statusCode || err.status || (err.response && err.response.status) || 500 - this.error({ statusCode, message: err.message }) - next(false) + err = err || {} + const statusCode = err.statusCode || err.status || (err.response && err.response.status) || 500 + this.error({ statusCode, message: err.message }) + next(false) } } @@ -145,20 +131,15 @@ function applySSRData(Component, ssrData) { function resolveComponents(router) { const path = getLocation(router.options.base, router.options.mode) - return flatMapComponents(router.match(path), (Component, _, match, key, index) => { - // If component already resolved - if (typeof Component !== 'function' || Component.options) { - const _Component = applySSRData(sanitizeComponent(Component), NUXT.data ? NUXT.data[index] : null) - match.components[key] = _Component - return _Component + return flatMapComponents(router.match(path), async (Component, _, match, key, index) => { + // If component is not resolved yet, resolve it + if (typeof Component === 'function' && !Component.options) { + Component = await Component() } - - // Resolve component - return Component().then(Component => { - const _Component = applySSRData(sanitizeComponent(Component), NUXT.data ? NUXT.data[index] : null) - match.components[key] = _Component - return _Component - }) + // Sanitize it and save it + const _Component = applySSRData(sanitizeComponent(Component), NUXT.data ? NUXT.data[index] : null) + match.components[key] = _Component + return _Component }) } @@ -204,17 +185,13 @@ async function render (to, from, next) { } // Update context - const context = getContext({ - to, + setContext(app, { + route: to, from, - <% if (store) { %>store,<% } %> - isClient: true, - next: _next.bind(this), - error: this.error.bind(this) - }, app) - this._context = context - this._dateLastError = this.$options._nuxt.dateErr - this._hadError = !!this.$options._nuxt.err + next: _next.bind(this) + }) + this._dateLastError = app.nuxt.dateErr + this._hadError = !!app.nuxt.err // Get route's matched components const Components = getMatchedComponents(to) @@ -222,15 +199,14 @@ async function render (to, from, next) { // If no Components matched, generate 404 if (!Components.length) { // Default layout - await callMiddleware.call(this, Components, context) - if (context._redirected) return - + await callMiddleware.call(this, Components, app.context) + if (app.context._redirected) return // Load layout for error page - const layout = await this.loadLayout(typeof NuxtError.layout === 'function' ? NuxtError.layout(context) : NuxtError.layout) + const layout = await this.loadLayout(typeof NuxtError.layout === 'function' ? NuxtError.layout(app.context) : NuxtError.layout) await callMiddleware.call(this, Components, context, layout) if (context._redirected) return - - this.error({ statusCode: 404, message: '<%= messages.error_404 %>' }) + // Show error page + app.context.error({ statusCode: 404, message: '<%= messages.error_404 %>' }) return next() } @@ -247,19 +223,19 @@ async function render (to, from, next) { try { // Call middleware - await callMiddleware.call(this, Components, context) - if (context._redirected) return + await callMiddleware.call(this, Components, app.context) + if (app.context._redirected) return // Set layout let layout = Components[0].options.layout if (typeof layout === 'function') { - layout = layout(context) + layout = layout(app.context) } layout = await this.loadLayout(layout) // Call middleware for layout - await callMiddleware.call(this, Components, context, layout) - if (context._redirected) return + await callMiddleware.call(this, Components, app.context, layout) + if (app.context._redirected) return // Call .validate() let isValid = true @@ -269,7 +245,7 @@ async function render (to, from, next) { isValid = Component.options.validate({ params: to.params || {}, query : to.query || {}, - <% if(store) { %>store: context.store <% } %> + <% if(store) { %>store<% } %> }) }) // ...If .validate() returned false @@ -294,7 +270,7 @@ async function render (to, from, next) { // Call asyncData(context) if (hasAsyncData) { - const promise = promisify(Component.options.asyncData, context) + const promise = promisify(Component.options.asyncData, app.context) .then(asyncDataResult => { applyAsyncData(Component, asyncDataResult) <% if(loading) { %>if(this.$loading.increase) this.$loading.increase(loadingIncrease)<% } %> @@ -304,7 +280,7 @@ async function render (to, from, next) { // Call fetch(context) if (hasFetch) { - let p = Component.options.fetch(context) + let p = Component.options.fetch(app.context) if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) { p = Promise.resolve(p) } @@ -332,7 +308,7 @@ async function render (to, from, next) { // Load error layout let layout = NuxtError.layout if (typeof layout === 'function') { - layout = layout(context) + layout = layout(app.context) } await this.loadLayout(layout) @@ -376,14 +352,14 @@ function fixPrepatch (to, ___) { }) // Hide error component if no error - if (this._hadError && this._dateLastError === this.$options._nuxt.dateErr) { + if (this._hadError && this._dateLastError === this.$options.nuxt.dateErr) { this.error() } // Set layout - let layout = this.$options._nuxt.err ? NuxtError.layout : to.matched[0].components.default.options.layout + let layout = this.$options.nuxt.err ? NuxtError.layout : to.matched[0].components.default.options.layout if (typeof layout === 'function') { - layout = layout(this._context) + layout = layout(app.context) } this.setLayout(layout) @@ -459,9 +435,13 @@ function addHotReload ($component, depth) { <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %> router.push(path) } - let context = getContext({ route: router.currentRoute<%= (store ? ', store' : '') %>, isClient: true, isHMR: true, next: next.bind(this), error: this.error }, app) + setContext(app, { + route: router.currentRoute, + isHMR: true, + next: next.bind(this) + }) <%= (loading ? 'this.$loading.start && this.$loading.start()' : '') %> - callMiddleware.call(this, Components, context) + callMiddleware.call(this, Components, app.context) .then(() => { // If layout changed if (depth !== 0) return Promise.resolve() @@ -538,7 +518,7 @@ async function mountApp(__app) { } // Enable transitions - _app.setTransitions = _app.$options._nuxt.setTransitions.bind(_app) + _app.setTransitions = _app.$options.nuxt.setTransitions.bind(_app) if (Components.length) { _app.setTransitions(mapTransitions(Components, router.currentRoute)) _lastPaths = router.currentRoute.matched.map(route => compile(route.path)(router.currentRoute.params)) @@ -546,7 +526,6 @@ async function mountApp(__app) { } // Initialize error handler - _app.error = _app.$options._nuxt.error.bind(_app) _app.$loading = {} // To avoid error while _app.$nuxt does not exist if (NUXT.error) _app.error(NUXT.error)