Bootstrap Example

Core Library for W3C Browser Frontside Applications

View project on GitHub

« Back

Intro

The bootstrappers responsability is the congigure the environment of the application.
The bootstrapper should be the only place in that location and installation related data is placed. The rest of the project code design must be independend of the installation configuration.
The CoreJS-W3C provides via use and namespace functionality to archieve that design.

The bootstrap process

In follow is used the code of the Page Manger.

src/bootstrap.js

use.psr4("CoreJs", "node_modules/corejs-w3c/src");
use.psr4("PageManager", "src");

/* global PageManager */
use("PageManager.Main");
use("CoreJs.Bootstrap.HeadCleaner");

/**
* Bootstrapper. 
*/
function Bootstrap() {
	CoreJs.Event.Handler.call(this);
}
Bootstrap.prototype = Object.create(CoreJs.Event.Handler.prototype);
Bootstrap.prototype.construct = Bootstrap;

Bootstrap.prototype.handleEvent = function() {
	// unbind
	window.removeEventListener("load", this);
	
	// load & start application
	// Info: namespace() is neccesary to have an auto-re-try after loading
	//       the main files.
	namespace("PageManager", function() {
		(new CoreJs.Bootstrap.HeadCleaner(document.head)).clean();
		
		this.app = new PageManager.Main();
		this.app.run();
	});
};

var loader = new Bootstrap();
window.addEventListener("load", loader);

Now in detail:

Configuration of the CoreJs location

use.psr4("CoreJs", "node_modules/corejs-w3c/src");

The definition at which place is the CoreJS-W3C installed. It could also be an full qualified URL like:

use.psr4("CoreJs", "http://rawgit.com/enbock/corejs-w3c/master/src");

Configuration of the project’s source

use.psr4("PageManager", "src");

Same as the CoreJs definition is here the path/url to the project source defines. In this example will all source code place the in PageManager namespace.

Loading the primary code

use("CoreJs.Bootstrap.HeadCleaner");
use("PageManager.Main");

The HeadCleaner is maybe the most unneeded tool. But it is nice to have a clean DOM tree. The seconds use is the Main program of the PageManager.

The files are of the class code are now scheduled to load. The loading process will be asynchronous. But with help of namespace we can ignore the asynchrony and can continue as it will be synchronous.

The Bootstrap class

This is the last class outside of a namespace. This small code is used to stick on the window load process and starts the project after the document is ready.
Typically is the Bootstraper extended from the CoreJs.Event.Handler.

We will be created as a local window object and bound to the 'load' event of window:

var loader = new Bootstrap();
window.addEventListener("load", loader);

Project start

Bootstrap.prototype.handleEvent = function() {
	// unbind
	window.removeEventListener("load", this);
	
	// load & start application
	namespace("PageManager", function() {
		(new CoreJs.Bootstrap.HeadCleaner(document.head)).clean();
		
		this.app = new PageManager.Main();
		this.app.run();
	});
};

The first of the handler function is, to release the bound of the window load event:

window.removeEventListener("load", this);

Normalize the event will not called a second time. But it is always good to have an clean event listener.

As next will be load the application into the projects namespace:

namespace("PageManager", function() {
	(new CoreJs.Bootstrap.HeadCleaner(document.head)).clean();
	
	this.app = new PageManager.Main();
	this.app.run();
});

At first we start a bit out of scope and let run the HeadCleaner.

Why inside of the namespace?

The namespace interact with the use functionality. Only that combination allows to think in sychnronous loading.
In real catch the TypeError or the RefernceError and wait for the Ajax Load Event. After the code file was loaded, executes the namespace the loading code(the 2nd parameter) again. Theoretical could call the bootstrap code twice. For the HeadCleaner is it no problem. But to avoid a duplicaed application we can use a very primitve trick:

namespace("PageManager", function() {
	(new CoreJs.Bootstrap.HeadCleaner(document.head)).clean();
	
	if(!this.app) {
		this.app = new PageManager.Main();
		this.app.run();
	}
});

How does that work? Via the this pointer, which is always the context of the specified namespace(here PageManager) we store the application object(this.app).
Also you can if it needed access the application via the namespace(ie: PageManager.app).

If you don’t like that approach, you can check at first, that all needed classes are loaded:

namespace("PageManager", function() {
	// Synchroize preconditions
	if(!CoreJs.Bootstrap.HeadCleaner) throw new TypeError()
	if(!PageManager.Main) throw new TypeError()

	(new CoreJs.Bootstrap.HeadCleaner(document.head)).clean();
	
	this.app = new PageManager.Main();
	this.app.run();
});

or

namespace("PageManager", function() {
	var cleaner = new CoreJs.Bootstrap.HeadCleaner(document.head);
	this.app    = new PageManager.Main();
	
	cleaner.clean();
	this.app.run();
});