From 21823564c23dd74e562818125e5d7817c0365c73 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Tue, 10 Sep 2013 14:40:00 +0200 Subject: [PATCH] add caching --- Gruntfile.js | 13 ++++++++++--- package.json | 3 ++- src/middleware.js | 37 ++++++++++++++++++++++++++++++++++++- src/server.js | 4 +++- views/index.jade | 10 +++++----- views/static/layout.jade | 13 ++++++------- 6 files changed, 62 insertions(+), 18 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index bda73f22d7..8e65954c76 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -108,6 +108,12 @@ module.exports = function(grunt) { } }, + copy: { + build: { + files: [{expand: true, cwd: 'public/', src: 'favicon.ico', dest: 'build/'}] + } + }, + // UPDATE IT! hashres: { build: { @@ -115,7 +121,7 @@ module.exports = function(grunt) { fileNameFormat: '${name}-${hash}.${ext}' }, src: [ - 'build/*.js', 'build/*.css', + 'build/*.js', 'build/*.css', 'build/favicon.ico', 'build/bower_components/bootstrap/docs/assets/css/*.css', 'build/bower_components/habitrpg-shared/dist/*.css' ], @@ -149,8 +155,8 @@ module.exports = function(grunt) { }); // Register tasks. - grunt.registerTask('build:prod', ['clean:build', 'uglify', 'stylus', 'cssmin', 'hashres']); - grunt.registerTask('build:dev', ['clean:build', 'stylus', 'cssmin', 'hashres']); + grunt.registerTask('build:prod', ['clean:build', 'uglify', 'stylus', 'cssmin', 'copy:build', 'hashres']); + grunt.registerTask('build:dev', ['clean:build', 'stylus', 'cssmin', 'copy:build', 'hashres']); grunt.registerTask('run:dev', [ 'build:dev', 'concurrent' ]); @@ -159,6 +165,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-stylus'); grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-nodemon'); grunt.loadNpmTasks('grunt-concurrent'); grunt.loadNpmTasks('grunt-contrib-watch'); diff --git a/package.json b/package.json index 74e72c179a..ce0234c1a9 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "grunt-contrib-stylus": "~0.8.0", "grunt-contrib-clean": "~0.5.0", "grunt-contrib-cssmin": "~0.6.1", - "grunt-contrib-watch": "~0.5.x", + "grunt-contrib-watch": "~0.5.3", + "grunt-contrib-copy": "~0.4.1", "grunt-hashres": "~0.3.2", "grunt-nodemon": "~0.1.1", "grunt-concurrent": "~0.3.1", diff --git a/src/middleware.js b/src/middleware.js index 376b00f177..67afee8461 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -1,5 +1,7 @@ var nconf = require('nconf'); var _ = require('lodash'); +var fs = require('fs'); +var path = require('path'); module.exports.forceSSL = function(req, res, next){ var baseUrl = nconf.get("BASE_URL"); @@ -26,12 +28,45 @@ module.exports.cors = function(req, res, next) { return next(); }; +var buildFiles = []; + +var walk = function(folder){ + var res = fs.readdirSync(folder); + + res.forEach(function(fileName){ + file = folder + '/' + fileName; + if(fs.statSync(file).isDirectory()){ + walk(file); + }else{ + var relFolder = path.relative(path.join(__dirname, "/../build"), folder); + var old = fileName.replace(/-.{8}(\.[\d\w]+)$/, '$1'); + + if(relFolder){ + old = relFolder + '/' + old; + fileName = relFolder + '/' + fileName; + } + + buildFiles[old] = fileName + } + }); +} + +walk(path.join(__dirname, "/../build")); + +var getBuildUrl = function(url){ + console.log("CALLED ", url) + if(buildFiles[url]) return buildFiles[url]; + + return filename; +} + module.exports.locals = function(req, res, next) { res.locals.habitrpg = res.locals.habitrpg || {} _.defaults(res.locals.habitrpg, { NODE_ENV: nconf.get('NODE_ENV'), IS_MOBILE: /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(req.header('User-Agent')), - STRIPE_PUB_KEY: nconf.get('STRIPE_PUB_KEY') + STRIPE_PUB_KEY: nconf.get('STRIPE_PUB_KEY'), + getBuildUrl: getBuildUrl }); next() } diff --git a/src/server.js b/src/server.js index 2ee1125bb0..cb1a0c18f0 100644 --- a/src/server.js +++ b/src/server.js @@ -99,7 +99,9 @@ app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); -app.use(express['static'](path.join(__dirname, "/../build"))); + +var oneYear = 31536000000; +app.use(express['static'](path.join(__dirname, "/../build"), { maxAge: oneYear })); app.use(express['static'](path.join(__dirname, "/../public"))); // development only diff --git a/views/index.jade b/views/index.jade index 433e6be686..33d3f8212a 100644 --- a/views/index.jade +++ b/views/index.jade @@ -4,7 +4,7 @@ html title HabitRPG | Your Life The Role Playing Game // ?v=1 needed to force refresh - link(rel='shortcut icon' href='/favicon.ico?v=1') + link(rel='shortcut icon' href='/#{env.getBuildUrl("favicon.ico")}?v=2') script(type='text/javascript'). window.env = !{JSON.stringify(env)}; @@ -15,15 +15,15 @@ html } // CSS Remember to update also in Grunfile.js cssmin task! - link(rel='stylesheet', href='/bower_components/bootstrap/docs/assets/css/bootstrap.css') + link(rel='stylesheet', href='/#{env.getBuildUrl("bower_components/bootstrap/docs/assets/css/bootstrap.css")}') - link(rel='stylesheet', href='/app.css') + link(rel='stylesheet', href='/#{env.getBuildUrl("app.css")}') // HabitRPG Shared - link(rel='stylesheet', href='/bower_components/habitrpg-shared/dist/spritesheets.css') + link(rel='stylesheet', href='/#{env.getBuildUrl("bower_components/habitrpg-shared/dist/spritesheets.css")}') - if(env.NODE_ENV == 'production'){ - script(type='text/javascript', src='/app.js') + script(type='text/javascript', src='/#{env.getBuildUrl("app.js")}') - }else{ // Remember to update the file list in Gruntfile.js! script(type='text/javascript', src='/bower_components/jquery/jquery.min.js') diff --git a/views/static/layout.jade b/views/static/layout.jade index 6c22de5eac..07814bd1dc 100644 --- a/views/static/layout.jade +++ b/views/static/layout.jade @@ -7,23 +7,22 @@ html block title title HabitRPG | Your Life the Role Playing Game - // ?v=1 needed to force refresh - link(rel='shortcut icon' href='/favicon.ico?v=1') + link(rel='shortcut icon', href='/#{env.getBuildUrl("favicon.ico")}?v=2') meta(charset='utf-8') meta(name='viewport', content='width=device-width, initial-scale=1.0') // CSS Remember to update also in Grunfile.js cssmin task! - link(rel='stylesheet', href='/bower_components/bootstrap/docs/assets/css/bootstrap.css') + link(rel='stylesheet', href='/#{env.getBuildUrl("bower_components/bootstrap/docs/assets/css/bootstrap.css")}') // Keep this out of build because the one after has some images and would like not to override it - link(rel='stylesheet', href='/bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css') - link(href='/bower_components/bootstrap/docs/assets/css/docs.css', rel='stylesheet') + link(rel='stylesheet', href='/#{env.getBuildUrl("bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css")}') + link(rel='stylesheet', href='/#{env.getBuildUrl("bower_components/bootstrap/docs/assets/css/docs.css")}') - link(rel='stylesheet', href='/static.css') + link(rel='stylesheet', href='/#{env.getBuildUrl("static.css")}') // JS - if(layoutEnv.NODE_ENV == 'production'){ - script(type='text/javascript', src='/static.js') + script(type='text/javascript', src='/#{env.getBuildUrl("static.js")') - }else{ // Remember to update the file list in Gruntfile.js! script(type='text/javascript', src='/bower_components/jquery/jquery.min.js')