mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 08:02:01 +00:00
76 lines
2.1 KiB
JavaScript
76 lines
2.1 KiB
JavaScript
import consola from 'consola'
|
|
import { timeout } from '@nuxt/utils'
|
|
|
|
export default async function renderAndGetWindow (
|
|
url = 'http://localhost:3000',
|
|
jsdomOpts = {},
|
|
{
|
|
loadedCallback,
|
|
loadingTimeout = 2000,
|
|
globals
|
|
} = {}
|
|
) {
|
|
const jsdom = await import('jsdom')
|
|
.then(m => m.default || m)
|
|
.catch((e) => {
|
|
consola.error(`
|
|
jsdom is not installed. Please install jsdom with:
|
|
$ yarn add --dev jsdom
|
|
OR
|
|
$ npm install --dev jsdom
|
|
`)
|
|
throw e
|
|
})
|
|
|
|
const options = Object.assign({
|
|
// Load subresources (https://github.com/tmpvar/jsdom#loading-subresources)
|
|
resources: 'usable',
|
|
runScripts: 'dangerously',
|
|
virtualConsole: true,
|
|
beforeParse (window) {
|
|
// Mock window.scrollTo
|
|
window.scrollTo = () => {}
|
|
}
|
|
}, jsdomOpts)
|
|
|
|
const jsdomErrHandler = (err) => {
|
|
throw err
|
|
}
|
|
|
|
if (options.virtualConsole) {
|
|
if (options.virtualConsole === true) {
|
|
options.virtualConsole = new jsdom.VirtualConsole().sendTo(consola)
|
|
}
|
|
// Throw error when window creation failed
|
|
options.virtualConsole.on('jsdomError', jsdomErrHandler)
|
|
} else {
|
|
// If we get the virtualConsole option as `false` we should delete for don't pass it to `jsdom.JSDOM.fromURL`
|
|
delete options.virtualConsole
|
|
}
|
|
|
|
const { window } = await jsdom.JSDOM.fromURL(url, options)
|
|
|
|
// If Nuxt could not be loaded (error from the server-side)
|
|
const nuxtExists = window.document.body.innerHTML.includes(`id="${globals.id}"`)
|
|
|
|
if (!nuxtExists) {
|
|
const error = new Error('Could not load the nuxt app')
|
|
error.body = window.document.body.innerHTML
|
|
window.close()
|
|
throw error
|
|
}
|
|
|
|
// Used by Nuxt to say when the components are loaded and the app ready
|
|
await timeout(new Promise((resolve) => {
|
|
window[loadedCallback] = () => resolve(window)
|
|
}), loadingTimeout, `Components loading in renderAndGetWindow was not completed in ${loadingTimeout / 1000}s`)
|
|
|
|
if (options.virtualConsole) {
|
|
// After window initialized successfully
|
|
options.virtualConsole.removeListener('jsdomError', jsdomErrHandler)
|
|
}
|
|
|
|
// Send back window object
|
|
return window
|
|
}
|