2011.05.09

Single entry point FTW!

Many programming languages and environments require a Main Class, Main function or Main file as an entry-point to the program, it’s where the execution starts and also usually where you have access to command arguments. JavaScript on the browser isn’t one of those environments tho, and I think it is one of the reasons why many applications become a real maintenance nightmare. I believe that the “Main File/Function/Class” approach can help a lot to increase extensibility/maintainability and favor a good structure even for languages that doesn’t require this practice.

Many back-end frameworks started to adopt this technique over the past years, most of them have some sort of URL redirect that points to a “index” file or a router that decides which actions should be executed and which files should be loaded instead of having a single file for each page or section. This kind of abstraction increases flexibility a lot since you can just keep adding new pages/sections/features without having to care about the code structure, it also reduce code duplication since you don’t need to create a new file for each new page…

Flash projects have a Main Class which is the entry-point for the application and also works as the root node where all the child elements are attached (similar to the body element of an HTML file) and it helps you keep the code flow organized since you are sure that your Main Class constructor is executed before any other code, programs get easier to understand since it follows a logic order.

The JavaScript problem

HTML pages can have multiple script tags (and that is a good thing) but it causes many problems specially as websites starts to grow. Code can get very messy since you need global variables/objects to communicate across different files, it is harder to identify where the application initiates and which code gets executed first, having multiple requests also degrades performance – specially before `DOM Ready` since it blocks the HTML rendering. Another option is to create a single “Megazord” file which contains the whole code of your app, this tends to become unpractical for medium and large projects - the bigger the file the harder to read, understand and maintain it.

Having multiple entry-points makes the “code execution flow” harder to understand, you need to fully understand the application structure to be able to make changes without breaking things, the simple action of removing or re-ordering certain includes may break the whole application. You also have no idea of which files are required by all pages and which ones aren’t, your problems grows together with the complexity of your application leading to many headaches…

The solution

Single entry-point for the win!

I’ve been using the single entry-point approach on most of my latest JavaScript projects and I think it is helping me a lot to keep things under control. - I still regret for not using this approach on a few projects that grew way more than the original scope (as they usually do)

Instead of having multiple script tags or some sort of simple file concatenation (that only disguise the mess), include the same JavaScript file on ALL pages of your application/site, it doesn’t matter if you have 1, 2, 50 pages… that’s where the application starts. This file have a single task, identify which files should be loaded and executed, nothing else. If something needs to be changed, added or removed, you don’t need to ask the back-end developer to update the files, you don’t need to update the HTML files, changes are “encapsulated” into its own domain which also reduces errors.

My “main files” are usually small (under 50 lines) which makes it really easy to understand and very fast to load so even if the page doesn’t require JavaScript (yet) I include it, the file will be cached between pages and even if it isn’t there’s no problem since it is so small… It also simplifies the back-end logic since you can just reuse the same includes for all pages. The main rule here is organization, performance improvement is just a bonus that comes with it.

You can use URL mapping to find out which files should be loaded, like: if URL contains “/news/” than you know you should load the script file for the news section or call the function that initializes the news page, and so on… Another option is to add metadata to the HTML (probably using “data attributes”) to describe which components/modules are required by the page (e.g. calendar, scrollbar, news, etc) and initialize those components. The best approach will vary based on the project requirements. URL mapping is usually more appropriate for projects which relies heavily in JavaScript (i.e. construct DOM elements dynamically) while the metadata is usually better for projects that uses JavaScript as an enhancement and already have a base structure for the components on the HTML. – Both techniques can be combined if needed, using URL routing for section/page logic and metadata for dynamic content/components. Keep logic into the same domain (markup or script) to make it easier to update.

Pro tip

Use RequireJS* and benefit from it’s awesome dependency management and build tool (that combines and compress files for deployment). Break your application into multiple small files/modules for better organization (try to keep each file under 200 lines), group functions by similarity/context and keep a single entry point for your app, you will probably notice a huge organization improvement on the first couple projects. As soon as you understand how an AMD module works you will see that global variables aren’t needed anymore.

* other script loaders may be a good option as well, I’ve been using RequireJS since it is popular, have an active community, it’s “battle-tested” and AMD modules are awesome!

PS: If you need a powerful and flexible library for URL mapping/routing check Crossroads.js, my latest open-source project.

Related


Comments

[...] Check the project page and examples to know more about it. It can be specially helpful for large websites and single page apps – as I mentioned on my previous post. [...]

You can do the same thing (and much more!) in YUI3. Docs can be found here: http://developer.yahoo.com/yui/3/yui/#use. Sandboxing, lazy-loading, code separation and extremely good Widget and Plugin infrastructure which can greatly improve your app logic. Using YUI3 or not I highly recommend everyone watching all videos from http://developer.yahoo.com/yui/theater/. It is tutorial on how to make web UI's and don't get frustrated at the same time.

hi, right now I use your js router lib, very useful and helpful for me, thanks

Once I found require I could finally see how I could create rich web apps and the like. I too come from a Flash AS3 background and require was a killer find.

Leave a Comment

Please post only comments that will add value to the content of this page. Please read the about page to understand the objective of this blog and the way I think about it. Thanks.

Comments are parsed as Markdown and you can use basic HTML tags (a, blockquote, cite, code, del, em, strong) but some code may be striped if not escaped (specially PHP and HTML tags that aren't on the list). Line and paragraph breaks automatic. Code blocks should be indented with 4 spaces.