Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the Singleton Router API #429

Merged
merged 6 commits into from
Dec 19, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use the new SingletonRouter for HMR error handling.
  • Loading branch information
arunoda committed Dec 19, 2016
commit 77413a293584e9a6ecff496ddb8ff372f4e70086
7 changes: 1 addition & 6 deletions client/next.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,12 @@ const {
const Component = evalScript(component).default
const ErrorComponent = evalScript(errorComponent).default

const router = createRouter(pathname, query, {
export const router = createRouter(pathname, query, {
Component,
ErrorComponent,
ctx: { err }
})

// This it to support error handling in the dev time with hot code reload.
if (window.next) {
window.next.router = router
}

const headManager = new HeadManager()
const container = document.getElementById('__next')
const appProps = { Component, props, router, headManager }
Expand Down
14 changes: 7 additions & 7 deletions client/webpack-hot-middleware-client.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
/* global next */
import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?overlay=false&reload=true'
import Router from '../lib/router'

const handlers = {
reload (route) {
if (route === '/_error') {
for (const r of Object.keys(next.router.components)) {
const { Component } = next.router.components[r]
for (const r of Object.keys(Router.components)) {
const { Component } = Router.components[r]
if (Component.__route === '/_error-debug') {
// reload all '/_error-debug'
// which are expected to be errors of '/_error' routes
next.router.reload(r)
Router.reload(r)
}
}
return
}

next.router.reload(route)
Router.reload(route)
},
change (route) {
const { Component } = next.router.components[route] || {}
const { Component } = Router.components[route] || {}
if (Component && Component.__route === '/_error-debug') {
// reload to recover from runtime errors
next.router.reload(route)
Router.reload(route)
}
},
hardReload () {
Expand Down
33 changes: 20 additions & 13 deletions lib/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,26 @@ export const createRouter = function (...args) {

router = new _Router(...args)

// Assign the router to the SingletonRouter object
for (const name of router) {
const property = router[name]
if (typeof property === 'function') {
SingletonRouter[name] = router[name].bind(router)
} else {
Object.defineProperty(SingletonRouter, name, {
get () {
return router[name]
}
})
}
}
// Move public properties and method from the actual router
// instance to the SingletonRouter
const propertyFields = ['route', 'components', 'pathname', 'query']
const methodFields = ['push', 'replace', 'reload', 'back']

propertyFields.forEach((field) => {
// Here we need to use Object.defineProperty because, we need to return
// the property assigned to the actual router
// The value might get changed as we change routes and this is the
// proper way to access it
Object.defineProperty(SingletonRouter, field, {
get () {
return router[field]
}
})
})

methodFields.forEach((field) => {
SingletonRouter[field] = router[field].bind(router)
})

return router
}
Expand Down