Grunt – Introduksjon – Hvorfor bruke Grunt?



Grunt – Introduksjon – Hvorfor bruke Grunt?

0 0


grunt-slides

Grunt presentation at Bouvet

On Github martinp / grunt-slides

Grunt

Introduksjon

Martin Polden, Bouvet ASA18. september 2013

Hva er Grunt?

  • En «task runner» for JavaScript
  • Kan sammenlignes med typiske byggverktøy (make, maven, gradle)
  • Basert på NodeJS
  • Enklere å kjøre JS utenfor browseren enn tidligere (no more Rhino hacks)
  • Fjerner (noe av) smerten ved å jobbe med JavaScript
  • Hipster approved!

Hvorfor bruke Grunt?

  • Organiser typiske tasks: hinting, testing, minifying mm.
  • Automatisere rutine-oppgaver
  • Reproduserbar byggeprosess
  • Økt kodekvalitet
  • Enklere å forholde seg til tasks enn individuelle verktøy
  • Enkelt å utvide via Grunts API, alt er «bare» JavaScript
  • Brukes av flere store prosjekter: jQuery, Twitter Bootstrap, Modernizr, AngularJS, Ember.js

Eksempel på tasks

  • Hinting av kode (jshint)
  • Kjøring av tester (nodeunit/karma/buster osv.)
  • Sammenslåing av JS-filer (concat)
  • «Minifying» av kode (uglifyjs)
  • Formatering av kode (jsbeautifier)
  • Kompilering av CoffeeScript, LESS, SASS o.l.
  • Kjøring av tasks ved lagring (watch)
  • ..og masse annet

Hvordan bruke Grunt?

  • Krever node og npm
  • grunt-cli installeres globalt
  • grunt (core) og tasks installeres per prosjekt
  • Eksempel:
# Installer Grunt CLI
$ npm install -g grunt-cli

# Installer Grunt og jshint task
$ npm install grunt grunt-contrib-jshint --save-dev

# Opprett Gruntfile.js i prosjektrot
$ $EDITOR Gruntfile.js

Meta-eksempel

Gruntfile.js for denne presentasjonen

Innlasting av tasks

/* Gruntfile.js */
module.exports = function (grunt) {

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-nodeunit');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-jsbeautifier');

jshint task

grunt.initConfig({
    jshint: {
      all: ['Gruntfile.js', 'test/**/*.js'],
      options: {
        indent: 2,
        quotmark: 'single',
        maxlen: 80
      },
    },

connect task

grunt.initConfig({
    ...
    connect: {
      server: {
        options: {
          hostname: '*'
        }
      }
    },

copy task

grunt.initConfig({
    ...
    copy: {
      main: {
        files: [{
          expand: true,
          cwd: 'bower_components/reveal.js/',
          src: ['js/reveal.min.js', 'css/reveal.min.css',
            'css/theme/*.css', 'plugin/highlight/**', 'plugin/notes/**',
            'lib/js/**'
          ],
          dest: '.'
        }, {
          expand: true,
          cwd: 'bower_components/highlightjs/styles/',
          src: '*.css',
          dest: 'css/highlightjs/'
        }]
      }
    },

watch task

grunt.initConfig({
    ...
    watch: {
      scripts: {
        files: ['index.html', 'test/**/*.js'],
        tasks: ['jsbeautifier', 'jshint', 'test'],
        options: {
          livereload: true,
          spawn: false,
          atBegin: true
        }
      }
    },

jsbeautifier task

grunt.initConfig({
    ...
    jsbeautifier: {
      all: ['Gruntfile.js', 'index.html', 'test/**/*.js'],
      options: {
        html: {
          indentSize: 2
        },
        js: {
          indent_size: 2,
          jslint_happy: true,
          wrap_line_length: 80
        }
      }
    },

nodeunit task

grunt.initConfig({
    ...
    nodeunit: {
      all: ['test/*_test.js']
    }

Egne tasks

...
grunt.registerTask('pretty', 'jsbeautifier');
grunt.registerTask('test', 'nodeunit');
grunt.registerTask('w', ['connect', 'watch']);
grunt.registerTask('default', ['jsbeautifier', 'jshint', 'nodeunit']);

Kjøring

$ grunt
Running "jsbeautifier:all" (jsbeautifier) task
Beautified 3 files, changed 0 files...OK

Running "jshint:all" (jshint) task
>> 2 files lint free.

Running "nodeunit:all" (nodeunit) task
Testing foo_test.js.OK
>> 1 assertions passed (8ms)

Done, without errors.

Lenker