diff --git a/.gitignore b/.gitignore
index 85eda7e..6fe25bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
node_modules
bower_components
-tmp
+.tmp
.vagrant
results/*
coverage
diff --git a/Gruntfile.js b/Gruntfile.js
index 9fd6597..9bcaea3 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,5 +1,8 @@
module.exports = function(grunt) {
+ // Load all grunt modules
+ require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
+
// Tell our Express server that Grunt launched it
process.env.GRUNTED = true;
@@ -18,7 +21,7 @@ module.exports = function(grunt) {
cssRouter: function (fontpath) {
var pathArray = fontpath.split('/');
var fileName = pathArray[pathArray.length - 1];
- return '/front/fonts/' + fileName;
+ return '/fonts/' + fileName;
}
}
},
@@ -69,19 +72,22 @@ module.exports = function(grunt) {
},
clean: {
tmp: {
- src: ['tmp']
+ src: ['.tmp']
},
dev: {
src: ['front/src/css']
},
coverage: {
- src: ['tmp', 'coverage/']
+ src: ['.tmp', 'coverage/']
+ },
+ build: {
+ src: ['front/build']
}
},
copy: {
beforeCoverage: {
files: [
- {src: ['bin/server.js'], dest: 'tmp/'}
+ {src: ['bin/server.js'], dest: '.tmp/'}
]
},
coverage: {
@@ -89,12 +95,18 @@ module.exports = function(grunt) {
{src: ['test/**'], dest: 'coverage/'},
{src: ['lib/metadata/**'], dest: 'coverage/'}
]
+ },
+ build: {
+ files: [
+ {src: ['./front/src/fonts/icons.woff'], dest: './front/build/fonts/icons.woff'},
+ {src: ['./front/src/img/favicon.png'], dest: './front/build/img/favicon.png'},
+ ]
}
},
lineremover: {
beforeCoverage: {
files: {
- 'tmp/bin/cli.js': 'bin/cli.js'
+ '.tmp/bin/cli.js': 'bin/cli.js'
},
options: {
exclusionPattern: /#!\/usr\/bin\/env node/
@@ -111,7 +123,7 @@ module.exports = function(grunt) {
dest: 'coverage/lib/'
},
coverageBin: {
- src: ['tmp/bin/'],
+ src: ['.tmp/bin/'],
dest: 'coverage/bin/'
}
},
@@ -137,6 +149,14 @@ module.exports = function(grunt) {
src: ['coverage/test/core/*.js', 'coverage/test/api/*.js']
}
},
+ env: {
+ dev: {
+ NODE_ENV: 'development'
+ },
+ builded: {
+ NODE_ENV: 'production'
+ }
+ },
express: {
dev: {
options: {
@@ -146,6 +166,14 @@ module.exports = function(grunt) {
showStack: true
}
},
+ builded: {
+ options: {
+ port: 8383,
+ server: './bin/server.js',
+ serverreload: true,
+ showStack: true
+ }
+ },
test: {
options: {
port: 8387,
@@ -159,6 +187,67 @@ module.exports = function(grunt) {
bases: 'test/www'
}
}
+ },
+ useminPrepare: {
+ html: './front/src/main.html',
+ options: {
+ dest: './front/build',
+ root: ['./', './front/src']
+ }
+ },
+ usemin: {
+ html: './front/build/main.html',
+ css: './front/build/css/*.css',
+ options: {
+ assetsDirs: ['front/build'],
+ patterns: {
+ css: [[/(\/fonts\/icons\.woff)/gm, 'Replacing reference to icons.woff']]
+ }
+ }
+ },
+ htmlmin: {
+ options: {
+ removeComments: true,
+ collapseWhitespace: true
+ },
+ main: {
+ files: [{
+ expand: true,
+ cwd: './front/build/',
+ src: 'main.html',
+ flatten: true,
+ dest: './front/build'
+ }]
+ },
+ views: {
+ files: [{
+ expand: true,
+ cwd: './front/src/views',
+ src: '*.html',
+ flatten: true,
+ dest: '.tmp/views/'
+ }]
+ }
+ },
+ inline_angular_templates: {
+ build: {
+ options: {
+ base: '.tmp',
+ method: 'append'
+ },
+ files: {
+ './front/build/main.html': ['.tmp/views/*.html']
+ }
+ }
+ },
+ filerev: {
+ options: {
+ algorithm: 'md5',
+ length: 8
+ },
+ assets: {
+ src: './front/build/*/*.*'
+ }
}
});
@@ -191,10 +280,6 @@ module.exports = function(grunt) {
});
-
-
- require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
-
grunt.registerTask('icons', [
'font:icons',
'less',
@@ -202,8 +287,20 @@ module.exports = function(grunt) {
]);
grunt.registerTask('build', [
+ 'clean:build',
+ 'copy:build',
'less',
- 'replace'
+ 'useminPrepare',
+ 'concat',
+ 'uglify',
+ 'cssmin',
+ 'replace',
+ 'htmlmin:views',
+ 'inline_angular_templates',
+ 'filerev',
+ 'usemin',
+ 'htmlmin:main',
+ 'clean:tmp'
]);
grunt.registerTask('hint', [
@@ -211,9 +308,15 @@ module.exports = function(grunt) {
]);
grunt.registerTask('dev', [
+ 'env:dev',
'express:dev'
]);
+ grunt.registerTask('builded', [
+ 'env:builded',
+ 'express:builded'
+ ]);
+
grunt.registerTask('test', [
'build',
'jshint',
diff --git a/front/src/css/icons.css b/front/src/css/icons.css
index 6ebf26b..ac51e0c 100644
--- a/front/src/css/icons.css
+++ b/front/src/css/icons.css
@@ -1,6 +1,6 @@
@font-face {
font-family: "fontsmith-icons";
- src: url("/front/fonts/icons.woff") format("woff");
+ src: url("/fonts/icons.woff") format("woff");
font-weight: normal;
font-style: normal;
}
diff --git a/front/src/css/main.css b/front/src/css/main.css
index 9ff35ad..8cab1bf 100644
--- a/front/src/css/main.css
+++ b/front/src/css/main.css
@@ -1,6 +1,6 @@
@font-face {
font-family: "fontsmith-icons";
- src: url("/front/fonts/icons.woff") format("woff");
+ src: url("/fonts/icons.woff") format("woff");
font-weight: normal;
font-style: normal;
}
diff --git a/front/src/fonts/icons.woff b/front/src/fonts/icons.woff
index 196e556..9611c2f 100644
Binary files a/front/src/fonts/icons.woff and b/front/src/fonts/icons.woff differ
diff --git a/front/src/js/app.js b/front/src/js/app.js
index 445c20c..a7f73d3 100644
--- a/front/src/js/app.js
+++ b/front/src/js/app.js
@@ -25,27 +25,27 @@ yltApp.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
- templateUrl: 'front/views/index.html',
+ templateUrl: 'views/index.html',
controller: 'IndexCtrl'
}).
when('/queue/:runId', {
- templateUrl: 'front/views/queue.html',
+ templateUrl: 'views/queue.html',
controller: 'QueueCtrl'
}).
when('/about', {
- templateUrl: 'front/views/about.html',
+ templateUrl: 'views/about.html',
controller: 'AboutCtrl'
}).
when('/result/:runId', {
- templateUrl: 'front/views/dashboard.html',
+ templateUrl: 'views/dashboard.html',
controller: 'DashboardCtrl'
}).
when('/result/:runId/timeline', {
- templateUrl: 'front/views/timeline.html',
+ templateUrl: 'views/timeline.html',
controller: 'TimelineCtrl'
}).
when('/result/:runId/rule/:policy', {
- templateUrl: 'front/views/rule.html',
+ templateUrl: 'views/rule.html',
controller: 'RuleCtrl'
}).
otherwise({
diff --git a/front/src/js/directives/gradeDirective.js b/front/src/js/directives/gradeDirective.js
index 7691c93..99cad49 100644
--- a/front/src/js/directives/gradeDirective.js
+++ b/front/src/js/directives/gradeDirective.js
@@ -9,7 +9,7 @@ gradeDirective.directive('grade', function() {
},
template: '
{{getGrade(score)}}
',
replace: true,
- controller : function($scope) {
+ controller : ['$scope', function($scope) {
$scope.getGrade = function(score) {
if (score > 80) {
return 'A';
@@ -28,6 +28,6 @@ gradeDirective.directive('grade', function() {
}
return 'F';
};
- }
+ }]
};
});
\ No newline at end of file
diff --git a/front/src/less/icons.less b/front/src/less/icons.less
index f02dcbc..7603317 100644
--- a/front/src/less/icons.less
+++ b/front/src/less/icons.less
@@ -1,24 +1,24 @@
-@lab-font-family: "fontsmith-icons";
-@lab-value: "\e004";
-@lab: '"fontsmith-icons"' '"\\e004"';
-@list-font-family: "fontsmith-icons";
-@list-value: "\e003";
-@list: '"fontsmith-icons"' '"\\e003"';
-@loop-font-family: "fontsmith-icons";
-@loop-value: "\e002";
-@loop: '"fontsmith-icons"' '"\\e002"';
@warning-font-family: "fontsmith-icons";
@warning-value: "\e000";
@warning: '"fontsmith-icons"' '"\\e000"';
@question-font-family: "fontsmith-icons";
@question-value: "\e001";
@question: '"fontsmith-icons"' '"\\e001"';
+@lab-font-family: "fontsmith-icons";
+@lab-value: "\e004";
+@lab: '"fontsmith-icons"' '"\\e004"';
+@list-font-family: "fontsmith-icons";
+@list-value: "\e003";
+@list: '"fontsmith-icons"' '"\\e003"';
@bars-font-family: "fontsmith-icons";
@bars-value: "\e005";
@bars: '"fontsmith-icons"' '"\\e005"';
@arrow-left3-font-family: "fontsmith-icons";
@arrow-left3-value: "\e006";
@arrow-left3: '"fontsmith-icons"' '"\\e006"';
+@loop-font-family: "fontsmith-icons";
+@loop-value: "\e002";
+@loop: '"fontsmith-icons"' '"\\e002"';
.icon-font-family(@char) {
font-family: ~`@{char}[0]`;
@@ -49,7 +49,7 @@
@font-face {
font-family: "fontsmith-icons";
- src:url("/front/fonts/icons.woff") format("woff"),
+ src:url("/fonts/icons.woff") format("woff"),
;
font-weight: normal;
font-style: normal;
diff --git a/front/src/main.html b/front/src/main.html
index 53ccfc5..508841a 100644
--- a/front/src/main.html
+++ b/front/src/main.html
@@ -3,30 +3,34 @@
Yellow Lab Tools
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -38,13 +42,7 @@
\ No newline at end of file
diff --git a/front/src/views/dashboard.html b/front/src/views/dashboard.html
index 0fba7bc..e95421d 100644
--- a/front/src/views/dashboard.html
+++ b/front/src/views/dashboard.html
@@ -1,4 +1,4 @@
-
+
@@ -16,11 +16,8 @@
{{category.label}}
-
+
diff --git a/front/src/views/queue.html b/front/src/views/queue.html
index 219d29f..c34d3b4 100644
--- a/front/src/views/queue.html
+++ b/front/src/views/queue.html
@@ -8,9 +8,7 @@
-
+
(auto-refresh activated)
diff --git a/front/src/views/rule.html b/front/src/views/rule.html
index 36b6cfc..ee540ce 100644
--- a/front/src/views/rule.html
+++ b/front/src/views/rule.html
@@ -1,4 +1,4 @@
-
+
-
+
diff --git a/front/src/views/timeline.html b/front/src/views/timeline.html
index de7894f..71210ab 100644
--- a/front/src/views/timeline.html
+++ b/front/src/views/timeline.html
@@ -1,4 +1,4 @@
-
+
Javascript Timeline
This graph gives a quick view of when the Javascript interactions with the DOM occur during the loading of the page.
@@ -9,14 +9,14 @@
-
+
{{$index + 1}}
{{node.data.type}}
@@ -90,10 +88,7 @@
-
diff --git a/lib/server/controllers/frontController.js b/lib/server/controllers/frontController.js
index ebcf139..9a19a67 100644
--- a/lib/server/controllers/frontController.js
+++ b/lib/server/controllers/frontController.js
@@ -1,19 +1,26 @@
-var path = require('path');
-var express = require('express');
+var path = require('path');
+var express = require('express');
var FrontController = function(app) {
'use strict';
+
+ var cacheDuration = 365 * 24 * 60 * 60 * 1000; // One year
+ var assetsPath = (app.get('env') === 'development') ? '../../../front/src' : '../../../front/build';
var routes = ['/', '/about', '/result/:runId', '/result/:runId/timeline', '/result/:runId/rule/:policy', '/queue/:runId'];
-
routes.forEach(function(route) {
app.get(route, function(req, res) {
- res.sendFile(path.join(__dirname, '../../../front/src/main.html'));
+ res.setHeader('Cache-Control', 'public, max-age=20');
+ res.sendFile(path.join(__dirname, assetsPath, 'main.html'));
});
});
- app.use('/front', express.static(path.join(__dirname, '../../../front/src')));
- app.use('/bower_components', express.static(path.join(__dirname, '../../../bower_components')));
+ app.use('/css', express.static(path.join(__dirname, assetsPath, 'css'), { maxAge: cacheDuration }));
+ app.use('/fonts', express.static(path.join(__dirname, assetsPath, 'fonts'), { maxAge: cacheDuration }));
+ app.use('/img', express.static(path.join(__dirname, assetsPath, 'img'), { maxAge: cacheDuration }));
+ app.use('/js', express.static(path.join(__dirname, assetsPath, 'js'), { maxAge: cacheDuration }));
+ app.use('/views', express.static(path.join(__dirname, assetsPath, 'views'), { maxAge: cacheDuration }));
+ app.use('/bower_components', express.static(path.join(__dirname, '../../../bower_components'), { maxAge: cacheDuration }));
};
module.exports = FrontController;
\ No newline at end of file
diff --git a/package.json b/package.json
index 39a277d..fa04850 100644
--- a/package.json
+++ b/package.json
@@ -26,14 +26,22 @@
"grunt": "^0.4.5",
"grunt-blanket": "^0.0.8",
"grunt-contrib-clean": "^0.6.0",
+ "grunt-contrib-concat": "^0.5.0",
"grunt-contrib-copy": "^0.7.0",
+ "grunt-contrib-cssmin": "^0.11.0",
+ "grunt-contrib-htmlmin": "^0.3.0",
"grunt-contrib-jshint": "^0.10.0",
"grunt-contrib-less": "^0.12.0",
+ "grunt-contrib-uglify": "^0.7.0",
+ "grunt-env": "^0.4.2",
"grunt-express": "^1.4.1",
+ "grunt-filerev": "^2.1.2",
"grunt-fontsmith": "^0.9.1",
+ "grunt-inline-angular-templates": "^0.1.5",
"grunt-line-remover": "^0.0.2",
"grunt-mocha-test": "^0.12.4",
"grunt-replace": "^0.8.0",
+ "grunt-usemin": "^3.0.0",
"matchdep": "^0.3.0",
"mocha": "^2.1.0",
"phantomjs": "^1.9.13",
diff --git a/server_config/server_install.sh b/server_config/server_install.sh
index cbdecae..f63294e 100644
--- a/server_config/server_install.sh
+++ b/server_config/server_install.sh
@@ -21,7 +21,7 @@ sudo chown $USER /space
cd /space
git clone https://github.com/gmetais/YellowLabTools.git --branch master
cd YellowLabTools
-npm install --production
+npm install
bower install --config.interactive=false --allow-root
# Front-end compilation
@@ -31,4 +31,4 @@ grunt build
# Start the server
rm server_config/settings.json
cp server_config/settings-prod.json server_config/settings.json
-forever start -c "node --stack-size=65500" bin/server.js
\ No newline at end of file
+NODE_ENV=production forever start -c "node --stack-size=65500" bin/server.js
\ No newline at end of file
diff --git a/server_config/server_update.sh b/server_config/server_update.sh
index a294ffb..0cf1ee3 100755
--- a/server_config/server_update.sh
+++ b/server_config/server_update.sh
@@ -12,9 +12,14 @@ git stash pop
# In case something was added in package.json or bower.json
rm -rf node_modules
-npm install --production
+npm install
rm -rf bower_components
bower install --config.interactive=false --allow-root
+# Front-end compilation
+rm -rf front/build
+npm install -g grunt
+grunt build
+
# Restart the server
-forever start -c "node --stack-size=65500" server.js
\ No newline at end of file
+NODE_ENV=production forever start -c "node --stack-size=65500" bin/server.js
\ No newline at end of file