top
Overview

Frontend Architecture

Every webdeveloper has to deal with two sides of a medallion. On one hand there is a programming language like PHP or Java. It is object-oriented, provides build and deployment tools, has coding styles, test-driven or agile approaches. And on the other hand there are HTML, CSS and Javascript. Wich have nothing but lots of spaghetti code. HTML and CSS are not even programming languages at all.


Introduction

Introduction

A software developer usually strives to follow design patterns, software development processes and paradigms like Clean Code for example. Why, because it helps to create reuseable, maintainable and testable source code. Having a big pool of reuseable code translates directly into small development periods, because you dont have to start at ground zero on every project. Having your code maintainable translates into continuous development, which adds two additional factors. It prevents the procrastination of bugs on further development and it prevents the general overhaul (relauch) because you can add and modify small pieces of your software continuously. And finally having testable code helps to ensure quality and stability of your software.

With a programming language there are lots of tools, frameworks, integrated development environments (IDE) that help a developer to use design patterns and follow the processes and principles of software development. But as a web-developer there is the frontend with HTML, CSS and Javascript. CSS and Javascript both share a common flaw, they litter the global scope. Object-orientation, software development methods and paradigms usually provide a structure that prevents that in a backend programming language. But such things do not exist in CSS and Javascript and therefore a lot of people dont even call them “programming language”.

As a logical consequence, this part of a web project is often aligned closer to the design department than to the software development department. But that amplifies the problem even more, as then designers are forced to produce quality source code, instead of software developers. The goal of having reuseable, maintainable and testable source code becomes even more distant.


OOCSS and Less

OOCSS and Less

After struggeling in projects for many years, i stumbled across OOCSS. It has kind of opened my eyes, as it solves some key problem with CSS. Two simple principles are the foundation of OOCSS, “the separation of structure and skin” and “the separation of container and content”. This creates encapsulated modules that can be resused on a page or across multiple projects. Dependencies and side effects are also minimized, making the result of a change to your CSS code 100% predictable.

With OOCSS three layers of definitions are created. The first layer contains global definitions like fonts, colors etc. The second layer holds the grid, responsible for positioning and page layout and the third layer defines all the modules and skins (variations of modules).

A simple HTML example may look like this


<div class="mod modExample">
  <div class="inner">
    <!-- module content -->
    <h3>Headline</h3>
    <p>
      Lorem ipsum dolor sit amet,
      consetetur sadipscing elitr, sed
    </p>
    <a href="#">read more</a>
  </div>
</div>

With the classes “mod” you declare the outer DIV container as boundary of the module. The “inner” container is important, because it defines “position: relative;”, which enables absolute positioning within a module.

Less

OOCSS is a good start, but still some problems remain. To support OOCSS i use Less. The main advantage in the combination of the two is, that with Less global styles can be defined as variables and multiple Less files can be compiled to one CSS file. So having multiple developers and a version controll system (vcs) like git for example works fine. In addition, the Less file of a module can be copied from one project to another easily.

Including Bootstrap or Font Awesome is easy, both are available as Less wich fits nicely into this structure. Just add a library folder, place the Less files provided by Bootstrap or Fontawesome there and include them to have them compiled into the app.css.

folder structure for less files

global.less:


@import "library/bootstrap/bootstrap.less";
@import "library/font-awesome/font-awesome.less";

Example.less:


.modExample {
    // modules css
    a {
        display: block;
   text-align: right;
    }
}

.modExample.skinRed {
    .inner {
        background-color: red;
    }
    h3 {
    color: black;
    }
}

.modExample.skinBlue {
    .inner {
        background-color: blue;
    }
    h3 {
    color: white;
    }
}

Scaleable Javascript Application Architecture

Scaleable Javascript Application Architecture

With OOCSS and Less we have a good base to start getting software development to the frontend. But Javascript is important, too and has similar problems. Scaleable Javascript Application Architecture is the OOCSS counterpart i prefer. It defines a modular structure that encapsulates the modules and avoids the littering of the global scope. It also creates layers, the application layer on a global level, the sandbox layer for connecting modules and underneath, all the modules of the application.

A structure similar to the Less files is reasonable. The library folder holds the Javascript framework and plugins that are used by the application.

AMD and require.js

To produce modular Javascript code for the browser AMD is recomended and i prefer the requre.js implementation.

folder structure for less files

Gulp

