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

A GruntJS Modular Compiler

Brett Uglow
February 24, 2015

A GruntJS Modular Compiler

Building websites from code that is grouped into modules, using the GruntJS plugin "grunt-modular-compiler"

Brett Uglow

February 24, 2015
Tweet

More Decks by Brett Uglow

Other Decks in Programming

Transcript

  1. Image  Credit   Code more, compile less Or, “Building Websites

    from Modular Code using a Module Compiler” Image  Credit  
  2. Image  Credit   Image  Credit   What am I talking

    about? •  One way to organise source code for web projects •  Past approaches •  Desired pattern & need for a tool •  An implementation of the pattern using GruntJS as the tool •  Key features of the tool •  How to extend & use tool Image  Credit  
  3. Image  Credit   Image  Credit   Image  Credit   Who

    this is for? •  You are sick of re-creating build processes every time you start a new project •  You want to have common workflow steps across projects •  You want debugging to be easy •  You want to write code & tests, not build tools
  4. Image  Credit   Image  Credit   Remember Dreamweaver? FrontPage? – all

    your files were grouped into a folder structure that would be uploaded to your web server – input source-tree === output source tree – Worked OK for static sites or server- rendered sites Image  Credit  
  5. Image  Credit   Image  Credit   But then we started

    building client-rendered apps/sites •  Lots more JS •  How to organise the JS, and other assets •  What about tests? Where should they sit? Image  Credit  
  6. Image  Credit   Image  Credit   Along came AngularJS • 

    Tutorial + early StackOverflow answers: arrange everything by type – /controllers – /services – /filters – /directives Image  Credit  
  7. Image  Credit   Image  Credit   By TYPE input-trees Pros

    •  Good for small codebases/demos •  Similar/same as how files will be deployed Cons •  Global code is next to module-specific code •  Hard to identify which files are part of a module >> doesn’t scale well Image  Credit  
  8. Image  Credit   Image  Credit   So what do I

    want the input tree to look like? •  Group related-things together into packages/ folders/modules •  If modules are complex, break into smaller sub-modules •  Move global code into a module •  Everything is inside a module – avoid “special” files (e.g. /lib, /test, /util) Image  Credit  
  9. Image  Credit   Image  Credit   Image  Credit   Example

    Sub-module Sub-sub-module Module Module Module
  10. Image  Credit   Image  Credit   By FEATURE input trees

    Pros •  Related code is all together (JS, HTML, CSS, tests, fixtures) •  No special files – (almost) everything can live inside a module •  Build tool can optimise-away non-production files (like tests, included files) Cons •  You need to transform your input-tree into a structure suitable for deployment to a website… you need a build tool •  It can be time-consuming to create a build tool from scratch Image  Credit  
  11. Image  Credit   Image  Credit   Build Tools to the

    Rescue Note: You don’t need to use GruntJS (or GulpJS, Broccoli or NPM) if your input-source code structure is identical to your output code structure... Image  Credit  
  12. Image  Credit   Image  Credit   It’s 2015… Input structure

    != Output structure •  Minification of assets •  Concatenation to" reduce HTTP requests •  Compile-time" file-inclusion, … Image  Credit  
  13. Image  Credit   Image  Credit   Build Tools Change the

    Game •  They allow the input code tree to be different to the output tree (by allowing files to be moved around, copied, concatenated, etc) •  Now we have the freedom to design our input-tree shape to meet our tastes/needs, but still meet needs of DEVOPS team – yay! Image  Credit  
  14. Image  Credit   Image  Credit   Requirements for the tool

    •  Have well-defined workflow steps: –  Develop, Build, Test, Release, Verify code style •  Minimise repetition (DRY configuration) •  Tasks inside workflow steps should be customisable, to support individual project needs Image  Credit  
  15. Image  Credit   Image  Credit   A better solution –"

    grunt-modular-project •  A series of grunt tasks •  Tasks grouped into workflow-tasks •  Default configuration •  Override defaults in your own Gruntfile.js •  https://github.com/uglow/grunt-modular- project Image  Credit  
  16. Image  Credit   Image  Credit   Installation •  npm install

    grunt-modular- project --save-dev •  Merge “node_modules/grunt- modular-project/ package.json” into your “package.json” file •  https://github.com/uglow/ grunt-modular-project/blob/ master/tasks/ modularProject.js for all configuration options •  Example: https://github.com/" uglow/angular-form-lib Image  Credit  
  17. Image  Credit   Image  Credit   Default input tree bower

      angular.js   ember.js   config   jshint,  karma,  protractor,  grunt  tasks   src   modules   myModule   <code>   JS,  HTML   assets   fonts   images   includes   styles   templates   unitTest   sub-­‐ moduleN   moduleN   Image  Credit  
  18. Image  Credit   Image  Credit   Image  Credit   Default

    output tree dev  /  dist   assets   myModule   font   images   css   style.css   js   myModule.js   moduleN.js   library.js   myModule   subModule.js   partials   myModule   HTML  files   moduleN   HTML  files   vendor   angular.js   ember.js  
  19. Image  Credit   Image  Credit   How to use • 

    grunt dev – development with recompilation •  grunt build – production build •  grunt build:serve – as above + web server •  grunt test – run unit tests •  grunt verify – run style/syntax tests •  grunt release<:patch|minor|major> - build + changelog + bump version Image  Credit  
  20. Image  Credit   Image  Credit   Default Gruntfile.js •  Becomes

    much smaller –  Define project-specific paths –  Vendor JS files (e.g. angular.js) –  Files to test –  Files to optimise Image  Credit  
  21. Image  Credit   Image  Credit   Key features •  Fast

    debug loops •  Extensible •  Consistent workflow and naming across projects that use this approach •  More time to code, less time writing tools
  22. Image  Credit   Image  Credit   How to extend • 

    build.tasks = [array of tasks] •  optimise.tasks = […] •  release.tasks (post-release tasks) = […] •  test.tasks.unitTest = […], test.tasks.unitTestBrowser = […] •  verify.tasks.<a few kinds> = […]
  23. Image  Credit   Image  Credit   Contributing •  This is

    a work in progress (ie: not perfect) •  Hopefully this workflow pattern (dev/build/ test/verify) can be better-implemented in GulpJS or Broccoli or <x> •  Having a consistent development approach is more important than the technology used to produce it – don’t get hung up on “Grunt vs X”
  24. Image  Credit   Image  Credit   Image  Credit   FAQ

    (there’s only one) •  Q. We build from source code straight to uglified code and source-maps. Why do you suggest a debug build? •  A. Because there will be bugs, and source-maps don’t always load in different/older browsers. Additionally, uglifying your code after every JS-change adds time to your debug-loop. Walk first, then run.