feat: ssr provider default options + config + globalPrefetch + mockInstance
This commit is contained in:
committed by
Guillaume Chau
parent
cd47404435
commit
11fc590ea8
@@ -6,6 +6,35 @@ See [SSR guide](../guide/ssr.md).
|
||||
|
||||
## Methods
|
||||
|
||||
### install
|
||||
|
||||
Install the SSR plugin only on the server with:
|
||||
|
||||
```js
|
||||
Vue.use(ApolloSSR)
|
||||
```
|
||||
|
||||
You can pass additional options like this:
|
||||
|
||||
```js
|
||||
Vue.use(ApolloSSR, {
|
||||
fetchPolicy: 'network-only',
|
||||
suppressRenderErrors: false,
|
||||
})
|
||||
```
|
||||
|
||||
#### fetchPolicy
|
||||
|
||||
When an Apollo query is prefetched, it's recommended to override `fetchPolicy` to force the queries to happen.
|
||||
|
||||
Default value: `'network-only'`.
|
||||
|
||||
#### suppressRenderErrors
|
||||
|
||||
Silent the fake render errors.
|
||||
|
||||
Default value: `false`.
|
||||
|
||||
### prefetchAll
|
||||
|
||||
Prefetches all queued component definitions and returns a promise resolved when all corresponding apollo data is ready.
|
||||
@@ -53,3 +82,40 @@ const js = ApolloSSR.exportStates(apolloProvider, options)
|
||||
exportNamespace: '',
|
||||
}
|
||||
```
|
||||
|
||||
### globalPrefetch
|
||||
|
||||
Allow you to register a component to be prefetched explicitely.
|
||||
|
||||
Simple example:
|
||||
|
||||
```js
|
||||
import MyComponent from '@/components/MyComponent.vue'
|
||||
|
||||
ApolloSSR.globalPrefetch(() => MyComponent)
|
||||
```
|
||||
|
||||
You can disable prefetching depending on context:
|
||||
|
||||
```js
|
||||
ApolloSSR.globalPrefetch(context => {
|
||||
if (context.route.name === 'foo'){
|
||||
return MyComponent
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### mockInstance
|
||||
|
||||
During `prefetchAll`, the app components tree is re-created with fake instances so the process is faster. You can apply plugins to modify the fake instances to prevent their render functions to crash if you have helpers like `this.$http` that is accessed in the template or render function (typically `Undefined error`). It's recommended to mock those helpers to improve performance.
|
||||
|
||||
```js
|
||||
const noop = () => {}
|
||||
|
||||
ApolloSSR.mockInstance({
|
||||
apply: vm => {
|
||||
// Mock $http
|
||||
vm.$http = noop
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
+8
-2
@@ -140,7 +140,11 @@ import Vue from 'vue'
|
||||
import ApolloSSR from 'vue-apollo/ssr'
|
||||
import App from './App.vue'
|
||||
|
||||
Vue.use(ApolloSSR)
|
||||
Vue.use(ApolloSSR, {
|
||||
// SSR config
|
||||
fetchPolicy: 'network-only',
|
||||
suppressRenderErrors: false,
|
||||
})
|
||||
|
||||
export default () => new Promise((resolve, reject) => {
|
||||
const { app, router, store, apolloProvider } = CreateApp({
|
||||
@@ -360,4 +364,6 @@ export default () => new Promise((resolve, reject) => {
|
||||
// Prefetch, render HTML (see above)
|
||||
})
|
||||
})
|
||||
```
|
||||
```
|
||||
|
||||
See the [SSR API](../api/ssr.md) for more details and other features.
|
||||
|
||||
+44
-11
@@ -3,12 +3,29 @@ const { VUE_APOLLO_QUERY_KEYWORDS } = require('../lib/consts')
|
||||
const { createFakeInstance, resolveComponent } = require('./utils')
|
||||
const { Globals, getMergedDefinition, omit } = require('../lib/utils')
|
||||
|
||||
exports.install = function (Vue) {
|
||||
Globals.Vue = Vue
|
||||
const config = exports.config = {
|
||||
globalPrefetchs: [],
|
||||
fakeInstanceMocks: [],
|
||||
fetchPolicy: 'network-only',
|
||||
suppressRenderErrors: false,
|
||||
}
|
||||
|
||||
exports.prefetchAll = function (apolloProvider, components, context) {
|
||||
return exports.getQueriesFromTree(components, context)
|
||||
exports.install = function (Vue, options = {}) {
|
||||
Globals.Vue = Vue
|
||||
Object.assign(config, options)
|
||||
}
|
||||
|
||||
exports.globalPrefetch = function (handler) {
|
||||
config.globalPrefetchs.push(handler)
|
||||
}
|
||||
|
||||
exports.mockInstance = function (plugin) {
|
||||
config.fakeInstanceMocks.push(plugin)
|
||||
}
|
||||
|
||||
exports.prefetchAll = function (apolloProvider, components = [], context = {}) {
|
||||
const globalPrefetchs = config.globalPrefetchs.map(handler => handler(context)).filter(Boolean)
|
||||
return exports.getQueriesFromTree(components.concat(globalPrefetchs), context)
|
||||
.then(queries => Promise.all(queries.map(
|
||||
query => prefetchQuery(apolloProvider, query, context)
|
||||
)))
|
||||
@@ -27,6 +44,13 @@ function walkTree (component, data, parent, children, context, queries, componen
|
||||
const queue = []
|
||||
data = data || {}
|
||||
const vm = createFakeInstance(component, data, parent, children, context)
|
||||
|
||||
// Mocks
|
||||
for (const mock of config.fakeInstanceMocks) {
|
||||
mock.apply(mock)
|
||||
}
|
||||
|
||||
// Render h function
|
||||
vm.$createElement = (el, data, children) => {
|
||||
if (typeof data === 'string' || Array.isArray(data)) {
|
||||
children = data
|
||||
@@ -58,8 +82,10 @@ function walkTree (component, data, parent, children, context, queries, componen
|
||||
try {
|
||||
component.render.call(vm, vm.$createElement)
|
||||
} catch (e) {
|
||||
console.log(chalk.red(`Error while rendering ${component.name || component.__file}`))
|
||||
console.log(e.stack)
|
||||
if (!config.suppressRenderErrors) {
|
||||
console.log(chalk.red(`Error while rendering ${component.name || component.__file}`))
|
||||
console.log(e.stack)
|
||||
}
|
||||
}
|
||||
|
||||
Promise.all(queue).then(queue => queue.filter(child => !!child).map(
|
||||
@@ -163,15 +189,22 @@ function prefetchQuery (apolloProvider, query, context) {
|
||||
queryOptions.query = queryOptions.query.call(vm)
|
||||
}
|
||||
|
||||
const options = omit(queryOptions, [
|
||||
...VUE_APOLLO_QUERY_KEYWORDS,
|
||||
'fetchPolicy',
|
||||
])
|
||||
// Default query options from apollo provider
|
||||
if (apolloProvider.defaultOptions && apolloProvider.defaultOptions.$query) {
|
||||
queryOptions = Object.assign({}, apolloProvider.defaultOptions.$query, queryOptions)
|
||||
}
|
||||
|
||||
// Remove vue-apollo specific options
|
||||
const options = omit(queryOptions, VUE_APOLLO_QUERY_KEYWORDS)
|
||||
options.variables = variables
|
||||
options.fetchPolicy = 'network-only'
|
||||
// Override fetchPolicy
|
||||
if (config.fetchPolicy != null) {
|
||||
options.fetchPolicy = config.fetchPolicy
|
||||
}
|
||||
|
||||
return client.query(options)
|
||||
} catch (e) {
|
||||
console.log(chalk.red(`[ERROR] While prefetching query`), query, chalk.grey(`Error stack trace:`))
|
||||
console.log(e.stack)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user