Skip to content

Commit 033f902

Browse files
committed
Added Grunt.js example project
1 parent 6b52995 commit 033f902

File tree

17 files changed

+280
-0
lines changed

17 files changed

+280
-0
lines changed

04-express-grunt-watch/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
public/stylesheets/**

04-express-grunt-watch/Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM dockerfile/nodejs
2+
3+
RUN apt-get update -qq && apt-get install -y build-essential
4+
RUN apt-get install -y ruby
5+
RUN gem install sass
6+
7+
RUN mkdir /src
8+
9+
RUN npm install grunt-cli -g
10+
11+
WORKDIR /src
12+
ADD app/package.json /src/package.json
13+
RUN npm install
14+
15+
ADD app/Gruntfile.js /src/Gruntfile.js
16+
17+
EXPOSE 3000
18+
EXPOSE 35729
19+
20+
CMD ["npm", "start"]

04-express-grunt-watch/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Express app with Grunt.js build system
2+
3+
This app contains a [Grunt](http://gruntjs.com/) configuration which will
4+
5+
* Restart the app on **.js**, **.json** or **.hjs** file changes via [grunt-nodemon](https://github.com/ChrisWren/grunt-nodemon)
6+
* Automatically compile [SASS](http://sass-lang.com/) stylesheets to CSS via [grunt-contrib-watch](https://github.com/gruntjs/grunt-contrib-watch) and [grunt-contrib-sass](https://github.com/gruntjs/grunt-contrib-sass)
7+
* Manage the concurrent `nodemon` and `watch` tasks via [grunt-concurrent](https://github.com/sindresorhus/grunt-concurrent)
8+
9+
## Prerequisites
10+
11+
Install [Docker](https://www.docker.com/) on your system.
12+
13+
* [Install instructions](https://docs.docker.com/installation/mac/) for Mac OS X
14+
* [Install instructions](https://docs.docker.com/installation/ubuntulinux/) for Ubuntu Linux
15+
* [Install instructions](https://docs.docker.com/installation/) for other platforms
16+
17+
Install [Fig](http://fig.sh) on your system.
18+
19+
* Homebrew (OS X): `brew install fig`
20+
* Python/pip: `sudo pip install -U fig`
21+
* Other: ``curl -L https://github.com/docker/fig/releases/download/1.0.0/fig-`uname -s`-`uname -m` > /usr/local/bin/fig; chmod +x /usr/local/bin/fig``
22+
23+
## Setup
24+
25+
Run `fig build`. It will
26+
27+
* install [Ruby](https://www.ruby-lang.org) and [SASS](https://rubygems.org/gems/sass)
28+
* install the [Grunt](http://gruntjs.com) CLI globally
29+
* install all dependencies from the package.json locally
30+
* expose port 3000 to the host
31+
* instruct the container to execute `grunt` on start up.
32+
33+
## Start
34+
35+
Run `fig up` to create and start the container. The app should then be running on your docker daemon on port 3030 (On OS X you can use `boot2docker ip` to find out the IP address).
36+
37+
Go ahead and change any SASS stylesheet inside app/public/sass, and watch it autmatically compile to CSS.
38+
39+
## Notes for boot2docker
40+
41+
It [appears](https://github.com/boot2docker/boot2docker/issues/290) that boot2docker (OS X, Windows) currently does not automatically sync the system clock with the host system after a host resumes from sleep. This becomes a problem due to the way nodemon detects file changes. That might cause it to go bananas, if the clocks on both systems are "too much" out of sync. Until this is fixed, you might use [this workaround](https://github.com/boot2docker/boot2docker/issues/290#issuecomment-62384209) or simply do a manual sync via
42+
43+
```bash
44+
/usr/local/bin/boot2docker ssh sudo ntpclient -s -h pool.ntp.org
45+
```
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
module.exports = function(grunt) {
2+
3+
// Project configuration.
4+
grunt.initConfig({
5+
6+
pkg: grunt.file.readJSON('package.json'),
7+
8+
concurrent: {
9+
dev: {
10+
tasks : ['nodemon', 'watch'],
11+
options : {
12+
logConcurrentOutput: true
13+
}
14+
}
15+
},
16+
17+
nodemon: {
18+
dev: {
19+
script : 'app/bin/www',
20+
options : {
21+
args : ['dev'],
22+
nodeArgs : ['--debug'],
23+
ext : 'js hjs json',
24+
ignore : ['node_modules/**'],
25+
legacyWatch : true
26+
}
27+
}
28+
},
29+
30+
sass: {
31+
dist: {
32+
files: [
33+
{
34+
expand : true,
35+
cwd : 'app/public/scss',
36+
src : 'style.scss',
37+
dest : 'app/public/stylesheets',
38+
ext : '.css'
39+
}
40+
]
41+
}
42+
},
43+
44+
watch: {
45+
sass: {
46+
files : ['app/public/scss/**/*.scss'],
47+
tasks : ['sass'],
48+
options: {
49+
livereload: true
50+
}
51+
}
52+
}
53+
54+
});
55+
56+
// Load the plugin that provides the "uglify" task.
57+
grunt.loadNpmTasks('grunt-concurrent');
58+
grunt.loadNpmTasks('grunt-contrib-sass');
59+
grunt.loadNpmTasks('grunt-contrib-watch');
60+
grunt.loadNpmTasks('grunt-nodemon');
61+
//grunt.loadNpmTasks('grunt-simple-watch');
62+
63+
// Default task(s).
64+
grunt.registerTask('default', ['sass', 'concurrent']);
65+
66+
};

