$30 off During Our Annual Pro Sale. View Details »

npm As A Build Tool

npm As A Build Tool

Grunt and Gulp are the heavyweights in the JavaScript build tool landscape. These tools can automate almost anything you find yourself doing repeatedly in a project, from minifying and concatenating source files, to running tests or compiling code. But the question is, do you need them? npm’s script directive can do everything that these build tools can, more succinctly, more elegantly, with less package dependencies and less maintenance overhead. In this session I will discuss what npm is capable of as a build tool.

Jennifer Bland

October 20, 2016
Tweet

More Decks by Jennifer Bland

Other Decks in Technology

Transcript

  1. by Jennifer Bland
    NPM as a Build Tool

    View Slide

  2. 2
    Who  am  I?
    h)p://www.jenniferbland.com  
    h)ps://github.com/ratracegrad/  
    [email protected]

    View Slide

  3. 3
    What  is  a  Build  Tool?
    Pipeline  converts  applicaBon  to  deployable  unit  
    Build  Tool  handles  
    compile  
    test  
    minify  
    bundle  
    build    
    deployment

    View Slide

  4. 4
    YEOMAN BOWER.IO
    GRUNT GULP

    View Slide

  5. 5
    Why  use  NPM?
    Already  using  npm  in  your  applicaBon  
    Keep  all  build  scripts  within  your  package.json  
    No  addiBonal  configuraBon  needed  
    Don’t  have  to  rely  on  plugins

    View Slide

  6. 6
    GeSng  Started
    npm  init

    View Slide

  7. 7
    How  to  run  npm  Scripts
    npm  scripts  are  in  the  package.json  
    Execute  by  running  either  
    npm  run-­‐script  test    
    npm  run  test

    View Slide

  8. 8
    Well  Known  Scripts
    npm  built  shortcuts  for  well-­‐known  Scripts  
    npm  run  test  
    npm  test  
    npm  tst  
    npm  t

    View Slide

  9. 9
    Other  Well  Known  Commands
    npm  start  
    npm  stop  
    npm  restart

    View Slide

  10. 10
    Pre  and  Post  Hooks
    A  hook  is  a  script  that  has  the  same  name  as  another  
    script  but  is  prefixed  with  either  pre  or  post.  
    “pretest”:  “Echo  “this  is  the  pretest  script\””,  
    “pos)est”:  “Echo  “this  is  the  pos)est  script\””  
    Use  the  -­‐s  flag  to  ‘silent’  the  script  
    1-­‐one

    View Slide

  11. 11
    Order  of  Hooks  Irrelevant
    You  can  put  the  scripts  in  any  order  in  the  
    package.json  file.  Npm  will  run  them  in  the  
    correct  order.

    View Slide

  12. 12
    Build  a  Test
    One  of  the  most  commonly  used  test  libraries  is  Mocha.  
    npm  install  mocha  should  superset  —save-­‐dev

    View Slide

  13. 13
    Available  Commands
    ls  node_modules/.bin

    View Slide

  14. 14
    Command  to  run  Mocha
    mocha  
       Default  it  looks  for  a  test  directory                                          
       Uses  the  reporter  ‘spec’  
    2-­‐two

    View Slide

  15. 15
    LinBng  Code
    JSHINT  is  a  tool  that  helps  to  detect  errors  and  
    potenBal  problems  in  your  JavaScript  code.

    View Slide

  16. 16
    Install  JSHINT
    npm  install  jshint  —save-­‐dev  
    jshint  *.js  **/*.js

    View Slide

  17. 17
    Building  Lint  Script
    “lint”:  “jshint  *.js  **/*.js

    View Slide

  18. 18
    Lint  as  pretest  Script
    Lint  is  a  script  that  you  should  run  frequently.  This    
    script  is  a  good  example  of  a  script  that  should  be  run  
    before  your  tests  in  a  pre-­‐hook  script.  
    “pretest”:  “npm  run  lint”  
    3-­‐three

    View Slide

  19. 19
    Front  End  Scripts
    compile  less  code  to  css  
    bundle  and  minify  all  scripts  
    compile  coffeeScript  and  typeScript  
    From  my  example  I  will  be    using  Browserify  to  do  
    the  bundling  and  minify.

    View Slide

  20. 20
    Install  Less
    npm  install  less  —save-­‐dev

    View Slide

  21. 21
    Compiling  Less  to  CSS
    To  compile  less  code  you  tell  it  where  is  your  source  
    less  code  and  then  where  you  want  to  output  the  CSS  
    code  that  is  generated  
    lessc  client/less/demo.less  public/css/site.css

    View Slide

  22. 22
    Create  less  Script
    “build:less”:  “lessc  client/less/demo.less    
                   public/css/site.css”

    View Slide

  23. 23
    Browserify
    npm  install  browserify  —save-­‐dev  

    View Slide

  24. 24
    Running  Browserify
    Browserify  is  similar  to  Less.  you  tell  it  where  is  your    
    sources  code  and  then  where  you  want  to  output    
    bundled  code  that  is  generated.  
    browersify  ./client/js/app.js  -­‐o  ./public/js/bundle.js
    24

    View Slide

  25. 25
    Create  Browserify  Script
    “build:bundle”:  “browersify  ./client/js/app.js    
               -­‐o  ./public/js/bundle.js”

    View Slide

  26. 26
    Minify
    Minify  is  an  npm  module  that  will  minify  the  bundle  
    created  by  Browserify.  
    npm  install  uglify  —save-­‐dev

    View Slide

  27. 27
    Minify  Script
    uglify  ./client/js/app.js  —mc  -­‐o  ./public/js/out.min.js  
    “build:uglify”:  “uglify  ./client/js/app.js  —mc    
             -­‐o  ./public/js/out.min.js”

    View Slide

  28. 28
    Refactoring  Uglify
    We  don’t  want  to  send  the  app.js  file  into  uglify.  We  
    want  to  send  the  file  generated  by  browserify  into  
    uglify.  So  let’s  refactor  our  script  to  combine  these.  
    “build:bundle”:  “browserify  ./client/js/app.js  |    
           uglifyjs  =mc  >  ./public/js/bundle.js”

    View Slide

  29. 29
    Explaining  the  Script
    The  pipe  command  tells  to  take  the  output  of  the  
    first  command  -­‐  browserify  -­‐  and  use  that  as  the  
    input  to  the  next  command  -­‐  uglify.  
    The  -­‐mc  parameter  tells  us  to  mangle  and  compress  
    the  files.  
    The  greater  than  -­‐  >  -­‐  command  tells  the  output  to    
    be  redirected  to  ./public/js/bundle.js

    View Slide

  30. 30
    Clean  Code
    Every  Bme  we  run  bundle  we  want  to  make  sure  
    that  the  old  code  is  deleted  before  the  new  code  
    is  created.  We  can  create  a  clean  script  to  do  this.  
    npm  install  rimraf  —save-­‐dev  
    “build:clean”:  “rimraf  public/css/*,  public/js/*”

    View Slide

  31. 31
    Running  the  Clean  Script
    We  want  to  run  the  clean  script  right  before  we  
    run  the  bundle  and  minify  scripts.  We  can  accomplish  
    this  by  creaBng  a  build  script  and  then  running  the  
    clean  script  in  a  “prebuild”  script.

    View Slide

  32. 32
    Build  Script
    “build”:  “npm  run  build:less  &&  npm  run  build:bundle”  
    “prebuild”:  “npm  run  build:clean”  
    4-­‐four

    View Slide

  33. 33
    What  scripts  are  available?
    So  far  we  have  created  almost  a  dozen  scripts  to  
    handle  linBng,  test,  compiling  less,  bundle,  minify  
    and  building.  
    How  do  you  know  what  scripts  are  available?  
    npm  run

    View Slide

  34. 34
    Server  Side  Scripts
    During  development  process  you  need  to  have  
    scripts  that  are  watching  for  certain  events  to  occur.  
    Compiling  Less  code  into  CSS  is  an  example  of  script  
    that  you  can  convert  into  a  watch  script.  Every  Bme  
    there  is  a  change  to  the  less  code  then  it  compiles  
    into  CSS.  All  you  need  to  do  is  refresh  your  browser  
    to  see  the  results  of  your  code  change.

    View Slide

  35. 35
    Server  Side  Watching
    Some  of  the  npm  modules  we  have  installed,  have  
    flags  that  will  allow  you  to  watch  for  changes.  Mocha  
    has  this  feature.  
    “mocha  test  -­‐u  bdd  -­‐R  min  -­‐w”  
    I  am  using  the  min  Reporter.  The  -­‐w  flag  is  the  watch.

    View Slide

  36. 36
    CreaBng  Test  Watch  Script
    “watch:test”:  “mocha  test  -­‐R  min  -­‐w”

    View Slide

  37. 37
    Refactor  Watch  Test
    We  can  improve  our  watch  script  since  it  is  using  
    the  same  command  as  our  test  script.  
    “watch:test”:  “npm  run  test  —  -­‐w  -­‐R  min”  
    The  dash  dash  space  allows  us  to  pass  through  
    arguments  to  the  underlying  command  which  
    is  mocha.

    View Slide

  38. 38
    Watching  without  BuilBn  OpBon
    If  an  npm  module  does  not  have  a  watch  opBon  then  
    you  can  use  an  npm  module  “watch”  that  can  watch  
    for  them.  
    npm  install  watch  —save-­‐dev

    View Slide

  39. 39
    Watching  Lint
    We  want  a  watch  script  that  checks  for  any  change  
    to  the  code  and  then  runs  lint  to  make  sure  our  code  
    passes.  

    View Slide

  40. 40
    Watch  Lint  Script
    “watch:lint”  “watch  ‘npm  run  lint’  .”  
    This  will  watch  for  any  changes  to  files  in  the  current  
    directory  and  if  there  is  a  change  then  run  the  lint  
    script.

    View Slide

  41. 41
    Versioning
    Usually  when  you  do  a  deploy  you  want  to  change  
    the  version  of  your  sopware.  Most  versioning  uses  
    semanBc  versioning.

    View Slide

  42. 42
    SemanBc  Versioning
    SemanBc  versioning  consists  of  MAJOR.MINOR.PATCH  
    numbering  system.  You  increment  the  
    1. MAJOR  when  you  make  incompaBble  API  changes  
    2. MINOR  when  you  add  funcBonality  in  a  backwards

    compaBble  manner  
    3. PATCH  when  you  make  backwards  compaBble

    bug  fixes


    View Slide

  43. 43
    Version  Scripts
    “version:major”:  “npm  version  major”  
    “version:minor”:  “npm  version  minor”  
    “version:patch”:  “npm  version  patch”

    View Slide

  44. 44
    Pushing  to  Github
    When  you  make  changes  to  your  code  you  want  to  
    push  those  changes  to  Github.  
    git  push  origin  master

    View Slide

  45. 45
    Pushing  to  Github
    “push:origin”:  “git  push  —tags  origin  master”  

    View Slide

  46. 46
    Deploying  to  Heroku
    First  download  the  heroku  tool  belt  from  
    h)ps://toolbelt.heroku.com  
    You  create  an  applicaBon  on  heroic  using  command  
    heroku  create  appname

    View Slide

  47. 47
    Heroku  Push  Script
    CreaBng  a  heroic  applicaBon  will  create  a  new  remote  
    for  you.  You  can  verify  that  with  the  command  
    npm  remote  -­‐v

    View Slide

  48. 48
    Heroku  Push  Script
    To  push  code  to  producBon  on  Heroku  you  would  
    use  the  command  
    git  push  heroku  master  
    “push:heroku”:  “git  push  heroku  master”

    View Slide

  49. 49
    Push  Script
    When  we  deploy  our  code  we  want  to  push  the  
    latest  version  to  github  and  to  heroic  
    We  can  combine  our  two  push  scripts  into  one  
    “push”:  “npm  run  push:origin  &&  npm  run  push:heroku

    View Slide

  50. 50
    Final  Deploy  Script
    Our  Final  Deploy  Script  should  do  the  following:  
    1. Link,  compile  and  test  server  side  JavaScript  
    2. Bundle  and  minify  client  side  JavaScript  
    3. Compile  LESS  to  CSS  
    4. New  version  
    5. Push  to  Github  
    6. Deploy  to  Heroku

    View Slide

  51. 51
    Deploy  Script
    “deploy:prod”:  “npm  run  test  -­‐s  &&                                            
         npm  run  build  -­‐s  &&  
         npm  run  version:patch  &&  
         npm  run  push  
    5-­‐five      

    View Slide

  52. 52
    LimitaBons  of  using  npm
    No  comments  
    Commands  can  be  different  on  Mac  vs  Windows  
    Harder  to  understand

    View Slide

  53. 53
    Slide  and  Code
    github.com/ratracegrad/npm-­‐as-­‐a-­‐build-­‐tool    

    View Slide

  54. 54
    NPM  Config  Variables
    npm  has  a  config  direcBve  which  allows  you  to  set  
    values  that  can  be  picked  up  as  environment  
    variables  in  your  scripts    

    View Slide

  55. 55
    NPM  Config  Variables
    “config”:  {  
    “reporter”:  “landing”  
    },  
    “scripts”:  {  
    “test”:  “mocha  -­‐r  $npm_package_config_reporter”,  
    “test:dev”:  “mocha”  
    }

    View Slide