Nodejitsu

Save time managing and deploying your node.js app. Code faster with jitsu and npm

Scaffold your front-end development

About the author

Name
Location
Worldwide
nodejitsu nodejitsu

In February we released our business plans and pushed a new design for our homepage. Branding is important for startups, you should recognize our product on first glance: 'hey.. thats from Nodejitsu!' We already created a lot of small applications for multiple purposes (e.g. the status page and error tracker).

These applications should have consistent company branding. However, having all developers worry about front-end is not efficient. Keeping track of HTML, microformats and CSS developments is time consuming. To maximize front-end engineering efforts we created a set of standardized templates and assets. These can be used by our engineers to scaffold and create new applications with ease.

Scaffold is part of the application stack which manages our front-end deployment. The application is private, since sharing our brand assets would defeat the purpose of branding. However, Scaffold is making heavy use of the Square API. This post will share details of those patterns.

Scaffolding

Scaffold unifies our applications and lets developers focus on writing functionality and content. At its core Scaffold is a collection of HTML templates and JS/CSS assets, linked by configuration files.

In combination with Square and our CDN versions Scaffold greatly reduces front-end development. It will reduce time spent on default elements, like headers, footers, boxes, login, etc. Any set of these elements can be combined.

You could compare it to Twitter Bootstrap on steroids. Like Bootstrap, our CSS framework is also modularized and runs on small client-side JS applications. Also we have similar standards for typography, tables and forms.

Concept

At construction Scaffold reads and caches templates and exposes each as a callable function. If the environment is development, monitoring will be done by Square, which will build and compile assets. Scaffold as can be seen in the schema below.

Time for some code examples! Scaffold is agnostic about the application it is used from. It will run with Flatiron, Express, a plain HTTP server or any other javascript application. The Scaffold constructor only needs to know where your templates are for app.include to work properly. Optionally, locations to store the Square configuration and build files can be provided. The Square configuration of the application home.json will be merged with square.json.

var scaffold = new Scaffold(templates, {  
  store: assets + '/square.json',
  output: path.resolve(__dirname, '../public'),
  import: 'home.json'
}

Example: navigation pills

Currently, our homepage is using most of Scaffolds templates. On some pages we include pills, for instance see our npm product page. If app.pills uses assets (CSS and JS) that have not yet been included in the square.json an event will be emitted. The event will trigger Square to rebuild the compiled CSS and JS.
In turn Square.Watch.live will trigger a reload. So basically you're doing work in your IDE and have a live stream of your efforts.

Square can trigger on HTML file changes as well, so rebuilding would not interrupt the development process. Content changes will be visible immediately, whereas CSS and/or JS changes will follow shortly after. Note that the CSS is hot reloaded, e.g. no page refresh is required.

scaffold.app.pills({  
  navigation: [
    { name: 'Product', page: 'npm-product', swap: { show: '.npm-pricing', hide: '.npm-product' }},
    { name: 'Pricing', page: 'npm-pricing', swap: { show: '.npm-product', hide: '.npm-pricing' }}
  ],
  page: 'npm-product'
});

// Results in the following HTML
<nav class="pills">  
  <a href="#" id="npm-product" data-swap=".npm-pricing@.npm-product" class="active">
    Product
  </a>
  <a href="#" id="npm-pricing" data-swap=".npm-product@.npm-pricing">
    Pricing
  </a>
</nav>  

Infect JS loader template with hook

Our navigation pills can dynamically switch content using the data-swap attribute. For this to work a small client-side javascript snippet has to be initialized. The above app.pills call provides the key swap to both pills. This will trigger the hook to enqueue data for the loader template.

app.pills = {  
  ...
  hook: function infect(data) {
    // Only initialize pills if required.
    if ('swap' in data.navigation[0]) {
      this._queue.enlist('loader', { custom: [ 'pills' ] });
    }
  }
}

The app.loader will dynamically load any client-side javascript after page load of the browser. If both templates are included (responsibility of the developer), the hook of app.pills will infect app.loader to include pills in the data-apps attribute.

// Some content was removed for clarity, see our homepage source for the complete JS
<script id="loader" data-load="..." data-plain="..." data-apps="login,pills">  
  !function loader(l,o,a,d,e,r) {
    d = l.getElementsByTagName(o)[0];
    a = [];

    // Append extra files that need to be loaded
    e = l.getElementById('loader');
    a = a.concat(e.getAttribute('data-load').split(','), e.getAttribute('data-plain').split(','));
    e = r = a.length;
    while (r--) {
      ...
    }
  }(document, 'script');
</script>  

With just two simple function calls the developer will end up with dynamic, styled, functional navigation pills.

Work in progress

Our CDN versions still needs proper integration. Currently, we are working on getting automated version control implemented. The idea is to have nodejitsu-app provide an ID to versions and set proper origins automatically. Which would reduce asset management even further.

If you know other cool ways to utilize Square or have questions regarding specific details of Nodejitsu-app feel free to send me a tweet. Also improvements on this pattern or good ideas regarding front-end scaffolding are always welcome.

Who wrote this piece of ...?

I never got around to say hi! Better late than never. I'm Martijn Swaagman, a self-taught developer from the Netherlands. I hold a MSc. in human movement science. I've always used programming to express thoughts and ideas. I really like the diverse nature of different languages. About eight years ago I began with PHP and front-end technologies like CSS and JS. During my studies I used some C++ and Matlab to process data and results.

Not long after that I was introduced to Node.JS, I immediately fell in love. Using one language for both front-end and back-end work is awesome. The amount of powerful Node.JS modules is staggering. Best of all, being able to work for Nodejitsu allows me to contribute to open source modules and innovate, two things I love!

I passionately follow the quantified self movement as it's fueled by both programming and human movement science. It couldn't get any better! I would really like to empower the movement with Node.JS awesomeness.