mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Came back to the mitt() based page-loader.
This commit is contained in:
parent
7997c1fd3c
commit
6e0e7b4d5a
|
@ -1,4 +1,6 @@
|
|||
/* global window, document */
|
||||
import mitt from 'mitt'
|
||||
|
||||
const webpackModule = module
|
||||
|
||||
export default class PageLoader {
|
||||
|
@ -6,6 +8,7 @@ export default class PageLoader {
|
|||
this.buildId = buildId
|
||||
this.pageCache = {}
|
||||
this.pageLoadedHandlers = {}
|
||||
this.registerEvents = mitt()
|
||||
this.loadingRoutes = {}
|
||||
}
|
||||
|
||||
|
@ -14,8 +17,7 @@ export default class PageLoader {
|
|||
throw new Error('Route name should start with a "/"')
|
||||
}
|
||||
|
||||
if (route === '/') return route
|
||||
return route.replace(/(\/)?(index)?$/, '')
|
||||
return route.replace(/index$/, '')
|
||||
}
|
||||
|
||||
loadPage (route) {
|
||||
|
@ -29,41 +31,37 @@ export default class PageLoader {
|
|||
})
|
||||
}
|
||||
|
||||
if (this.loadingRoutes[route]) {
|
||||
return this.loadingRoutes[route]
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const fire = ({ error, page }) => {
|
||||
this.registerEvents.off(route, fire)
|
||||
|
||||
const loadingPromise = new Promise((resolve, reject) => {
|
||||
this.loadScript(route, (error) => {
|
||||
delete this.loadingRoutes[route]
|
||||
if (error) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(page)
|
||||
}
|
||||
}
|
||||
|
||||
if (error) return reject(error)
|
||||
this.registerEvents.on(route, fire)
|
||||
|
||||
const cachedPage = this.pageCache[route]
|
||||
if (cachedPage.error) return reject(cachedPage.error)
|
||||
return resolve(cachedPage.page)
|
||||
})
|
||||
// Load the script if not asked to load yet.
|
||||
if (!this.loadingRoutes[route]) {
|
||||
this.loadScript(route)
|
||||
this.loadingRoutes[route] = true
|
||||
}
|
||||
})
|
||||
|
||||
this.loadingRoutes[route] = loadingPromise
|
||||
return loadingPromise
|
||||
}
|
||||
|
||||
loadScript (route, fn) {
|
||||
loadScript (route) {
|
||||
route = this.normalizeRoute(route)
|
||||
|
||||
const script = document.createElement('script')
|
||||
const url = `/_next/${encodeURIComponent(this.buildId)}/page${route}`
|
||||
script.src = url
|
||||
script.type = 'text/javascript'
|
||||
|
||||
script.onerror = (e) => {
|
||||
const error = new Error(`Network error occurred when loading route: ${route}`)
|
||||
fn(error)
|
||||
}
|
||||
|
||||
script.onload = () => {
|
||||
fn()
|
||||
script.onerror = () => {
|
||||
const error = new Error(`Error when loading route: ${route}`)
|
||||
this.registerEvents.emit(route, { error })
|
||||
}
|
||||
|
||||
document.body.appendChild(script)
|
||||
|
@ -71,12 +69,10 @@ export default class PageLoader {
|
|||
|
||||
// This method if called by the route code.
|
||||
registerPage (route, regFn) {
|
||||
route = this.normalizeRoute(route)
|
||||
|
||||
const register = () => {
|
||||
// add the page to the cache
|
||||
const { error, page } = regFn()
|
||||
this.pageCache[route] = { error, page }
|
||||
this.registerEvents.emit(route, { error, page })
|
||||
}
|
||||
|
||||
// Wait for webpack to became idle if it's not.
|
||||
|
|
Loading…
Reference in a new issue