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

Build your own Grunt Task

Build your own Grunt Task

Slide for my presentation on gruntjs at @jsmontreal
https://github.com/nitriques/js-mtl-2014-08-12

Nicolas Brassard

August 12, 2014
Tweet

More Decks by Nicolas Brassard

Other Decks in Programming

Transcript

  1. Me! Nicolas Brassard-Ferron @nitriques (github, twitter) CTO & Partner @DeuxHuitHuit

    Software Engineering Degree 12+ years with javascript Early adopter of cowboy/grunt (March 2012)
  2. This talk 1. Quick view of grunt’s architecture (v0.4.x) 2.

    API 3. Hello world tasks examples 4. Plugin/Task Implementation walkthrough Does everybody uses grunt daily? * I used latest grunt-* versions.
  3. v0.4.x Architecture Underlying platform: nodejs (Duh!) 3 “layers”: API -

    CLI - Plugins Public API: Static & Task helpers CLI: Calling the API from CLI Plugins: Registering tasks + Your gruntfile!
  4. v0.4.x Architecture High level responsibilities API CLI Plugin Plugins Uses

    Calls Gruntfile Reads Loads Tasks Runs Registers Tasks
  5. API: grunt.* Grunt expose some core features using static functions.

    (ex.: grunt.event.*) Grunt also offers simple wrappers around node primitives. (ex.: grunt.log.*)
  6. API: grunt.* grunt: global namespace (contains some aliases like grunt.initConfig())

    grunt.config: read and write config values grunt.event: listen and emit global events *grunt.fail: all about failling your tasks grunt.file: reading/writing files to disk (yaml and json support) *grunt.log: better accessor for the stdout (write vs. writeln, grunt.verbose) grunt.option: shared parameters (typically CLI flags) *grunt.task: loading and registering tasks grunt.template: wrapper around Lo-Dash template engine grunt.utils: … (error, linefeed, callbacks, etc)
  7. API: Task object Encapsulates the work to be done into

    manageable and reusable units. Never directly exposed (Task === this) === true *** Except, in templating… grunt.current.task
  8. API: Task object *this.async(): promotes the task to an async

    one. puts grunt in wait mode. *this.requires(tasks[]): tells grunt this task needs success from other previously executed tasks *this.requiresConfig(prop…): validates presence of config properties this.name: the current name of the task, as defines by the register/rename call this.nameArgs: the full name, with the target and args, as from the CLI this.args: the CLI args, as an array *this.flags: the CLI args, as an object this.errorCount: the number of grunt.log.error calls during current execution *this.options([defaults]): merges the options objects with the provided defaults. returns the new options object.
  9. API: Multi Task object Extends Task to allow multiple targets.

    By default, grunt runs all targets. grunt task:test # will only run the test target *this.target: the name of the currently running target this.files: flat array of all expanded path to all files *this.filesSrc: flat array of all expanded path to source files this.data: raw data object. Use files and filesSrc is recommanded Recommanded reading: Configuring tasks, file formats, pattern matching http://gruntjs.com/configuring-tasks#files
  10. API: Multi Task object The end user creates all targets

    with initConfig(); // gruntfile.js grunt.initConfig({ task: { dev: {}, prod: {}, ... } }); Any name can be used, except options which is reserved by grunt.
  11. Hello world! We will start with a tiny and pretty

    standard looking gruntfile.js /*global module*/ module.exports = function (grunt) { 'use strict'; grunt.initConfig({...}); grunt.loadNpmTasks('grunt-plugin'); grunt.registerTask('default', ['my-task']); }; This is all you need to run existing tasks!
  12. Task: Hello world! Source code in gruntfile.js /*global module*/ module.exports

    = function (grunt) { 'use strict'; grunt.initConfig({...}); grunt.registerTask('hello', 'Task description', function () { grunt.log.writeln('Hello world!'); }); };
  13. Multi task: Hello target! Source code in gruntfile.js /*global module*/

    module.exports = function (grunt) { 'use strict'; grunt.initConfig({ hello: { world: {}, everybody: {} } }); grunt.registerMultiTask('hello', 'Task description', function () { grunt.log.writeln('Hello ' + this.target + '!'); }); }; // grunt hello:world or grunt hello:everybody
  14. Module Task: Hello world! gruntfile.js /*global module*/ module.exports = function

    (grunt) { 'use strict'; grunt.initConfig({...}); grunt.loadTasks('./tasks'); // load all tasks (all js files) in that dir }; tasks/hello.js /*global module*/ module.exports = function (grunt) { 'use strict'; grunt.registerTask('hello', 'Task description', function () { grunt.log.writeln('Hello world!'); }); };
  15. Async Task: Hello world! Source code in gruntfile.js /*global module*/

    module.exports = function (grunt) { 'use strict'; grunt.initConfig({...}); grunt.registerTask('hello', 'Task description', function () { var done = this.async(); // creates a callback // fake async operation setTimeout(function async() { grunt.log.writeln('Hello async world!'); done(true); // call the callback with success boolean parameter }, 1000); }); };
  16. Plugin: Hello world! Create a valid npm git repo 1.

    package.json 2. README.md Put your task(s) into the tasks directory (that how loadNpmTasks works) :shipit: to npm!
  17. Walkthrough Deux Huit Huit’s first published grunt plugin on npm

    Wrapper around analyze-css module (by @macbre) https://github.com/DeuxHuitHuit/grunt-contrib-analyze-css/ https://www.npmjs.org/package/grunt-contrib-analyze-css
  18. Walkthrough Make sure you have valid defaults! Also make sure

    very possible values are declared and/or documented in code. https://github.com/DeuxHuitHuit/grunt-contrib-analyze- css/blob/master/tasks/analyze-css.js#L20-L59
  19. Conclusion Do not be afraid to poke at Grunt’s API!

    It’s simple, yet really powerful. Read plugins code! Checkout CLI auto-completion support! @DeuxHuitHuit’s gruntfile.js Come say Hi! → https://deuxhuithuit.com Twitter: @nitriques, @DeuxHuitHuit
  20. Questions ? Code: https://github.com/nitriques/js-mtl-2014-08-12 Slides: https://speakerdeck.com/nitriques/build-your-own-grunt-task License: http://nitriques.mit-license.org/ Sources: http://gruntjs.com/

    http://gruntjs.com/api/grunt https://github.com/gruntjs/grunt https://github.com/gruntjs/grunt-cli https://github.com/DeuxHuitHuit/grunt-contrib-analyze-css/ https://github.com/macbre/analyze-css