UNPKG

7.54 kBJavaScriptView Raw
1import Vue from 'vue'
2import Meta from 'vue-meta'
3import { createRouter } from './router.js'
4import NoSSR from './components/no-ssr.js'
5import NuxtChild from './components/nuxt-child.js'
6import NuxtLink from './components/nuxt-link.js'
7import NuxtError from '<%= components.ErrorPage ? components.ErrorPage : "./components/nuxt-error.vue" %>'
8import Nuxt from './components/nuxt.js'
9import App from '<%= appPath %>'
10import { setContext, getLocation, getRouteData } from './utils'
11<% if (store) { %>import { createStore } from './store.js'<% } %>
12
13/* Plugins */
14<%= isTest ? '/* eslint-disable camelcase */' : '' %>
15<% plugins.forEach((plugin) => { %>import <%= plugin.name %> from '<%= plugin.name %>' // Source: <%= relativeToBuild(plugin.src) %><%= (plugin.ssr===false) ? ' (ssr: false)' : '' %>
16<% }) %>
17<%= isTest ? '/* eslint-enable camelcase */' : '' %>
18
19// Component: <no-ssr>
20Vue.component(NoSSR.name, NoSSR)
21
22// Component: <nuxt-child>
23Vue.component(NuxtChild.name, NuxtChild)
24
25// Component: <nuxt-link>
26Vue.component(NuxtLink.name, NuxtLink)
27
28// Component: <nuxt>`
29Vue.component(Nuxt.name, Nuxt)
30
31// vue-meta configuration
32Vue.use(Meta, {
33 keyName: 'head', // the component option name that vue-meta looks for meta info on.
34 attribute: 'data-n-head', // the attribute name vue-meta adds to the tags it observes
35 ssrAttribute: 'data-n-head-ssr', // the attribute name that lets vue-meta know that meta info has already been server-rendered
36 tagIDKeyName: 'hid' // the property name that vue-meta uses to determine whether to overwrite or append a tag
37})
38
39const defaultTransition = <%=
40 serialize(transition)
41 .replace('beforeEnter(', 'function(').replace('enter(', 'function(').replace('afterEnter(', 'function(')
42 .replace('enterCancelled(', 'function(').replace('beforeLeave(', 'function(').replace('leave(', 'function(')
43 .replace('afterLeave(', 'function(').replace('leaveCancelled(', 'function(').replace('beforeAppear(', 'function(')
44 .replace('appear(', 'function(').replace('afterAppear(', 'function(').replace('appearCancelled(', 'function(')
45%><%= isTest ? '// eslint-disable-line' : '' %>
46
47async function createApp(ssrContext) {
48 const router = await createRouter(ssrContext)
49
50 <% if (store) { %>
51 const store = createStore(ssrContext)
52 // Add this.$router into store actions/mutations
53 store.$router = router
54 <% if (mode === 'universal') { %>
55 // Fix SSR caveat https://github.com/nuxt/nuxt.js/issues/3757#issuecomment-414689141
56 const registerModule = store.registerModule
57 store.registerModule = (path, rawModule, options) => registerModule.call(store, path, rawModule, Object.assign({ preserveState: process.client }, options))
58 <% } %>
59 <% } %>
60
61 // Create Root instance
62
63 // here we inject the router and store to all child components,
64 // making them available everywhere as `this.$router` and `this.$store`.
65 const app = {
66 router,
67 <% if (store) { %>store,<% } %>
68 nuxt: {
69 defaultTransition,
70 transitions: [ defaultTransition ],
71 setTransitions(transitions) {
72 if (!Array.isArray(transitions)) {
73 transitions = [ transitions ]
74 }
75 transitions = transitions.map((transition) => {
76 if (!transition) {
77 transition = defaultTransition
78 } else if (typeof transition === 'string') {
79 transition = Object.assign({}, defaultTransition, { name: transition })
80 } else {
81 transition = Object.assign({}, defaultTransition, transition)
82 }
83 return transition
84 })
85 this.$options.nuxt.transitions = transitions
86 return transitions
87 },
88 err: null,
89 dateErr: null,
90 error(err) {
91 err = err || null
92 app.context._errored = !!err
93 if (typeof err === 'string') err = { statusCode: 500, message: err }
94 const nuxt = this.nuxt || this.$options.nuxt
95 nuxt.dateErr = Date.now()
96 nuxt.err = err
97 // Used in src/server.js
98 if (ssrContext) ssrContext.nuxt.error = err
99 return err
100 }
101 },
102 ...App
103 }
104 <% if (store) { %>
105 // Make app available into store via this.app
106 store.app = app
107 <% } %>
108 const next = ssrContext ? ssrContext.next : location => app.router.push(location)
109 // Resolve route
110 let route
111 if (ssrContext) {
112 route = router.resolve(ssrContext.url).route
113 } else {
114 const path = getLocation(router.options.base)
115 route = router.resolve(path).route
116 }
117
118 // Set context to app.context
119 await setContext(app, {
120 route,
121 next,
122 error: app.nuxt.error.bind(app),
123 <% if (store) { %>store,<% } %>
124 payload: ssrContext ? ssrContext.payload : undefined,
125 req: ssrContext ? ssrContext.req : undefined,
126 res: ssrContext ? ssrContext.res : undefined,
127 beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined
128 })
129
130 <% if (plugins.length) { %>
131 const inject = function (key, value) {
132 if (!key) throw new Error('inject(key, value) has no key provided')
133 if (!value) throw new Error('inject(key, value) has no value provided')
134 key = '$' + key
135 // Add into app
136 app[key] = value
137 <% if (store) { %>
138 // Add into store
139 store[key] = app[key]
140 <% } %>
141 // Check if plugin not already installed
142 const installKey = '__<%= globals.pluginPrefix %>_' + key + '_installed__'
143 if (Vue[installKey]) return
144 Vue[installKey] = true
145 // Call Vue.use() to install the plugin into vm
146 Vue.use(() => {
147 if (!Vue.prototype.hasOwnProperty(key)) {
148 Object.defineProperty(Vue.prototype, key, {
149 get() {
150 return this.$root.$options[key]
151 }
152 })
153 }
154 })
155 }
156 <% } %>
157
158 <% if (store) { %>
159 if (process.client || process.browser) {
160 <% if (isDev) { %>
161 if (process.browser) {
162 console.warn('process.browser is deprecated, use process.client instead.')
163 }
164 <% } %>
165 // Replace store state before plugins execution
166 if (window.<%= globals.context %> && window.<%= globals.context %>.state) {
167 store.replaceState(window.<%= globals.context %>.state)
168 }
169 }
170 <% } %>
171
172 // Plugin execution
173 <%= isTest ? '/* eslint-disable camelcase */' : '' %>
174 <% plugins.filter(p => p.ssr).forEach((plugin) => { %>
175 if (typeof <%= plugin.name %> === 'function') await <%= plugin.name %>(app.context, inject)<% }) %>
176 <% if (plugins.filter(p => !p.ssr).length) { %>
177 if (process.client || process.browser) {
178 <% if (isDev) { %>
179 if (process.browser) {
180 console.warn('process.browser is deprecated, use process.client instead.')
181 }
182 <% } %>
183 <% plugins.filter((p) => !p.ssr).forEach((plugin) => { %>
184 if (typeof <%= plugin.name %> === 'function') await <%= plugin.name %>(app.context, inject)<% }) %>
185 }<% } %>
186 <%= isTest ? '/* eslint-enable camelcase */' : '' %>
187
188 // If server-side, wait for async component to be resolved first
189 if (process.server && ssrContext && ssrContext.url) {
190 await new Promise((resolve, reject) => {
191 router.push(ssrContext.url, resolve, () => {
192 // navigated to a different route in router guard
193 const unregister = router.afterEach(async (to, from, next) => {
194 ssrContext.url = to.fullPath
195 app.context.route = await getRouteData(to)
196 app.context.params = to.params || {}
197 app.context.query = to.query || {}
198 unregister()
199 resolve()
200 })
201 })
202 })
203 }
204
205 return {
206 app,
207 <% if(store) { %>store,<% } %>
208 router
209 }
210}
211
212export { createApp, NuxtError }
213
\No newline at end of file