Gulp is a tool based on Node.js and provides plugins for dealing with common development and deployment tasks. First of all they can be used to merge multiple Javascript files into one. Validation (jslint), minification (jsmin) and compilation of less files are other tasks that fit nicely into our development system.

A simple gulpfile I use may look like this


var gulp = require('gulp'),
        jshint = require('gulp-jshint'),
        uglify = require('gulp-uglify'),
        concat = require('gulp-concat'),
        less = require('gulp-less'),
        path = require('path'),
        minifyCSS = require('gulp-minify-css')

// default gulp task
gulp.task('default', ['js', 'minify-css'], function() {
});
gulp.task('js', ['mergejsfiles'], function() {
    return gulp.src([
        './resources/js/application.js',
        './resources/js/modules/*.js',
        './resources/js/plugins/*.js'
    ])
            .pipe(uglify())
            .pipe(concat('app-min.js'))
            .pipe(gulp.dest('./resources/js/'));
});
gulp.task('mergejsfiles', function() {
    return gulp.src([
        './resources/js/application.js',
        './resources/js/modules/*.js',
        './resources/js/plugins/*.js'
    ])
            .pipe(jshint())
            .pipe(jshint.reporter('default'))
            .pipe(concat('app.js'))
            .pipe(gulp.dest('./resources/js/'));
});
gulp.task('less', function() {
    return gulp.src('resources/less/app.less')
            .pipe(less({
                paths: [path.join(__dirname, 'less', 'includes')]
            }))
            .pipe(gulp.dest('./resources/css/'));
});
gulp.task('minify-css', ['less'], function() {
    return gulp.src('resources/css/app.css')
            .pipe(minifyCSS({
keepBreaks: false,
keepSpecialComments: 0
  }))
            .pipe(concat('app-min.css'))
            .pipe(gulp.dest('./resources/css/'));
});

It creates a single Javascript file and a single CSS file for the project that contains all modules for inclusion in the HTML pages. But also testing and code-coverage is available for larger projects via Karma, Istanbul and Jasmine. See my GitRepository for an example project putting all this together.


Merging Frontend and Backend

Merging Frontend and Backend

From a developers point of view, this all makes sense. One CSS file and one Javascript file per module, the sandbox and grid seperating the modules from the global scope. Supported by Less, requirejs and build tools like gulp to get a really nice development environment and a build process that merges all the files and builds one CSS and one Javascript file for deployment to production. Testing and code coverage bring it down to a round fingure and ensure stability and quality.

Even the utilization of continuous integration is possible. And the integration in a web application, a content management system (CMS) or an online shop system is just the next step. A layer structure and the concept of reuseable components is deep-seated for PHP development and web applications. For example Zend Framework uses ViewScripts to render pages. Instead of generating all HTML there, you just provide the page structure (grid) in the ViewScript and for each module you use a ViewHelper to get a reuseable component backend to frontend. And as the frontend tests rely on a fixture file that holds the HTML structure for the module to test, it is quite easy to write a test with PHPUnit that ensures that the HTML produced by the ViewHelper matches this structure. Providing test coverage even for the gap between frontend and backend development.

Testing

With the addition of a continous integration tool like Jenkins or Hudson and the abillity to automate tests for the frontend, even more testing is possible. Running selenium-tests that cover integration and regression tests, Karma for low level unit and component tests on the frontend and PHPUnit on the backend the test coverage is almost 100% complete and via continuous integration and its self testing features, running the tests happens automatically. Code metrics and their compliance for both, Javascript and PHP code, provide sufficient controll to run large scale projects with lots of developers participating.

Final Thoughts

Final Thoughts

On the long way from a conceptual design to the release of a web application the earlier the modular concept is installed the better. And even on a design level you can work modular. See my article on Modular Design for more detailed thoughts on this topic.

 DesignCSSJavascriptHTMLPHP
ModuleModulemodule.lessModule.js<div class="mod">ViewHelper
StructurePage LayoutGridSandbox.js ViewScript
GlobalStyleguideglobal.lessApplication.js Zend Framework

“OOCSS” and “Scaleable Javascript Application Architecture” both add structure, already known from software development with Java or PHP, to the frontend. In conjunction with Less, requirejs and gulp we get a development environment that fits nicely into the development process. Testing capabilities via Karma and Jasmine provide base to guarantee quality and stability for the frontend code.
In addition, we get modular code that is reuseable, maintainable and testable, can easily be shared between projects, works well with a VCS and in small to large development teams. And finaly using continous integration helps us to achieve sustainable code quality frontend to backend