So it is 2009 and JavaScript is major. The internet no longer consists of only simple page oriented web sites, but large scale, dynamic web applications as well. An application like Gmail is massive and written completely in JavaScript. So while your project is unlikely to be the size of Gmail, it could be quite close. So how do you architect and develop an application of that calibre in JavaScript? How do you enforce coding standards, test and document it? And of course how do you engineer that application in the super tight deadline all software development has?

Justin Meyer and Brian Moschel set out to create a solution to these problems in JavaScript development. That solution has become JavaScriptMVC. JavaScriptMVC is an open-source JavaScript framework (not library) which enforces strict application structure using the MVC design pattern and promotes best practices by supporting testing and documentation. JavaScriptMVC is based on the concept of convention over configuration providing utilities for many tedious tasks, greatly speeding up your development time.

This article is based on JavaScriptMVC 2.0 which has just been released into production. The new release of 2.0 has many new additions, but most importantly the underlying core of the framework has been changed to use jQuery. Prior to 2.0, JavaScriptMVC implemented all the framework’s components, and could be integrated with frameworks like jQuery for specific functionality like DOM queries and effects. A lot of time was being spent creating and maintaining components that already existed in jQuery and most JavaScriptMVC users used jQuery anyway. JavaScriptMVC now takes advantage of existing jQuery classes allowing the framework to focus on its goals of enforcing best practices, improving maintainability of your application, and reducing development time.

Basics

Take all your knowledge of traditional server side application development with an MVC framework and apply that to JavaScript. At first glance, this can be a bit hard to visualise. Most JavaScript on a web site comes in the form of hacky little scripts included here and there which manipulate the DOM in strange and inefficient ways, or add some kind of visual effect to the page, or perhaps is some Ajax talking to the server. This code is usually all over the place and can be hard to understand due to the lack of standardisation and naming conventions. While this might be the common scenario, it is not at all necessary. JavaScript is a full fledged scripting language and should be used as such in conjunction with all the traditional design patterns, standards and conventions used by other web scripting languages.

In MVC we start with the controller. Actions are dispatched to a specific controller and a specific action within that controller. In JavaScriptMVC, actions are events. Your controller represents a section of DOM and each method corresponds to an event taking place on a specific piece of that DOM. Once an event occurs, the controller will use a model to either save or retrieve some data based on that event. Models wrap and represent data. Once the model has dealt with the data, the controller will take that data and give it to the view, which contains all your HTML, and shows it to the user.

In JavaScriptMVC, everything is a plugin, including all the core components of the framework. This makes the framework highly extensible, but more important, very light weight. This way, you only include the components which you need to get the job done. You will never include code you do not use. This type of code inclusion/exclusion is handled by a plugin called include. It sits at the core of JavaScriptMVC handling code inclusion, compression, and setting the current environment.

Application Structure

JavaScriptMVC’s main purpose is to enforce good application structure. The layout of a JavaScriptMVC application is very similar to most other MVC frameworks with controllers, models, and views each in their own directory and a jmvc directory for the framework specific files. Here is the standard directory structure:

Command Line Interface with Rhino

JavaScriptMVC makes heavy use of a project called Rhino. Rhino is developed by Mozilla and is an implementation of JavaScript in Java. What this provides for JavaScriptMVC is an environment in which to run JavaScript which does not require a web browser. This means all of the generation scripts can be written in JavaScript but can be executed via command line. For more information about the Rhino project, visit http://www.mozilla.org/rhino/.

JavaScriptMVC comes with two command line utility scripts, one for Unix based operating systems and one for Windows operating systems. They are both located at the root directory of the JavaScriptMVC framework and should be executed on the command line relatively. To view the basic interface commands, use the -h option:

The command line utility has a wide range of uses. It can be used for generating code, updating the framework to the newest release, and compressing your application for release into production. The command line utility has a few other JavaScript related uses such as an interactive command line JavaScript environment for quickly writing and testing a piece of code and also a debugging environment as well. If you simply pass a file name to the utility, it will run the file which can be used to check for syntax errors or to test a singular functionality.

Generators

Generators show the face of JavaScriptMVC’s method of convention over configuration. This concept dictates that as a developer, when engineering an application, you’ll find that a lot of the data structures and application logic is the same between different applications. This means when writing code, you will write the same exact code over and over again. Clearly a waste of time. These reoccurrences are the conventions of most software applications. Once you get past the conventions, each application has a few parts that are configurations, as in specific to that application only, and you can implement those individually. Using a generator can save you a lot of time by setting up some basic application structures for you. Using generators is the recommended way to create and maintain your JavaScriptMVC application.

JavaScriptMVC has 9 generators: app, controller, engine, fixture, functional_test, model, page, scaffold, and unit_test. The app generator is the first generator you’ll use when beginning a project. It will create the following files:

This generator initialises a base project structure that is required of all JavaScriptMVC applications. The file init.js is the front controller of the application, setting configurations and loading plugins and dependencies. The file compress.js is used when compressing your application for production. Make sure to keep this around as you’ll need it! There are various tests created for you to fill in and run as you are developing your application. The HTML file created is a sample file which loads your application and should be used to test your application as you’re building it. This file is served to the users of your application.

The scaffolding generator is another extra special generator. Scaffolding is one of the most useful generators for really speeding up your development. Scaffolding an application is very commonly found in MVC based frameworks and is a method for generating models, views, controllers, and supporting files for a single database entity. The code generated will support creating, reading, updating, and deleting (CRUD) data associated with this entity. The scaffolding generator in JavaScriptMVC will create the following files for a given entity:

