1
0
Fork 0
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:
Arunoda Susiripala 2017-04-11 22:07:59 +05:30
parent 7997c1fd3c
commit 6e0e7b4d5a

View file

@ -1,4 +1,6 @@
/* global window, document */ /* global window, document */
import mitt from 'mitt'
const webpackModule = module const webpackModule = module
export default class PageLoader { export default class PageLoader {
@ -6,6 +8,7 @@ export default class PageLoader {
this.buildId = buildId this.buildId = buildId
this.pageCache = {} this.pageCache = {}
this.pageLoadedHandlers = {} this.pageLoadedHandlers = {}
this.registerEvents = mitt()
this.loadingRoutes = {} this.loadingRoutes = {}
} }
@ -14,8 +17,7 @@ export default class PageLoader {
throw new Error('Route name should start with a "/"') throw new Error('Route name should start with a "/"')
} }
if (route === '/') return route return route.replace(/index$/, '')
return route.replace(/(\/)?(index)?$/, '')
} }
loadPage (route) { loadPage (route) {
@ -29,41 +31,37 @@ export default class PageLoader {
}) })
} }
if (this.loadingRoutes[route]) { return new Promise((resolve, reject) => {
return this.loadingRoutes[route] const fire = ({ error, page }) => {
this.registerEvents.off(route, fire)
if (error) {
reject(error)
} else {
resolve(page)
}
} }
const loadingPromise = new Promise((resolve, reject) => { this.registerEvents.on(route, fire)
this.loadScript(route, (error) => {
delete this.loadingRoutes[route]
if (error) return reject(error) // Load the script if not asked to load yet.
if (!this.loadingRoutes[route]) {
const cachedPage = this.pageCache[route] this.loadScript(route)
if (cachedPage.error) return reject(cachedPage.error) this.loadingRoutes[route] = true
return resolve(cachedPage.page) }
}) })
})
this.loadingRoutes[route] = loadingPromise
return loadingPromise
} }
loadScript (route, fn) { loadScript (route) {
route = this.normalizeRoute(route) route = this.normalizeRoute(route)
const script = document.createElement('script') const script = document.createElement('script')
const url = `/_next/${encodeURIComponent(this.buildId)}/page${route}` const url = `/_next/${encodeURIComponent(this.buildId)}/page${route}`
script.src = url script.src = url
script.type = 'text/javascript' script.type = 'text/javascript'
script.onerror = () => {
script.onerror = (e) => { const error = new Error(`Error when loading route: ${route}`)
const error = new Error(`Network error occurred when loading route: ${route}`) this.registerEvents.emit(route, { error })
fn(error)
}
script.onload = () => {
fn()
} }
document.body.appendChild(script) document.body.appendChild(script)
@ -71,12 +69,10 @@ export default class PageLoader {
// This method if called by the route code. // This method if called by the route code.
registerPage (route, regFn) { registerPage (route, regFn) {
route = this.normalizeRoute(route)
const register = () => { const register = () => {
// add the page to the cache
const { error, page } = regFn() const { error, page } = regFn()
this.pageCache[route] = { error, page } this.pageCache[route] = { error, page }
this.registerEvents.emit(route, { error, page })
} }
// Wait for webpack to became idle if it's not. // Wait for webpack to became idle if it's not.