Hello developers, before we start integration of all our components, let’s have a quick review of the below things.
Node.js
Node.js is a server side javascript-based platform. Like other server side platforms ( eg: Rails, Python, PHP… ), this javascript based platform is built on Google Chrome V8 Javascript Engine. Node.js uses an event-driven architecture & asynchronous or non-blocking I/O model, which improves efficiency and scalability for real-time applications.Express
Express is a web application server framework for Node.js. Express provide a robust set of features for building single, multi-page and hybrid web applications. Express allows us to set up middlewares to respond to client HTTP requests. It also provides URL routing which allows to perform different actions and render dynamic HTML pages using any of the template engines like jade, EJS, nunjucks …Nunjucks
Nunjucks is a rich & powerful templating engine for javascript. It takes inspiration from jinja2 templating system. Using nunjucks we can inherit templates and make it possible to use the same or a similar layout for all templates.Gulp
Gulp automates and enhances your application workflow. It is a task runner which uses node.js. Gulp keeps things simple and makes complex tasks manageable using node modules.Nodemon
After any changes in your node.js application files, your changes will not reflect immediately. To reflect changes you will have to manually restart node.js server each time in a development environment. Nodemon helps us to avoid such manual restarts. It monitors all changes in your node.js application and automatically restarts the server for a development environment. Nodemon will watch the files in the directory in which nodemon was started, and if any files change, it will automatically restart your node application. So we are now clear about all the things. Let’s install the required dependencies using the following commands. Install Node & npm from nodejs.org. or you can directly install it using brew
1
2 |
$ brew install node.js $ node -v |
1
2
3
4
5
6 |
$ sudo npm install npm -g $ npm -v $ npm install express --save $ npm install -g gulp $ npm install nunjucks $ npm install -g nodemon |
1 |
$ mkdir myapp && cd myapp |
1 |
$ npm init |
{ | |
“name“: “myapp“, | |
“private“: true, | |
“version“: “1.0.0“, | |
“description“: “example.com“, | |
“main“: “app.js“, | |
“scripts“: { | |
“test“: “echo \”Error: no test specified\” && exit 1“, | |
“start“: “echo \”Starting server\” && NODE_ENV=production gulp“ | |
}, | |
“author“: “author@example.com“, | |
“license“: “ISC“, | |
“devDependencies“: { | |
“body-parser“: “~1.13.2“, | |
“cookie-parser“: “~1.3.5“, | |
“debug“: “~2.2.0“, | |
“del“: “^0.1.2“, | |
“express“: “^4.13.3“, | |
“gulp“: “^3.9.0“, | |
“gulp-changed“: “^1.3.0“, | |
“gulp-concat“: “^2.6.0“, | |
“gulp-imagemin“: “^2.4.0“, | |
“gulp-jshint“: “^2.0.0“, | |
“gulp-livereload“: “^3.8.1“, | |
“gulp-minify-css“: “^1.2.3“, | |
“gulp-minify-html“: “^1.0.5“, | |
“gulp-nodemon“: “^2.0.6“, | |
“gulp-notify“: “^2.2.0“, | |
“gulp-plumber“: “^1.0.1“, | |
“gulp-rev“: “^6.0.1“, | |
“gulp-sass“: “^2.1.1“, | |
“gulp-uglify“: “^1.5.1“, | |
“gulp-util“: “^3.0.7“, | |
“jshint“: “^2.8.0“, | |
“morgan“: “~1.6.1“, | |
“node-neat“: “^1.7.2“, | |
“nunjucks“: “^2.2.0“, | |
“shipit-cli“: “^1.4.1“, | |
“shipit-deploy“: “^2.1.2“ | |
}, | |
“dependencies“: { | |
“gulp-rev-collector“: “^1.0.2“ | |
} | |
} |
1 |
$ npm install |
var express = require(‘express‘), | |
nunjucks = require(‘nunjucks‘), | |
path = require(‘path‘), | |
app = express(), | |
logger = require(‘morgan‘), | |
cookieParser = require(‘cookie-parser‘), | |
bodyParser = require(‘body-parser‘); | |
app.set(‘assets_path‘, (process.env.NODE_ENV === ‘production‘) ? ‘dist‘ : ‘build‘); | |
app.set(‘views‘, path.join(__dirname, app.get(‘assets_path‘) + ‘/views‘)); | |
app.use(logger(‘dev‘)); | |
app.use(bodyParser.json()); | |
app.use(bodyParser.urlencoded({ extended: false })); | |
app.use(cookieParser()); | |
app.use(express.static(path.join(__dirname, app.get(‘assets_path‘)))); | |
var routes = require(‘./routes/index‘), | |
api_routes = require(‘./routes/api‘); | |
app.set(‘port‘, process.env.PORT || 8000); | |
// Setup nunjucks templating engine | |
nunjucks.configure(app.get(‘views‘), { | |
autoescape: true, | |
noCache: true, | |
watch: true, | |
express: app | |
}); | |
// serve index and view partials | |
app.use(‘/‘, routes); | |
app.use(‘/api/‘, api_routes); | |
// catch 404 and forward to error handler | |
app.use(function(req, res, next) { | |
var err = new Error(‘Not Found‘); | |
err.status = 404; | |
next(err); | |
}); | |
// no stacktraces leaked to user | |
app.use(function(err, req, res, next) { | |
res.status(err.status || 500); | |
res.render(‘404.html‘); | |
}); | |
// Kick start our server | |
app.listen(app.get(‘port‘), function() { | |
console.log(‘Server started on port‘, app.get(‘port‘)); | |
}); | |
module.exports = app; |
1
2
3
4
5
6
7 |
var nunjucks = require( 'nunjucks' ); nunjucks.configure(app.get( 'views' ), { autoescape: true , noCache: true , watch: true , express: app }); |
<html> | |
<head> | |
<title> | |
{% block title %}{{ page.title if page.title}} {% endblock %} | |
</title> | |
<meta name=“viewport“ content=“width=device-width, initial-scale=1“/> | |
<link rel=“shortcut icon“ type=“image/ico“ href=“favicon.ico“ /> | |
<link href=“/css/style.css“ rel=“stylesheet“> | |
{% block styles %}{% endblock %} | |
</head> | |
<body class=“main-wrap“> | |
{% include “../includes/header.html” %} | |
<div class=“content-wrap“> | |
{% block content %} | |
{% endblock %} | |
</div> | |
{% include “../includes/footer.html” %} | |
<script src=“/js/vendor.js“></script> | |
<script src=“/js/main.js“></script> | |
{% block extra_js %}{% endblock %} | |
</body> | |
</html> |
{% extends “./layouts/default.html” %} | |
{% block content %} | |
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. | |
{% endblock %} |
‘use strict‘; | |
// Dependencies | |
var gulp = require(‘gulp‘), | |
nodemon = require(‘gulp-nodemon‘), | |
notify = require(‘gulp-notify‘), | |
livereload = require(‘gulp-livereload‘), | |
changed = require(‘gulp-changed‘), | |
del = require(‘del‘), | |
gutil = require(‘gulp-util‘), | |
concat = require(‘gulp-concat‘), | |
plumber = require(‘gulp-plumber‘), | |
imagemin = require(‘gulp-imagemin‘), | |
minifyCSS = require(‘gulp-minify-css‘), | |
minifyHtml = require(‘gulp-minify-html‘), | |
rev = require(‘gulp-rev‘), | |
jshint = require(‘gulp-jshint‘), | |
imagemin = require(‘gulp-imagemin‘), | |
revCollector = require(‘gulp-rev-collector‘), | |
uglify = require(‘gulp-uglify‘), | |
sass = require(‘gulp-sass‘); | |
var paths = { | |
fontsSrc: ‘src/fonts/‘, | |
htmlSrc: ‘src/views/‘, | |
sassSrc: ‘src/sass/‘, | |
jsSrc: ‘src/js/‘, | |
imgSrc: ‘src/images/‘, | |
buildDir: ‘build/‘, | |
revDir: ‘build/rev/‘, | |
distDir: ‘dist/‘ | |
}; | |
var onError = function (err) { | |
gutil.beep(); | |
gutil.log(gutil.colors.green(err)); | |
}, | |
nodemonServerInit = function(){ | |
livereload.listen(); | |
nodemon({ | |
script: ‘app.js‘, | |
ext: ‘js‘ | |
}).on(‘restart‘, function(){ | |
gulp.src(‘app.js‘) | |
.pipe(livereload()) | |
.pipe(notify(‘Reloading page, please wait…‘)); | |
}) | |
}; | |
if(process.env.NODE_ENV === ‘prod‘){ | |
gulp.task(‘default‘, [‘dist‘]); | |
}else { | |
gulp.task(‘default‘, [‘build‘, ‘watch‘]); | |
} | |
gulp.task(‘clean‘, function(cb) { | |
del([paths.buildDir, paths.distDir], cb); | |
}); | |
gulp.task(‘build‘, [‘build-html‘, ‘build-css‘, ‘build-js‘, ‘build-images‘, ‘build-favicon‘, ‘build-fonts‘], function (cb) { | |
nodemonServerInit(); | |
}); | |
gulp.task(‘dist‘, [‘dist-html‘, ‘dist-js‘, ‘dist-css‘, ‘dist-images‘, ‘dist-favicon‘, ‘dist-fonts‘], function (cb) { | |
nodemonServerInit(); | |
}); | |
/* | |
HTML Tasks | |
*/ | |
gulp.task(‘build-html‘, function() { | |
return gulp.src(paths.htmlSrc + ‘**/*.html‘) | |
.pipe(gulp.dest(paths.buildDir + ‘views/‘)) | |
.pipe(livereload()); | |
}); | |
gulp.task(‘dist-html‘, [‘build-html‘, ‘dist-js‘, ‘dist-css‘, ‘dist-images‘], function() { | |
return gulp.src([ | |
paths.revDir + “**/*.json“, | |
paths.buildDir + ‘views/‘ + “**/*.html“ | |
]) | |
.pipe(revCollector()) | |
.pipe(minifyHtml({ | |
conditionals: true, | |
quotes: true | |
})) | |
.pipe(gulp.dest(paths.distDir + ‘views‘)); | |
}); | |
/* | |
CSS tasks | |
*/ | |
gulp.task(‘build-css‘, [‘sass‘]); | |
gulp.task(‘sass‘, function () { | |
return gulp.src(paths.sassSrc + ‘**/*.scss‘) | |
.pipe(sass({ | |
includePaths: require(‘node-neat‘).includePaths, | |
style: ‘nested‘, | |
onError: function(){ | |
console.log(“Error in scss“); | |
} | |
})) | |
.pipe(plumber({ errorHandler: onError })) | |
.pipe(gulp.dest(paths.buildDir + ‘css/‘)) | |
.pipe(livereload()); | |
}); | |
gulp.task(‘dist-css‘, [‘build-css‘, ‘dist-images‘], function() { | |
return gulp.src([ | |
paths.buildDir + ‘css/*‘, | |
paths.revDir + “images/*.json“ | |
]) | |
.pipe(revCollector()) | |
.pipe(minifyCSS()) | |
.pipe(rev()) | |
.pipe(gulp.dest(paths.distDir + ‘css‘)) | |
.pipe(rev.manifest()) | |
.pipe(gulp.dest(paths.revDir + ‘css‘)); | |
}); | |
gulp.task(‘build-fonts‘, [], function() { | |
return gulp.src(paths.fontsSrc + ‘**/*.*‘) | |
.pipe(gulp.dest(paths.buildDir + ‘fonts/‘)) | |
.pipe(livereload()); | |
}); | |
gulp.task(‘dist-fonts‘, [‘build-fonts‘], function() { | |
return gulp.src(‘build/fonts/*‘) | |
.pipe(gulp.dest(paths.distDir + “/fonts/“)); | |
}); | |
/* | |
JS Tasks | |
*/ | |
gulp.task(‘build-js‘, [‘js‘, ‘js-plugins‘]); | |
gulp.task(‘js‘, function() { | |
return gulp.src(paths.jsSrc + ‘*.js‘) | |
.pipe(plumber({ errorHandler: onError })) | |
.pipe(changed(paths.buildDir + ‘js‘)) | |
.pipe(jshint()) | |
.pipe(jshint.reporter(‘default‘)) | |
.pipe(gulp.dest(paths.buildDir + ‘js‘)) | |
.pipe(livereload()); | |
}); | |
gulp.task(‘js-plugins‘, [], function() { | |
return gulp.src([ | |
‘src/lib/*.js‘ | |
]) | |
.pipe(concat(‘vendor.js‘)) | |
.pipe(gulp.dest(paths.buildDir + ‘js/‘)) | |
.pipe(livereload()); | |
}); | |
gulp.task(‘dist-js‘, [‘build-js‘], function() { | |
return gulp.src(paths.buildDir + ‘js/*‘) | |
.pipe(uglify()) | |
.pipe(rev()) | |
.pipe(gulp.dest(paths.distDir + ‘js‘)) | |
.pipe(rev.manifest()) | |
.pipe(gulp.dest(paths.revDir + ‘js‘)); | |
}); | |
/* | |
Image Tasks | |
*/ | |
gulp.task(‘build-images‘, function() { | |
return gulp.src(paths.imgSrc + ‘**/*.+(png|jpeg|jpg|gif|svg|eps)‘) | |
.pipe(changed(paths.buildDir + ‘images‘)) | |
.pipe(gulp.dest(paths.buildDir + ‘images‘)) | |
.pipe(livereload()); | |
}); | |
gulp.task(‘dist-images‘, [‘build-images‘], function() { | |
return gulp.src(paths.buildDir + ‘images/**/*‘) | |
.pipe(imagemin({ | |
progressive: true | |
})) | |
.pipe(rev()) | |
.pipe(gulp.dest(paths.distDir + ‘images‘)) | |
.pipe(rev.manifest()) | |
.pipe(gulp.dest(paths.revDir + ‘images‘)); | |
}); | |
gulp.task(‘build-favicon‘, function() { | |
return gulp.src(‘src/favicon.ico‘) | |
.pipe(changed(paths.buildDir)) | |
.pipe(gulp.dest(paths.buildDir)) | |
.pipe(livereload()); | |
}); | |
gulp.task(‘dist-favicon‘, [‘build-favicon‘], function() { | |
return gulp.src(paths.buildDir + ‘favicon.ico‘) | |
.pipe(changed(paths.distDir)) | |
.pipe(gulp.dest(paths.distDir)); | |
}); | |
gulp.task(‘watch‘, function () { | |
gulp.watch([‘src/views/**/*.html‘], [‘build-html‘]); | |
gulp.watch(‘src/sass/**‘, [‘sass‘]); | |
gulp.watch(paths.jsSrc + ‘**/*.js‘, [‘js‘]); | |
gulp.watch(‘src/lib/**‘ + ‘**/*.js‘, [‘js-plugins‘]); | |
gulp.watch(paths.imgSrc + ‘**/*.+(png|jpeg|jpg|gif|svg)‘, [‘build-images‘]); | |
}); |
1
2
3
4
5
6
7
8
9
10
11 |
nodemonServerInit = function (){ livereload.listen(); nodemon({ script: 'app.js' , ext: 'js' }).on( 'restart' , function (){ gulp.src( 'app.js' ) .pipe(livereload()) .pipe(notify( 'Reloading page, please wait...' )); }) } |

1 |
$ gulp |
1 |
$ npm start |