فهرست منبع

feat(ssr): add custom state serializer option

close #6614
Evan You 7 سال پیش
والد
کامیت
44940121ee
3فایلهای تغییر یافته به همراه35 افزوده شده و 3 حذف شده
  1. 5 2
      src/server/create-renderer.js
  2. 8 1
      src/server/template-renderer/index.js
  3. 22 0
      test/ssr/ssr-template.spec.js

+ 5 - 2
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 {

+ 8 - 1
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<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);}());'
       : ''

+ 22 - 0
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: '<div>hi</div>'
+      }), context, (err, res) => {
+        expect(err).toBeNull()
+        expect(res).toContain(
+          `<script>window.__INITIAL_STATE__=${expected}</script>`
+        )
+        done()
+      })
+    })
   }
 })