Skip to content

Commit 4494012

Browse files
committed
feat(ssr): add custom state serializer option
close #6614
1 parent 7ebabe2 commit 4494012

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

src/server/create-renderer.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type RenderOptions = {
2929
shouldPreload?: Function;
3030
shouldPrefetch?: Function;
3131
clientManifest?: ClientManifest;
32+
serializer?: Function;
3233
runInNewContext?: boolean | 'once';
3334
};
3435

@@ -41,15 +42,17 @@ export function createRenderer ({
4142
cache,
4243
shouldPreload,
4344
shouldPrefetch,
44-
clientManifest
45+
clientManifest,
46+
serializer
4547
}: RenderOptions = {}): Renderer {
4648
const render = createRenderFunction(modules, directives, isUnaryTag, cache)
4749
const templateRenderer = new TemplateRenderer({
4850
template,
4951
inject,
5052
shouldPreload,
5153
shouldPrefetch,
52-
clientManifest
54+
clientManifest,
55+
serializer
5356
})
5457

5558
return {

src/server/template-renderer/index.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type TemplateRendererOptions = {
1616
clientManifest?: ClientManifest;
1717
shouldPreload?: (file: string, type: string) => boolean;
1818
shouldPrefetch?: (file: string, type: string) => boolean;
19+
serializer?: Function;
1920
};
2021

2122
export type ClientManifest = {
@@ -47,6 +48,7 @@ export default class TemplateRenderer {
4748
preloadFiles: Array<Resource>;
4849
prefetchFiles: Array<Resource>;
4950
mapFiles: AsyncFileMapper;
51+
serialize: Function;
5052

5153
constructor (options: TemplateRendererOptions) {
5254
this.options = options
@@ -57,6 +59,11 @@ export default class TemplateRenderer {
5759
? parseTemplate(options.template)
5860
: null
5961

62+
// function used to serialize initial state JSON
63+
this.serialize = options.serializer || (state => {
64+
return serialize(state, { isJSON: true })
65+
})
66+
6067
// extra functionality with client manifest
6168
if (options.clientManifest) {
6269
const clientManifest = this.clientManifest = options.clientManifest
@@ -194,7 +201,7 @@ export default class TemplateRenderer {
194201
contextKey = 'state',
195202
windowKey = '__INITIAL_STATE__'
196203
} = options || {}
197-
const state = serialize(context[contextKey], { isJSON: true })
204+
const state = this.serialize(context[contextKey])
198205
const autoRemove = process.env.NODE_ENV === 'production'
199206
? ';(function(){var s;(s=document.currentScript||document.scripts[document.scripts.length-1]).parentNode.removeChild(s);}());'
200207
: ''

test/ssr/ssr-template.spec.js

+22
Original file line numberDiff line numberDiff line change
@@ -489,5 +489,27 @@ describe('SSR: template option', () => {
489489
done()
490490
})
491491
})
492+
493+
it('renderToString + custom serializer', done => {
494+
const expected = `{"foo":123}`
495+
const renderer = createRenderer({
496+
template: defaultTemplate,
497+
serializer: () => expected
498+
})
499+
500+
const context = {
501+
state: { a: 1 }
502+
}
503+
504+
renderer.renderToString(new Vue({
505+
template: '<div>hi</div>'
506+
}), context, (err, res) => {
507+
expect(err).toBeNull()
508+
expect(res).toContain(
509+
`<script>window.__INITIAL_STATE__=${expected}</script>`
510+
)
511+
done()
512+
})
513+
})
492514
}
493515
})

0 commit comments

Comments
 (0)