mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
Merge remote-tracking branch 'origin/2.x' into dev
This commit is contained in:
commit
5f9b1044ff
@ -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
|
||||
}
|
||||
|
@ -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
20
test/fixtures/spa/pages/async.vue
vendored
Normal 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>
|
@ -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">')
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user