Merge remote-tracking branch 'origin/2.x' into dev

This commit is contained in:
Clark Du 2019-02-15 13:18:09 +00:00
commit 5f9b1044ff
5 changed files with 62 additions and 15 deletions

View File

@ -1,7 +1,5 @@
import Vue from 'vue'
const noopData = () => ({})
// window.{{globals.loadedCallback}} hook
// Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading)
if (process.client) {
@ -24,12 +22,17 @@ export function interopDefault(promise) {
}
export function applyAsyncData(Component, asyncData) {
const ComponentData = Component.options.data || noopData
// Prevent calling this method for each request on SSR context
if (!asyncData && Component.options.hasAsyncData) {
if (
// For SSR, we once all this function without second param to just apply asyncData
// Prevent doing this for each SSR request
!asyncData && Component.options.__hasNuxtData
) {
return
}
Component.options.hasAsyncData = true
const ComponentData = Component.options._originDataFn || Component.options.data || function () { return {} }
Component.options._originDataFn = ComponentData
Component.options.data = function () {
const data = ComponentData.call(this)
if (this.$ssrContext) {
@ -37,6 +40,9 @@ export function applyAsyncData(Component, asyncData) {
}
return { ...data, ...asyncData }
}
Component.options.__hasNuxtData = true
if (Component._Ctor && Component._Ctor.options) {
Component._Ctor.options.data = Component.options.data
}

View File

@ -73,16 +73,20 @@ export default class SPAMetaRenderer {
meta.resourceHints = ''
const { clientManifest } = this.renderer.context.resources
const { modernManifest, clientManifest } = this.renderer.context.resources
const manifest = this.options.modern ? modernManifest : clientManifest
const { shouldPreload, shouldPrefetch } = this.options.render.bundleRenderer
if (this.options.render.resourceHints && clientManifest) {
const publicPath = clientManifest.publicPath || '/_nuxt/'
if (this.options.render.resourceHints && manifest) {
const publicPath = manifest.publicPath || '/_nuxt/'
// Preload initial resources
if (Array.isArray(clientManifest.initial)) {
meta.resourceHints += clientManifest.initial
if (Array.isArray(manifest.initial)) {
const { crossorigin } = this.options.build
const cors = `${crossorigin ? ` crossorigin="${crossorigin}"` : ''}`
meta.resourceHints += manifest.initial
.map(SPAMetaRenderer.normalizeFile)
.filter(({ fileWithoutQuery, asType }) => shouldPreload(fileWithoutQuery, asType))
.map(({ file, extension, fileWithoutQuery, asType }) => {
@ -90,15 +94,15 @@ export default class SPAMetaRenderer {
if (asType === 'font') {
extra = ` type="font/${extension}" crossorigin`
}
return `<link rel="preload" href="${publicPath}${file}"${
return `<link rel="${this.options.modern ? 'module' : ''}preload"${cors} href="${publicPath}${file}"${
asType !== '' ? ` as="${asType}"` : ''}${extra}>`
})
.join('')
}
// Prefetch async resources
if (Array.isArray(clientManifest.async)) {
meta.resourceHints += clientManifest.async
if (Array.isArray(manifest.async)) {
meta.resourceHints += manifest.async
.map(SPAMetaRenderer.normalizeFile)
.filter(({ fileWithoutQuery, asType }) => shouldPrefetch(fileWithoutQuery, asType))
.map(({ file }) => `<link rel="prefetch" href="${publicPath}${file}">`)

20
test/fixtures/spa/pages/async.vue vendored Normal file
View File

@ -0,0 +1,20 @@
<template>
<pre>
{{ debug }}
</pre>
</template>
<script>
export default {
asyncData() {
return {
[Math.random()]: true
}
},
computed: {
debug() {
return JSON.stringify(this.$data, null, 2)
}
}
}
</script>

View File

@ -31,7 +31,7 @@ describe('modern client mode (SPA)', () => {
expect(response).toContain('<script type="module" src="/_nuxt/modern-commons.app.js" crossorigin="use-credentials"')
})
test.skip('should contain module preload resources', async () => {
test('should contain module preload resources', async () => {
const response = await rp(url('/'))
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-app.js" as="script">')
expect(response).toContain('<link rel="modulepreload" crossorigin="use-credentials" href="/_nuxt/modern-commons.app.js" as="script">')

View File

@ -82,6 +82,23 @@ describe('spa', () => {
expect(consola.log).toHaveBeenCalledWith('mounted')
consola.log.mockClear()
})
test('/async no asyncData leak', async () => {
const window = await nuxt.server.renderAndGetWindow(url('/async'))
const navigate = url => new Promise((resolve, reject) => {
window.$nuxt.$router.push(url, resolve, reject)
})
for (let i = 0; i < 3; i++) {
await navigate('/')
await navigate('/async')
}
const { $data } = window.$nuxt.$route.matched[0].instances.default
expect(Object.keys($data).length).toBe(1)
})
// Close server and ask nuxt to stop listening to file changes
afterAll(async () => {
await nuxt.close()