Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Automated Front-end Development with Grunt

FEVR
October 27, 2014

Automated Front-end Development with Grunt

Preprocessors, minification, image enhancement, and then testing, deployment .. How many tasks we do every day? And how many different tools we have to use along our workflow?
Marco Solazzi gives us the solution, strictly javascript based, called Gruntjs

FEVR

October 27, 2014
Tweet

More Decks by FEVR

Other Decks in Programming

Transcript

  1. Performance Golden Rule: “80-90% of the end-user response time is

    spent on the frontend.” - Steve Souders (http://www.stevesouders.com/blog/2012/02/10/the-performance-golden-rule/)
  2. “Users expect pages to load in two seconds — and

    after three seconds, up to 40 percent will simply leave.” - Lara Hogan (http://alistapart.com/article/improving-ux-through-front-end-performance)
  3. Performance tips ▪Ridurre le richieste HTTP ▪Minificare JavaScript e CSS

    e comprimerli (gzip) ▪Ottimizzare le immagini ▪Resource hashing + Expires o Cache-Control Header ▪Utilizzare sprite https://developers.google.com/speed/docs/best-practices/rules_intro
  4. If your "build process" is the F5 key, you have

    a problem. - Jeff Atwood (http://www.codinghorror.com/blog/2007/10/the-f5-key-is-not-a-build-process.html)
  5. Grunt cosa? ▪JavaScript based task runner ▪Creato da Ben Alman

    nel 2012 ▪49 Contributors ▪8500+ stars su GitHub
  6. Vantaggi ▪Scritto in Nodejs ▪Installabile come modulo npm ▪Configurazione in

    formato JSON ▪Estendibile con moduli JavaScript ▪3500+ plugins (http://gruntjs.com/plugins)
  7. npm install --save-dev grunt-contrib-concat grunt-contrib-uglifyjs # concatenazione di file e

    minificazione js con uglifyjs Configurazione di base sudo npm install -g grunt-cli # -g installa globalmente 1) Installazione runtime cd grunt-demo npm init # reply to prompts... 2) Creazione file di progetto package.json npm install --save-dev grunt # --save-dev salva un riferimento alla libreria in package.json 3) Installazione delle librerie di base di grunt 4) Installazione plugins
  8. package.json { "name": "grunt-demo", "version": "0.0.1", ... "devDependencies": { "grunt":

    "~0.4.5", "grunt-contrib-concat": "~0.5.0", "grunt-contrib-uglify": "~0.6.0" } }
  9. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']); };
  10. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']);}; legge package.json e lo salva per gli altri task
  11. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']); }; legge i file JS e li concatena
  12. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']); }; minifica i sorgenti
  13. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']); }; commento generato dinamicamente
  14. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']); }; riferimenti ad altri task
  15. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']); }; carica i plugin/task installati
  16. module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { dist:

    { src: ['src/javascripts/base.js', 'src/javascripts/modules.js', 'src/javascripts/application.js'], dest: 'dist/javascripts/application.js' } }, uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n' }, dist: { files: { 'dist/javascripts/application.min.js': ['<%= concat.dist.dest %>'] } } } }); ['grunt-contrib-uglify', 'grunt-contrib-concat'].forEach(grunt.loadNpmTasks); grunt.registerTask('default', ['concat', 'uglify']); }; definisce un task di default
  17. WOK is a loosely opinionated boilerplate for web development built

    with flexibility and productivity in mind.
  18. Ingredienti... ▪Sass + Compass ( + Bootstrap-Sass) ▪Ottimizzazione e minificazione

    CSS, JS e immagini ▪EJS Templating (Jade coming soon...) ▪Markdown partials, JSON data & fixtures ▪Environment specific code blocks ▪Asset filename revving ▪Analisi e build custom di Modernizr ▪Sass automated styleguide ▪Server statico locale + watch + live reload / Browsersync ▪Deploy remoto con rsync ▪Server weinre per debug mobile