Categories
A piece of Art as big as India

Streamlining development of the project with Express, nodemon, Pug, Less, Gulp and Browsersync

In order to be able to develop efficiently, I’ve realised that I need a local web server running on my own computer, instead of having to constantly upload code to my GitHub Pages server.

As I’d already selected node.js as my backend, it made sense to use that on my local machine too. I found The Art of Node by Max Ogden a great introduction to what node.js is and what is it useful for, namely:

Node.js is an open source project designed to help you write JavaScript programs that talk to networks, file systems or other I/O (input/output, reading/writing) sources. That’s it! It is just a simple and stable I/O platform that you are encouraged to build modules on top of.

Quoting further:

Node isn’t either of the following:

  • A web framework (like Rails or Django, though it can be used to make such things)
  • A programming language (it uses JavaScript but node isn’t its own language)

Instead, node is somewhere in the middle. It is:

  • Designed to be simple and therefore relatively easy to understand and use
  • Useful for I/O based programs that need to be fast and/or handle lots of connections

This is exactly what I want to do – I need something simple that is going to be fast and handle lots of connections – potentially up to 300,000,000 at once!

I installed node.js on my laptop via Homebrew.

In order not to have to write HTML and CSS completely manually, I asked my friend Ross Cairns for some tips on what would be useful, and he gave me a rapid tutorial in the following platforms:

  • Express – a web framework for node that enables you to write web applications – which is what I’ll need to enable users to load my sculpture and alter it themselves within a mobile webpage.
  • nodemon – tool that reloads your node server automatically when it detects any changes in your code.
  • Pug – a templating engine for node that enables you to write HTML in a simpler way, without having to worry about closing tags and other complications. I also found a Pug template (formally known at Jade) that used A-Frame, which was very encouraging.
  • Less – a pre-processor for CSS that makes it much easier to use.
  • Gulp – a tool for automation that enables the automatic use of tools like Pug, Less and many others.
  • Browsersync – a tool that automatically reloads your web browser when it detects changes in your source code.

By default, Node.js also installs Node Package Manager (npm) which can be used to install further node programs.

I want to be able to install lots of node programs for this project, and doing it by hand can get unwieldy, so on Ross’s advice, I used the:

npm init

Command in order to create a package.json file in my project directory to list all the node programs I install, in order to make the project easier to manage and share in the future.

After that I installed nodemon and gulp-cli globally:

npm install nodemon --global
npm install gulp-cli --global

And then Express, Pug, Less, Gulp and BrowserSync locally:

npm install express --save
npm install gulp --save
npm install gulp-pug --save
npm install gulp-less --save
npm install browser-sync --save

Then I had to create the most simple Express app possible – a completely static one, by creating an “app.server.js” in the root of my project, with the following content:

// Modules
var express = require('express');

// Express
var app = express();

// our middleware
app.use(express.static('docs')); //Also GitHub Pages root, everything is going to be static to begin with

//Binding to a port...
app.listen(3000, function () {
 console.log('A piece of Art as big as India Express app listening on port 3000.');
});

I could then test the Express app by running the following command:

node app.server.js

and accessing http://localhost:3000 to test my new node server. Everything worked as if I was accessing the GitHub pages I had previously been working with.

In order to have something for Gulp to automate, I then created a .less file and .pug file in a newly created src folder (with less and pug folders within) that would duplicate the Pug template I had found earlier:

body {
   background: white;
}

style.less

doctype html
html
 head
 meta(charset='utf-8')
 title Hello, World! • A-Frame, made via Pug and Less and Gulp
 meta(name='description', content='Hello, World! • A-Frame')
 script(src='https://aframe.io/releases/0.3.2/aframe.min.js')
 link( href="style.css", rel="stylesheet", media="all")
 body
 a-scene
 a-box(position='-1 0.5 -3' rotation='0 45 0' color='#4CC3D9')
 a-sphere(position='0 1.25 -5' radius='1.25' color='#EF2D5E')
 a-cylinder(position='1 0.75 -3' radius='0.5' height='1.5' color='#FFC65D')
 a-plane(position='0 0 -4' rotation='-90 0 0' width='4' height='4' color='#7BC8A4')
 a-sky(color='#ECECEC')

aFrameBoilerPlateGeneratedViaLessAndPug.pug

Now that I had some files to generate from, I could create a gulpfile.js in the root of my project in order to automate the process.

// Modules
var gulp = require('gulp');
var pug = require('gulp-pug');
var less = require('gulp-less');
var browserSync = require('browser-sync').create();

// Tasks
gulp.task('default', ['pug', 'less']);

gulp.task('pug', function(){
 return gulp.src( './src/pug/**/*.pug')
 .pipe( pug( {pretty: true}))
 .pipe( gulp.dest('./docs/'));
});

gulp.task('less', function(){
 return gulp.src( './src/less/**/*.less')
 .pipe( less())
 .pipe( gulp.dest('./docs/'));
});

// Watching
gulp.task('watch', function(){
 browserSync.init({
 port: 4000, //where is browser sync
 proxy: 'http://localhost:3000/', //what are we proxying?
 ui: {port: 4001}, //where is the UI
 browser: [] //empty array of browsers
 });

gulp.watch('./src/pug/**/*.pug', [ 'pug'])
 .on('change', browserSync.reload);

gulp.watch('./src/less/**/*.less', [ 'less'])
 .on('change', browserSync.reload);
});

By running the following commands in two Terminal windows, I can write code locally and see the changes instantaneously in a browser running on my own computer.

nodemon app.server.js
gulp && gulp watch

I’ve pushed all these changes to my GitHub for the project, and you can see the generated html file here, it’s identical to the file I created manually before.