Once you have generated these files, all you have to do is fill in the attributes of your model and this entity becomes fully functional. Wow, that was easy!

Include

Include is a small package used to include the different JavaScript files for your application into your page. Because JavaScriptMVC is plugin based, you need to specifically load the components you will be using, including core framework elements. With include, you manage these file dependencies from within the application rather than the script tags in the HTML file. Include can be used conditionally from within your init.js, so it can include only the JavaScript which you need to run that page of the application. All inclusions are performed in a last-in-first-out order and all paths are relative to the current file running the inclusions (init.js).

Include handles managing the current runtime environment of your application. There are 3 environments available: development, test, production. In development mode, each JavaScript file is included individually, allowing you to view and debug the code in your browser or in a tool like Firebug. Test mode is used when running unit or functional tests. Production mode is used for running your application in production so a compressed version can be served to the client if its available.

When you are ready for production, include also handles concatenating and compressing your application. Documentation is also compiled and rendered during this step. You use include on the command line like so:

This command creates a file /apps/[app_name]/production.js which becomes the only file include will include when running in production mode.

Controllers

Once you have created a skeleton for your application with the generators and include, you will want it to actually do something. This is the job of a controller. Controllers are extremely flexible, can be extended, and have several ways of being implemented, depending on what your application needs.

JavaScriptMVC controllers are executed using event delegation. Event delegation binds the event to a parent element and delegates the event to the correct child when the event bubbles up. This reduces memory use and improves performance and also prevents you from having to re-bind events to new elements which are injected into the DOM while running your application.

Document Controllers

Document controllers are a traditional, page-like controller. The controller name and function names match the ID’s and class names of the DOM it interacts with. Take the following:

To build a controller for this HTML, you would first make a controller file called sampleController. The name of the controller must be the same as the ID of the parent element. Each event function references the class name of a child element which the events occur on and the name of the event. A document controller that works with the HTML above would look like this:

Stateful Controllers

Stateful controllers are quite different to document controllers. You can have multiple instances of a stateful controller allowing you to control several of the same objects on the page individually (think list items or widgets). By default, controllers are stateful as you are most likely to need the reusability they offer. Since there can be more than one instance on a given page, the events are not bound to a parent object with the same ID. Instead, you instantiate the controller when and where you need it, giving the controller the ID of the element to bind to upon instantiation. Stateful controllers become part of the jQuery object, so instantiating and accessing the controller become:

Models

A model in JavaScriptMVC, like in all applications, wrap data and data sources (web services). This makes hooking your JavaScriptMVC application up to your backend services API an absolute breeze. The models generator will get you started creating models. You can create generic models, which will be more or less empty, or you can create JSON REST models, which will have several CRUD related methods implemented which will talk to a JSON rest service. Just add a little configuration to a JSON REST model and its ready to be used. Models can tie in closely to the DOM of your application, again, based on naming conventions. This allows you the ability to have a model instance for every DOM element in a sequence. An example would be having a model instance for every list item in an unordered list.

NOTE: JavaScriptMVC more or less exclusively supports JSON REST services and has dropped support for XML web services. There are many reasons for this decision, all of which are beyond the scope of this article.

Views

Views are used in an MVC framework to separate all markup and styling from any other logic of your application. Since JavaScript is so closely tied to the DOM of a web page, a lot of application logic will involve manipulating the DOM. Usually this causes lots of little bits of HTML and CSS stuck everywhere in your JavaScript files cluttering up your project and negatively affecting its maintainability. And your poor design team. How can they ever find anything to make updates? Using a view solves this problem by putting all this in only one place. JavaScriptMVC views can be called from anywhere in a controller and have access to data you pass to it from the controller, making views totally dynamic.

Documentation

Documentation has never been easier than with JavaScriptMVC’s include.Doc. You write your documentation inline in each of your application’s files. During compression, the documentation is stripped out of each file and is generated into HTML files in your docs/ directory. include.Doc is not just for API documentation, but can be used to create a full web site with formatted text, inter-linking pages, and code samples.

Testing

JavaScriptMVC is set up to create completely test driven applications. There is a significant amount of functionality available in the testing suite. Both unit and functional tests are supported, and both are created by the generators. You can run your tests 3 different ways: in the browser, using Rhino, or using Selenium. Running tests in the browser will allow you to run both unit and functional tests (on that browser only) at the same time. You can use Rhino to run unit tests. Since Rhino is Mozilla based, the tests will be run in a simulated Firefox version 2 browser. Selenium can be integrated to run your functional tests in multiple browsers at the same time.

Conclusion

JavaScriptMVC is intended for complex JavaScript applications that require a full framework to provide strict structure and standards needed for large projects. The use of the Model View Controller design pattern has become a standard for engineering web applications as its structure caters to all the needs and problems a web application has. Coupling this design pattern with JavaScript makes for an extremely powerful solution to a long standing problem in JavaScript development. JavaScriptMVC is evidence of JavaScript being capable of everything any other web scripting language is capable of and shows JavaScript as a first class web programming language.

The future of web development is now. It’s full of advanced applications created with new and emerging technologies. Considering the potential these technologies have when put together begs the question if we put JavaScriptMVC on top of CouchDB, where does that leave PHP?

Visit the JavaScriptMVC web site for more information and to download the framework http://javascriptmvc.com