feat(ssr): add custom state serializer option

close #6614
This commit is contained in:
Evan You 2018-12-20 16:08:58 -05:00
parent 7ebabe2392
commit 44940121ee
3 changed files with 35 additions and 3 deletions

View File

@ -29,6 +29,7 @@ export type RenderOptions = {
shouldPreload?: Function;
shouldPrefetch?: Function;
clientManifest?: ClientManifest;
serializer?: Function;
runInNewContext?: boolean | 'once';
};
@ -41,7 +42,8 @@ export function createRenderer ({
cache,
shouldPreload,
shouldPrefetch,
clientManifest
clientManifest,
serializer
}: RenderOptions = {}): Renderer {
const render = createRenderFunction(modules, directives, isUnaryTag, cache)
const templateRenderer = new TemplateRenderer({
@ -49,7 +51,8 @@ export function createRenderer ({
inject,
shouldPreload,
shouldPrefetch,
clientManifest
clientManifest,
serializer
})
return {

View File

@ -16,6 +16,7 @@ type TemplateRendererOptions = {
clientManifest?: ClientManifest;
shouldPreload?: (file: string, type: string) => boolean;
shouldPrefetch?: (file: string, type: string) => boolean;
serializer?: Function;
};
export type ClientManifest = {
@ -47,6 +48,7 @@ export default class TemplateRenderer {
preloadFiles: Array<Resource>;
prefetchFiles: Array<Resource>;
mapFiles: AsyncFileMapper;
serialize: Function;
constructor (options: TemplateRendererOptions) {
this.options = options
@ -57,6 +59,11 @@ export default class TemplateRenderer {
? parseTemplate(options.template)
: null
// function used to serialize initial state JSON
this.serialize = options.serializer || (state => {
return serialize(state, { isJSON: true })
})
// extra functionality with client manifest
if (options.clientManifest) {
const clientManifest = this.clientManifest = options.clientManifest
@ -194,7 +201,7 @@ export default class TemplateRenderer {
contextKey = 'state',
windowKey = '__INITIAL_STATE__'
} = options || {}
const state = serialize(context[contextKey], { isJSON: true })
const state = this.serialize(context[contextKey])
const autoRemove = process.env.NODE_ENV === 'production'
? ';(function(){var s;(s=document.currentScript||document.scripts[document.scripts.length-1]).parentNode.removeChild(s);}());'
: ''

View File

@ -489,5 +489,27 @@ describe('SSR: template option', () => {
done()
})
})
it('renderToString + custom serializer', done => {
const expected = `{"foo":123}`
const renderer = createRenderer({
template: defaultTemplate,
serializer: () => expected
})
const context = {
state: { a: 1 }
}
renderer.renderToString(new Vue({
template: '<div>hi</div>'
}), context, (err, res) => {
expect(err).toBeNull()
expect(res).toContain(
`<script>window.__INITIAL_STATE__=${expected}</script>`
)
done()
})
})
}
})