From 44940121eef4e2df5f3cb3c21f3f468af8b336bc Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 20 Dec 2018 16:08:58 -0500 Subject: [PATCH] feat(ssr): add custom state serializer option close #6614 --- src/server/create-renderer.js | 7 +++++-- src/server/template-renderer/index.js | 9 ++++++++- test/ssr/ssr-template.spec.js | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/server/create-renderer.js b/src/server/create-renderer.js index 0d335462147..1cfbfb0ddd9 100644 --- a/src/server/create-renderer.js +++ b/src/server/create-renderer.js @@ -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 { diff --git a/src/server/template-renderer/index.js b/src/server/template-renderer/index.js index 0233d157646..269673fb3d7 100644 --- a/src/server/template-renderer/index.js +++ b/src/server/template-renderer/index.js @@ -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; prefetchFiles: Array; 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);}());' : '' diff --git a/test/ssr/ssr-template.spec.js b/test/ssr/ssr-template.spec.js index c9cc001b7bd..d3e81e83159 100644 --- a/test/ssr/ssr-template.spec.js +++ b/test/ssr/ssr-template.spec.js @@ -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: '
hi
' + }), context, (err, res) => { + expect(err).toBeNull() + expect(res).toContain( + `` + ) + done() + }) + }) } })