From 1bd8f4ea45146707e97d493b54e1aed16460e21d Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 2 May 2017 14:57:39 +0800 Subject: [PATCH] make use of runInNewContext: false --- lib/app/client.js | 4 +- lib/app/index.js | 161 ++++++++++++++++++++++++---------------------- lib/app/router.js | 20 +++--- lib/app/server.js | 5 +- lib/app/store.js | 14 +++- lib/build.js | 3 +- 6 files changed, 115 insertions(+), 92 deletions(-) diff --git a/lib/app/client.js b/lib/app/client.js index 3627902d87..793c631983 100644 --- a/lib/app/client.js +++ b/lib/app/client.js @@ -2,13 +2,15 @@ import Vue from 'vue' import middleware from './middleware' -import { app, router<%= (store ? ', store' : '') %>, NuxtError } from './index' +import { createApp, NuxtError } from './index' import { applyAsyncData, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, getContext, promiseSeries, promisify, getLocation, compile } from './utils' const noopData = () => { return {} } const noopFetch = () => {} let _lastPaths = [] let _lastComponentsFiles = [] +const { app, router<%= (store ? ', store' : '') %> } = createApp() + function mapTransitions(Components, to, from) { return Components.map((Component) => { let transition = Component.options.transition diff --git a/lib/app/index.js b/lib/app/index.js index 17b7269867..87fa679d36 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -2,8 +2,8 @@ import Vue from 'vue' import Meta from 'vue-meta' -import router from './router.js' -<% if (store) { %>import store from './store.js'<% } %> +import { createRouter } from './router.js' +<% if (store) { %>import { createStore } from './store.js'<% } %> import NuxtChild from './components/nuxt-child.js' import NuxtLink from './components/nuxt-link.js' import NuxtError from '<%= components.ErrorPage ? components.ErrorPage : "./components/nuxt-error.vue" %>' @@ -25,86 +25,95 @@ Vue.use(Meta, { tagIDKeyName: 'hid' // the property name that vue-meta uses to determine whether to overwrite or append a tag }) -if (process.browser) { - <% if (store) { %> - // Replace store state before calling plugins - if (window.__NUXT__ && window.__NUXT__.state) { - store.replaceState(window.__NUXT__.state) - } - <% } %> - // window.onNuxtReady(() => console.log('Ready')) hook - // Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading) - window._nuxtReadyCbs = [] - window.onNuxtReady = function (cb) { - window._nuxtReadyCbs.push(cb) - } -} - -// root instance -// here we inject the router and store to all child components, -// making them available everywhere as `this.$router` and `this.$store`. const defaultTransition = <%= -serialize(transition) -.replace('beforeEnter(', 'function(').replace('enter(', 'function(').replace('afterEnter(', 'function(') -.replace('enterCancelled(', 'function(').replace('beforeLeave(', 'function(').replace('leave(', 'function(') -.replace('afterLeave(', 'function(').replace('leaveCancelled(', 'function(') -%> -let app = { - router, - <%= (store ? 'store,' : '') %> - _nuxt: { - defaultTransition: defaultTransition, - transitions: [ defaultTransition ], - setTransitions (transitions) { - if (!Array.isArray(transitions)) { - transitions = [ transitions ] - } - transitions = transitions.map((transition) => { - if (!transition) { - transition = defaultTransition - } else if (typeof transition === 'string') { - transition = Object.assign({}, defaultTransition, { name: transition }) - } else { - transition = Object.assign({}, defaultTransition, transition) - } - return transition - }) - this.$options._nuxt.transitions = transitions - return transitions - }, - err: null, - dateErr: null, - error (err) { - err = err || null - if (typeof err === 'string') { - err = { statusCode: 500, message: err } - } - this.$options._nuxt.dateErr = Date.now() - this.$options._nuxt.err = err; - return err + serialize(transition) + .replace('beforeEnter(', 'function(').replace('enter(', 'function(').replace('afterEnter(', 'function(') + .replace('enterCancelled(', 'function(').replace('beforeLeave(', 'function(').replace('leave(', 'function(') + .replace('afterLeave(', 'function(').replace('leaveCancelled(', 'function(') + %> + +export { NuxtError } + +export function createApp (ssrContext) { + const store = createStore() + const router = createRouter() + + if (process.browser) { + <% if (store) { %> + // Replace store state before calling plugins + if (window.__NUXT__ && window.__NUXT__.state) { + store.replaceState(window.__NUXT__.state) } - }, - ...App -} + <% } %> + // window.onNuxtReady(() => console.log('Ready')) hook + // Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading) + window._nuxtReadyCbs = [] + window.onNuxtReady = function (cb) { + window._nuxtReadyCbs.push(cb) + } + } + + // root instance + // here we inject the router and store to all child components, + // making them available everywhere as `this.$router` and `this.$store`. + let app = { + router, + <%= (store ? 'store,' : '') %> + ssrContext, + _nuxt: { + defaultTransition: defaultTransition, + transitions: [ defaultTransition ], + setTransitions (transitions) { + if (!Array.isArray(transitions)) { + transitions = [ transitions ] + } + transitions = transitions.map((transition) => { + if (!transition) { + transition = defaultTransition + } else if (typeof transition === 'string') { + transition = Object.assign({}, defaultTransition, { name: transition }) + } else { + transition = Object.assign({}, defaultTransition, transition) + } + return transition + }) + this.$options._nuxt.transitions = transitions + return transitions + }, + err: null, + dateErr: null, + error (err) { + err = err || null + if (typeof err === 'string') { + err = { statusCode: 500, message: err } + } + this.$options._nuxt.dateErr = Date.now() + this.$options._nuxt.err = err; + return err + } + }, + ...App + } -// Includes & Inject external plugins -<% plugins.forEach(function (plugin) { -if (plugin.ssr) { %> -<%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>') -<% if (plugin.injectAs) { %> -<%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %> -app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %> -<% } -} else { %> -if (process.browser) { + // Includes & Inject external plugins + <% plugins.forEach(function (plugin) { + if (plugin.ssr) { %> <%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>') <% if (plugin.injectAs) { %> <%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %> app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %> - <% } %> -} -<% } -}) %> + <% } + } else { %> + if (process.browser) { + <%= (plugin.injectAs ? 'let ' + plugin.injectAs + ' = ' : '') %>require('<%= plugin.src %>') + <% if (plugin.injectAs) { %> + <%= plugin.injectAs + ' = ' + plugin.injectAs + '.default || ' + plugin.injectAs %> + app['<%= plugin.injectAs %>'] = <%= plugin.injectAs %> + <% } %> + } + <% } + }) %> -export { app, router<%= (store ? ', store' : '') %>, NuxtError } + return { app, router<%= (store ? ', store' : '') %> } +} diff --git a/lib/app/router.js b/lib/app/router.js index 6e37b462e9..4d3dc71f64 100644 --- a/lib/app/router.js +++ b/lib/app/router.js @@ -53,12 +53,14 @@ const scrollBehavior = (to, from, savedPosition) => { } <% } %> -export default new Router({ - mode: '<%= router.mode %>', - base: '<%= router.base %>', - linkActiveClass: '<%= router.linkActiveClass %>', - scrollBehavior, - routes: [ -<%= _routes %> - ] -}) +export function createRouter () { + return new Router({ + mode: '<%= router.mode %>', + base: '<%= router.base %>', + linkActiveClass: '<%= router.linkActiveClass %>', + scrollBehavior, + routes: [ + <%= _routes %> + ] + }) +} diff --git a/lib/app/server.js b/lib/app/server.js index b0e0d62db8..ff50771a7a 100644 --- a/lib/app/server.js +++ b/lib/app/server.js @@ -7,11 +7,10 @@ import Vue from 'vue' import { stringify } from 'querystring' import { omit } from 'lodash' import middleware from './middleware' -import { app, router<%= (store ? ', store' : '') %>, NuxtError } from './index' +import { createApp, NuxtError } from './index' import { applyAsyncData, getMatchedComponents, getContext, promiseSeries, promisify, urlJoin } from './utils' const isDev = <%= isDev %> -const _app = new Vue(app) // This exported function will be called by `bundleRenderer`. // This is where we perform data-prefetching to determine the @@ -19,6 +18,8 @@ const _app = new Vue(app) // Since data fetching is async, this function is expected to // return a Promise that resolves to the app instance. export default context => { + const { app, router<%= (store ? ', store' : '') %> } = createApp(context) + const _app = new Vue(app) // Add store to the context <%= (store ? 'context.store = store' : '') %> // Nuxt object diff --git a/lib/app/store.js b/lib/app/store.js index acf94f07ac..0bad41e6e2 100644 --- a/lib/app/store.js +++ b/lib/app/store.js @@ -30,8 +30,11 @@ let storeData = {} if (filenames.indexOf('./index.js') !== -1) { let mainModule = getModule('./index.js') if (mainModule.commit) { - store = mainModule + console.error('[nuxt.js] store/index.js should export raw store options instead of an instance.') } else { + if (mainModule.state && typeof mainModule.state !== 'function') { + console.error('[nuxt.js] store state should be a function.') + } storeData = mainModule } } @@ -49,8 +52,13 @@ if (store == null) { name = namePath.pop() module[name] = getModule(filename) module[name].namespaced = true + + if (typeof module[name].state !== 'function') { + console.error('[nuxt.js] store module state should be a function.') + } } - store = new Vuex.Store(storeData) } -export default store +export function createStore () { + return new Vuex.Store(storeData) +} diff --git a/lib/build.js b/lib/build.js index 7316939ed7..24ab9d95bb 100644 --- a/lib/build.js +++ b/lib/build.js @@ -464,7 +464,8 @@ function createRenderer (bundle) { })) } this.renderer = createBundleRenderer(bundle, { - cache: cacheConfig + cache: cacheConfig, + runInNewContext: false }) this.renderToString = pify(this.renderer.renderToString) this.renderToStream = this.renderer.renderToStream