From a3dd7dad6b64366703c6fe36a1b845d408ee3a83 Mon Sep 17 00:00:00 2001 From: Jonas Galvez Date: Tue, 9 Oct 2018 09:07:23 -0300 Subject: [PATCH] feat: configurable global name (#4012) Co-authored-by: JuliaNeumann --- lib/app/App.js | 13 ++-- lib/app/client.js | 85 ++++++++++++--------- lib/app/components/nuxt-child.js | 8 +- lib/app/index.js | 6 +- lib/app/router.js | 2 +- lib/app/server.js | 3 +- lib/app/utils.js | 17 +++-- lib/app/views/loading/chasing-dots.html | 2 +- lib/app/views/loading/circle.html | 2 +- lib/app/views/loading/cube-grid.html | 2 +- lib/app/views/loading/fading-circle.html | 2 +- lib/app/views/loading/folding-cube.html | 2 +- lib/app/views/loading/nuxt.html | 2 +- lib/app/views/loading/pulse.html | 2 +- lib/app/views/loading/rectangle-bounce.html | 2 +- lib/app/views/loading/rotating-plane.html | 2 +- lib/app/views/loading/three-bounce.html | 2 +- lib/app/views/loading/wandering-cubes.html | 2 +- lib/builder/builder.js | 17 ++++- lib/common/nuxt.config.js | 12 +++ lib/common/options.js | 4 + lib/common/utils.js | 12 +++ lib/core/renderer.js | 14 ++-- test/fixtures/with-config/nuxt.config.js | 4 + test/unit/basic.config.defaults.test.js | 16 ++++ test/unit/with-config.test.js | 19 ++++- test/utils/browser.js | 20 +++-- 27 files changed, 184 insertions(+), 90 deletions(-) diff --git a/lib/app/App.js b/lib/app/App.js index 575d2cba00..786d710afb 100644 --- a/lib/app/App.js +++ b/lib/app/App.js @@ -37,7 +37,7 @@ export default { return h('div',{ domProps: { - id: '__nuxt' + id: '<%= globals.id %>' } }, [ <% if (loading) { %>loadingEl,<% } %> @@ -53,10 +53,13 @@ export default { }, created () { // Add this.$nuxt in child instances - Vue.prototype.$nuxt = this + Vue.prototype.<%= globals.nuxt %> = this // add to window so we can listen when ready if (typeof window !== 'undefined') { - window.$nuxt = this + window.<%= globals.nuxt %> = this + <% if (globals.nuxt !== '$nuxt') { %> + window.$nuxt = true + <% } %> } // Add $nuxt.error() this.error = this.nuxt.error @@ -100,8 +103,8 @@ export default { return resolvedLayouts[_layout] }) .catch((e) => { - if (this.$nuxt) { - return this.$nuxt.error({ statusCode: 500, message: e.message }) + if (this.<%= globals.nuxt %>) { + return this.<%= globals.nuxt %>.error({ statusCode: 500, message: e.message }) } }) } diff --git a/lib/app/client.js b/lib/app/client.js index e9a5209bd1..7c93bf133d 100644 --- a/lib/app/client.js +++ b/lib/app/client.js @@ -27,43 +27,54 @@ let router <% if (store) { %>let store<% } %> // Try to rehydrate SSR data from window -const NUXT = window.__NUXT__ || {} +const NUXT = window.<%= globals.context %> || {} Object.assign(Vue.config, <%= serialize(vue.config) %>) <% if (debug || mode === 'spa') { %> // Setup global Vue error handler -const defaultErrorHandler = Vue.config.errorHandler -Vue.config.errorHandler = (err, vm, info, ...rest) => { - const nuxtError = { - statusCode: err.statusCode || err.name || 'Whoops!', - message: err.message || err.toString() - } +if (!Vue.config.$nuxt) { + const defaultErrorHandler = Vue.config.errorHandler + Vue.config.errorHandler = (err, vm, info, ...rest) => { + const nuxtError = { + statusCode: err.statusCode || err.name || 'Whoops!', + message: err.message || err.toString() + } - // Call other handler if exist - let handled = null - if (typeof defaultErrorHandler === 'function') { - handled = defaultErrorHandler(err, vm, info, ...rest) - } - if (handled === true){ - return handled - } + // Call other handler if exist + let handled = null + if (typeof defaultErrorHandler === 'function') { + handled = defaultErrorHandler(err, vm, info, ...rest) + } + if (handled === true){ + return handled + } - // Show Nuxt Error Page - if (vm && vm.$root && vm.$root.$nuxt && vm.$root.$nuxt.error && info !== 'render function') { - vm.$root.$nuxt.error(nuxtError) - } - if (typeof defaultErrorHandler === 'function') { - return handled - } + if (vm && vm.$root) { + const nuxtApp = Object.keys(Vue.config.$nuxt) + .find(nuxtInstance => vm.$root[nuxtInstance]) + + // Show Nuxt Error Page + if (nuxtApp && vm.$root[nuxtApp].error && info !== 'render function') { + vm.$root[nuxtApp].error(nuxtError) + } + } - // Log to console - if (process.env.NODE_ENV !== 'production') { - console.error(err) - } else { - console.error(err.message || nuxtError.message) + if (typeof defaultErrorHandler === 'function') { + return handled + } + + // Log to console + if (process.env.NODE_ENV !== 'production') { + console.error(err) + } else { + console.error(err.message || nuxtError.message) + } } + Vue.config.$nuxt = {} } +Vue.config.$nuxt.<%= globals.nuxt %> = true + <% } %> // Create and mount App @@ -142,7 +153,7 @@ async function loadAsyncComponents (to, from, next) { err = err || {} const statusCode = (err.statusCode || err.status || (err.response && err.response.status) || 500) this.error({ statusCode, message: err.message }) - this.$nuxt.$emit('routeChanged', to, from, err) + this.<%= globals.nuxt %>.$emit('routeChanged', to, from, err) next(false) } } @@ -401,7 +412,7 @@ async function render (to, from, next) { if (!error) { error = {} } else if (error.message === 'ERR_REDIRECT') { - return this.$nuxt.$emit('routeChanged', to, from, error) + return this.<%= globals.nuxt %>.$emit('routeChanged', to, from, error) } _lastPaths = [] const errorResponseStatus = (error.response && error.response.status) @@ -417,7 +428,7 @@ async function render (to, from, next) { await this.loadLayout(layout) this.error(error) - this.$nuxt.$emit('routeChanged', to, from, error) + this.<%= globals.nuxt %>.$emit('routeChanged', to, from, error) next(false) } } @@ -489,19 +500,19 @@ function fixPrepatch(to, ___) { } function nuxtReady (_app) { - window._nuxtReadyCbs.forEach((cb) => { + window.<%= globals.readyCallback %>Cbs.forEach((cb) => { if (typeof cb === 'function') { cb(_app) } }) // Special JSDOM - if (typeof window._onNuxtLoaded === 'function') { - window._onNuxtLoaded(_app) + if (typeof window.<%= globals.loadedCallback %> === 'function') { + window.<%= globals.loadedCallback %>(_app) } // Add router hooks router.afterEach((to, from) => { // Wait for fixPrepatch + $data updates - Vue.nextTick(() => _app.$nuxt.$emit('routeChanged', to, from)) + Vue.nextTick(() => _app.<%= globals.nuxt %>.$emit('routeChanged', to, from)) }) } @@ -523,7 +534,7 @@ function getNuxtChildComponents($parent, $components = []) { function hotReloadAPI (_app) { if (!module.hot) return - let $components = getNuxtChildComponents(_app.$nuxt, []) + let $components = getNuxtChildComponents(_app.<%= globals.nuxt %>, []) $components.forEach(addHotReload.bind(_app)) } @@ -623,11 +634,11 @@ async function mountApp(__app) { // Mounts Vue app to DOM element const mount = () => { - _app.$mount('#__nuxt') + _app.$mount('#<%= globals.id %>') // Listen for first Vue update Vue.nextTick(() => { - // Call window.onNuxtReady callbacks + // Call window.{{globals.readyCallback}} callbacks nuxtReady(_app) <% if (isDev) { %> // Enable hot reloading diff --git a/lib/app/components/nuxt-child.js b/lib/app/components/nuxt-child.js index c1d2c4b6e3..63b43738f0 100644 --- a/lib/app/components/nuxt-child.js +++ b/lib/app/components/nuxt-child.js @@ -5,8 +5,8 @@ export default { render (h, { parent, data, props }) { data.nuxtChild = true const _parent = parent - const transitions = parent.$nuxt.nuxt.transitions - const defaultTransition = parent.$nuxt.nuxt.defaultTransition + const transitions = parent.<%= globals.nuxt %>.nuxt.transitions + const defaultTransition = parent.<%= globals.nuxt %>.nuxt.defaultTransition let depth = 0 while (parent) { @@ -33,8 +33,8 @@ export default { let beforeEnter = listeners.beforeEnter listeners.beforeEnter = (el) => { // Ensure to trigger scroll event after calling scrollBehavior - window.$nuxt.$nextTick(() => { - window.$nuxt.$emit('triggerScroll') + window.<%= globals.nuxt %>.$nextTick(() => { + window.<%= globals.nuxt %>.$emit('triggerScroll') }) if (beforeEnter) return beforeEnter.call(_parent, el) } diff --git a/lib/app/index.js b/lib/app/index.js index 1bbed569c8..d7bcb727d4 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -135,7 +135,7 @@ async function createApp (ssrContext) { store[key] = app[key] <% } %> // Check if plugin not already installed - const installKey = '__nuxt_' + key + '_installed__' + const installKey = '__<%= globals.pluginPrefix %>_' + key + '_installed__' if (Vue[installKey]) return Vue[installKey] = true // Call Vue.use() to install the plugin into vm @@ -153,8 +153,8 @@ async function createApp (ssrContext) { <% if (store) { %> if (process.client) { // Replace store state before plugins execution - if (window.__NUXT__ && window.__NUXT__.state) { - store.replaceState(window.__NUXT__.state) + if (window.<%= globals.context %> && window.<%= globals.context %>.state) { + store.replaceState(window.<%= globals.context %>.state) } } <% } %> diff --git a/lib/app/router.js b/lib/app/router.js index 21db366f1b..b85b030586 100644 --- a/lib/app/router.js +++ b/lib/app/router.js @@ -67,7 +67,7 @@ const scrollBehavior = function (to, from, savedPosition) { return new Promise((resolve) => { // wait for the out transition to complete (if necessary) - window.$nuxt.$once('triggerScroll', () => { + window.<%= globals.nuxt %>.$once('triggerScroll', () => { // coords will be used if no selector is provided, // or if the selector didn't match any element. if (to.hash) { diff --git a/lib/app/server.js b/lib/app/server.js index b419e2ecdd..07630445a4 100644 --- a/lib/app/server.js +++ b/lib/app/server.js @@ -46,7 +46,7 @@ export default async (ssrContext) => { ssrContext.next = createNext(ssrContext) // Used for beforeNuxtRender({ Components, nuxtState }) ssrContext.beforeRenderFns = [] - // Nuxt object (window.__NUXT__) + // Nuxt object (window{{globals.context}}, defaults to window.__NUXT__) ssrContext.nuxt = { layout: 'default', data: [], error: null<%= (store ? ', state: null' : '') %>, serverRendered: true } // Create the app definition and the instance (created for each request) const { app, router<%= (store ? ', store' : '') %> } = await createApp(ssrContext) @@ -125,7 +125,6 @@ export default async (ssrContext) => { await _app.loadLayout(layout) if (ssrContext.nuxt.error) return renderErrorPage() layout = _app.setLayout(layout) - // ...Set layout to __NUXT__ ssrContext.nuxt.layout = _app.layoutName /* diff --git a/lib/app/utils.js b/lib/app/utils.js index 316adc3773..2b17d27387 100644 --- a/lib/app/utils.js +++ b/lib/app/utils.js @@ -2,12 +2,12 @@ import Vue from 'vue' const noopData = () => ({}) -// window.onNuxtReady(() => console.log('Ready')) hook +// window.{{globals.loadedCallback}} hook // Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading) if (process.client) { - window._nuxtReadyCbs = [] - window.onNuxtReady = (cb) => { - window._nuxtReadyCbs.push(cb) + window.<%= globals.readyCallback %>Cbs = [] + window.<%= globals.readyCallback %> = (cb) => { + window.<%= globals.readyCallback %>Cbs.push(cb) } } @@ -134,7 +134,6 @@ export async function setContext(app, context) { if (!status) { return } - // Used in middleware app.context._redirected = true // if only 1 or 2 arguments: redirect('/') or redirect('/', { foo: 'bar' }) let pathType = typeof path @@ -171,8 +170,12 @@ export async function setContext(app, context) { } } } - if (process.server) app.context.beforeNuxtRender = fn => context.beforeRenderFns.push(fn) - if (process.client) app.context.nuxtState = window.__NUXT__ + if (process.server) { + app.context.beforeNuxtRender = fn => context.beforeRenderFns.push(fn) + } + if (process.client) { + app.context.nuxtState = window.<%= globals.context %> + } } // Dynamic keys app.context.next = context.next diff --git a/lib/app/views/loading/chasing-dots.html b/lib/app/views/loading/chasing-dots.html index d2cf7326fb..ee4cd83560 100644 --- a/lib/app/views/loading/chasing-dots.html +++ b/lib/app/views/loading/chasing-dots.html @@ -1,5 +1,5 @@