fix(vue-renderer): clone spa meta to prevent cache modification (#5964)

This commit is contained in:
Ustun Ozgur 2019-06-27 20:17:43 +00:00 committed by Pooya Parsa
parent d1395a032a
commit ae9d3519f7
3 changed files with 36 additions and 5 deletions

View File

@ -1,4 +1,5 @@
import { extname } from 'path' import { extname } from 'path'
import cloneDeep from 'lodash/cloneDeep'
import Vue from 'vue' import Vue from 'vue'
import VueMeta from 'vue-meta' import VueMeta from 'vue-meta'
import { createRenderer } from 'vue-server-renderer' import { createRenderer } from 'vue-server-renderer'
@ -43,7 +44,9 @@ export default class SPARenderer extends BaseRenderer {
let meta = this.cache.get(cacheKey) let meta = this.cache.get(cacheKey)
if (meta) { if (meta) {
return meta // Return a copy of the content, so that future
// modifications do not effect the data in cache
return cloneDeep(meta)
} }
meta = { meta = {
@ -149,7 +152,9 @@ export default class SPARenderer extends BaseRenderer {
// Set meta tags inside cache // Set meta tags inside cache
this.cache.set(cacheKey, content) this.cache.set(cacheKey, content)
return content // Return a copy of the content, so that future
// modifications do not effect the data in cache
return cloneDeep(content)
} }
static normalizeFile(file) { static normalizeFile(file) {

View File

@ -1,3 +1,10 @@
function modifyHtml(html) {
return html.replace(
'</body>',
`<!-- extra html from render:route hook added at ${Date.now()}--></body>`
)
}
export default { export default {
mode: 'spa', mode: 'spa',
pageTransition: false, pageTransition: false,
@ -18,7 +25,10 @@ export default {
router: { router: {
middleware: 'middleware' middleware: 'middleware'
}, },
plugins: [ plugins: ['~/plugins/error.js'],
'~/plugins/error.js' hooks: {
] 'render:route': (url, page, { req, res }) => {
page.html = modifyHtml(page.html)
}
}
} }

View File

@ -138,6 +138,22 @@ describe('spa', () => {
consola.log.mockClear() consola.log.mockClear()
}) })
test('render:route hook does not corrupt the cache', async () => {
const window1 = await nuxt.server.renderAndGetWindow(url('/'))
const html1 = window1.document.body.innerHTML
expect(html1).toContain('extra html from render:route hook')
expect(html1.match(/render:route/g).length).toBe(1)
window1.close()
const window2 = await nuxt.server.renderAndGetWindow(url('/'))
const html2 = window2.document.body.innerHTML
expect(html2).toContain('extra html from render:route hook')
expect(html2.match(/render:route/g).length).toBe(1)
window2.close()
})
// Close server and ask nuxt to stop listening to file changes // Close server and ask nuxt to stop listening to file changes
afterAll(async () => { afterAll(async () => {
await nuxt.close() await nuxt.close()