04-express-grunt-watch/app/app.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
var express = require('express');
2+
var path = require('path');
3+
var favicon = require('serve-favicon');
4+
var logger = require('morgan');
5+
var cookieParser = require('cookie-parser');
6+
var bodyParser = require('body-parser');
7+
8+
var routes = require('./routes/index');
9+
var users = require('./routes/users');
10+
11+
var app = express();
12+
13+
// view engine setup
14+
app.set('views', path.join(__dirname, 'views'));
15+
app.set('view engine', 'hjs');
16+
17+
// uncomment after placing your favicon in /public
18+
//app.use(favicon(__dirname + '/public/favicon.ico'));
19+
app.use(logger('dev'));
20+
app.use(bodyParser.json());
21+
app.use(bodyParser.urlencoded({ extended: false }));
22+
app.use(cookieParser());
23+
app.use(express.static(path.join(__dirname, 'public')));
24+
25+
app.use('/', routes);
26+
app.use('/users', users);
27+
28+
// catch 404 and forward to error handler
29+
app.use(function(req, res, next) {
30+
var err = new Error('Not Found');
31+
err.status = 404;
32+
next(err);
33+
});
34+
35+
// error handlers
36+
37+
// development error handler
38+
// will print stacktrace
39+
if (app.get('env') === 'development') {
40+
app.use(function(err, req, res, next) {
41+
res.status(err.status || 500);
42+
res.render('error', {
43+
message: err.message,
44+
error: err
45+
});
46+
});
47+
}
48+
49+
// production error handler
50+
// no stacktraces leaked to user
51+
app.use(function(err, req, res, next) {
52+
res.status(err.status || 500);
53+
res.render('error', {
54+
message: err.message,
55+
error: {}
56+
});
57+
});
58+
59+
60+
module.exports = app;

04-express-grunt-watch/app/bin/www

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env node
2+
var debug = require('debug')('app');
3+
var app = require('../app');
4+
5+
app.set('port', process.env.PORT || 3000);
6+
7+
var server = app.listen(app.get('port'), function() {
8+
debug('Express server listening on port ' + server.address().port);
9+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "app",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"start": "grunt"
7+
},
8+
"dependencies": {
9+
"express": "~4.9.0",
10+
"body-parser": "~1.8.1",
11+
"cookie-parser": "~1.3.3",
12+
"morgan": "~1.3.0",
13+
"serve-favicon": "~2.1.3",
14+
"debug": "~2.0.0",
15+
"hjs": "~0.0.6"
16+
},
17+
"devDependencies": {
18+
"grunt": "~0.4.5",
19+
"grunt-concurrent": "~1.0.0",
20+
"grunt-contrib-sass": "~0.8.1",
21+
"grunt-contrib-watch": "~0.6.1",
22+
"grunt-nodemon": "~0.3.0",
23+
"grunt-simple-watch": "~0.1.2"
24+
}
25+
}

04-express-grunt-watch/app/public/images/.gitkeep

Whitespace-only changes.

04-express-grunt-watch/app/public/javascripts/.gitkeep

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
$font-family: "Lucida Grande", Helvetica, Arial, sans-serif;
2+
$font-size: 14;
3+
4+
$padding: 50px;

0 commit comments

Comments
 (0)