Last active
December 24, 2017 13:25
-
-
Save artemgurzhii/9f56401a227eaffd094205e1c7b0fdcb to your computer and use it in GitHub Desktop.
JS dynamic Code Splitting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Router | |
} from './helpers/router/lib'; | |
const router = new Router({ | |
mode: 'history', | |
root: '/' | |
}); | |
router | |
.add(/posts/, () => { | |
// Those files will be executed only on the routes, which urls match `/posts/` regexp. | |
Promise.all([ | |
import('./controllers/posts'), | |
import('./controllers/comments') | |
]).then(([Posts, Comments]) => { | |
new Posts.default(), | |
new Comments.default() | |
}) | |
}).add(() => { | |
// This file will be executed on all routes. | |
import('./controllers/application').then(Application => new Application.default); | |
}) | |
.listen() | |
.exec(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This code is tooked directly from my projects and can(should) be customized for your use. | |
//================== | |
// Used for the implicity | |
// Can be replaced with: | |
// isPresent(obj) && isPresent(obj.key) -> obj && obj.key | |
import { isPresent } from '../../is/lib'; | |
/** | |
* Routing system for the app. | |
* | |
* @class | |
* @classdesc Routing system. | |
* | |
* @example | |
* new Router({ mode: 'history', root: '/' }); | |
*/ | |
export default class Router { | |
constructor(options) { | |
this._routes = []; | |
this._mode = ( | |
isPresent(options) && options.mode === 'history' && isPresent(history.pushState) | |
) ? 'history' : 'hash'; | |
this._root = options && options.root ? options.root : '/'; | |
} | |
/** | |
* @description Get current route. | |
* | |
* @return {String} Current route | |
*/ | |
get() { | |
let route = ''; | |
if (this._mode === 'history') { | |
const URI = decodeURI(window.location.pathname + window.location.search); | |
route = this.removeSlashes(URI).replace(/\?(.*)$/, ''); | |
if (this._root !== '/') { | |
route = route.replace(this._root, ''); | |
} | |
} else { | |
const match = window.location.href.match(/#(.*)$/); | |
route = match ? match[1] : ''; | |
} | |
return this.removeSlashes(route); | |
} | |
/** | |
* @description Removes slashes from the beggining and the end. | |
* | |
* @param {String} path - Path from which to remove slashed. | |
* @return {String} Cleared path without slashes. | |
*/ | |
removeSlashes(path) { | |
return path | |
.toString() | |
.replace(/\/$/, '') | |
.replace(/^\//, ''); | |
} | |
/** | |
* @description Add a new route to handle. | |
* | |
* @param {Object} pattern - Pattern to which route should match. | |
* @return {This} | |
*/ | |
add(pattern, handler) { | |
if (typeof pattern === 'function') { | |
handler = pattern; | |
pattern = ''; | |
} | |
this._routes.push({ | |
pattern, | |
handler | |
}); | |
return this; | |
} | |
/** | |
* @description Remove route from router. | |
* | |
* @param {String|Object} param - Route to remove. | |
* @return {This} | |
*/ | |
remove(param) { | |
this._routes.forEach((route, i) => { | |
if (route.handler === param || route.pattern.toString() === param.toString()) { | |
this._routes.splice(i, 1); | |
return this; | |
} | |
}); | |
return this; | |
} | |
/** | |
* @description Drop all router settings. | |
* | |
* @return {This} | |
*/ | |
clean() { | |
this._routes = []; | |
this._mode = null; | |
this._root = '/'; | |
return this; | |
} | |
/** | |
* @description Execute code for special router | |
* | |
* @param {String} path - Path which code to execute | |
* @return {This} | |
*/ | |
exec(path = this.get()) { | |
this._routes.forEach(route => { | |
const match = path.match(route.pattern); | |
if (isPresent(match)) { | |
match.shift(); | |
route.handler.apply({}, match); | |
return this; | |
} | |
}); | |
return this; | |
} | |
/** | |
* @description Listen for the page path change. | |
* | |
* @return {This} | |
*/ | |
listen() { | |
let current = this.get(); | |
clearInterval(this.interval); | |
this.interval = setInterval(() => { | |
if (current !== this.get()) { | |
current = this.get(); | |
this.exec(current); | |
} | |
}, 50); | |
return this; | |
} | |
/** | |
* @description Navigate to other route. | |
* | |
* @param {String} [path=''] - Path to which navigate. | |
* @return {This} | |
*/ | |
navigateTo(path = '') { | |
if (this._mode === 'history') { | |
history.pushState(null, null, this._root + this.removeSlashes(path)); | |
} else { | |
window.location.href = `${window.location.href.replace(/#(.*)$/, '')}#${path}`; | |
} | |
return this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment