Extending Build to the Client: A Maven User's Guide to Grunt.js

30
Extending Build to the Client: A Maven User's Guide to Grunt.js Petr Jiricka Software Development Manager NetBeans IDE team, Oracle September 29, 2014 Copyright © 2014, Oracle and/or its affiliates. All rights reserved.

description

Maven is now established as the de facto standard build tool for Java web applications. But what if the application makes extensive use of modern client-side technologies like AngularJS or Ember framework, CSS processors like SASS/LESS, Bower package manager, what if we need to compress and minify JavaScript and CSS files? In that case it makes sense to have a dedicated build infrastructure for the client. Enter Grunt.js, a build tool specifically made for the client side. In this BOF, we will explore combining the use of Maven for the server side with Grunt.js for the client.

Transcript of Extending Build to the Client: A Maven User's Guide to Grunt.js

Page 1: Extending Build to the Client: A Maven User's Guide to Grunt.js

Extending  Build  to  the  Client:    A  Maven  User's  Guide  to  Grunt.js  

Petr  Jiricka  Software  Development  Manager  NetBeans  IDE  team,  Oracle  September  29,  2014

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Page 2: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Safe  Harbor  Statement

The  following  is  intended  to  outline  our  general  product  direction.  It  is  intended  for  information  purposes  only,  and  may  not  be  incorporated  into  any  contract.  It  is  not  a  commitment  to  deliver  any  material,  code,  or  functionality,  and  should  not  be  relied  upon  in  making  purchasing  decisions.  The  development,  release,  and  timing  of  any  features  or  functionality  described  for  Oracle’s  products  remains  at  the  sole  discretion  of  Oracle.

2

Page 3: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Program  Agenda

Evolution  of  Java  Web  Applications  

Introducing  Grunt.js  

Moving  from  Maven  to  Maven  +  Grunt.js  

Compilation,  Minification,  Unit  testing,  …  

Development  Cycle  with  Grunt.js  and  NetBeans  IDE

1

2

3

4

5

3

Page 4: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Evolution  of  Java  Web  Applications

4

Page 5: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Traditional  Java  Web  Application

• Server-­‐side  – Server-­‐side  business  logic  and  data  access  code  – Presentation  logic  and  view  controllers,  template  processing  

• Client-­‐side  – Views  using  a  template-­‐based  framework  (JSF,  Wicket,  Spring  MVC,  …)  

• Packaged  together  into  a  .war  file,  typically  using  Maven

5

Page 6: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Modern  Java  Web  Application

• Server-­‐side  – Server-­‐side  business  logic  and  data  access  code  – Exposed  as  RESTful  services  (typically  JSON)  —  “thin  server”  

• Client-­‐side  –MVVM  JavaScript  framework  (Model-­‐View-­‐Viewmodel):  AngularJS,  Ember,  Backbone,  Knockout,  …  – Client-­‐side  navigation  logic,  “single-­‐page  application”  – Consumes  JSON  data  from  the  server  

• Typically  still  packaged  together  into  a  .war  file  using  Maven

6

Page 7: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Client-­‐side  build  tasks  using  Maven?

• How  do  we  do:  – Client-­‐side  library  management  analogous  to  Maven  repositories?  

– Compilation  of  preprocessor  languages  like  SASS,  LESS  

– Compilation  of  languages  like  CoffeeScript,  TypeScript?  

–Optimization  of  static  files  (concatenation,  minification,  compression,  image  sprites)?  

– Versioning  of  static  resources  to  enable  long-­‐term  caching  by  browsers?  

– Unit  testing  and  integration  testing  of  JavaScript  files?  

• And  what  is  the  overall  development  cycle?

7

Page 8: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Introducing  Grunt.js  and  Related  Toolsgruntjs.com

8

Page 9: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

First,  let’s  talk  about  Node.js

• JavaScript  runtime  for  server  applications,  but  also  for  command-­‐line  apps  

• Includes  node  package  manager  (npm),  online  repository  of  packages  

• Packages  installed  globally  or  per-­‐project  – Per-­‐project  packages  specified  in  package.json  file  

• Platform-­‐specific  installers  available  at  nodejs.org  – Installer  adds  node  and  npm  commands  on  your  system  PATH  

• Tip:  Use  Node  Version  Manager  (nvm)  to  manage  Node.js  distribution(s)  – See  https://github.com/creationix/nvm

9

Page 10: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Next,  we  need  to  introduce  Bower

• Package  manager  for  the  client-­‐side  –Manages  frameworks,  libraries,  assets,  …  

– Supports  various  sources:  git  or  svn  repositories,  download  from  URLs,  archives,  …  

– Controlled  by  bower.json  (and  .bowerrc)  files  

• Install  using  npm,  then  use  bower  command:  – npm install -g bower  :  installs  bower  as  a  global  Node.js  module!– bower install --save jquery  :  installs  jQuery  (latest  version)  to  this  project  and  adds  an  entry  to  bower.json  – bower install  :  installs  everything  specified  in  bower.json

10

Page 11: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

And  finally,  Grunt.js

• JavaScript  task  runner  —  or  simply  a  build  tool  

• Install  using  npm:  – npm install --save-dev grunt  :  installs  Grunt  in  this  project  and  saves  it  to  the  project’s  package.json!– npm install -g grunt-cli  :  installs  the  Grunt  command  as  a  global  Node.js  module  (and  adds  it  to  your  PATH)!

• Gruntfile.js  defines  and  configures  tasks

11

Page 12: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Grunt  plugins  and  tasks

• Plugins  provide  predefined  functionality  and  make  it  available  as  tasks  

• Installing  a  plugin:  – npm install --save-dev grunt-usemin  :  installs/saves  grunt-­‐usemin  plugin  (which  provides  useminPrepare  and  usemin  tasks)  in  this  project

12

Page 13: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Configuring  tasks  and  loading  plugins  in  Gruntfile.js

grunt.initConfig({! usemin : {! options: {! dirs: ['dist']! },! html: ['dist/{,*/}*.html']! } !});!!// Load the plugin that provides the "usemin" task.!grunt.loadNpmTasks('grunt-usemin');

13

Page 14: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Custom  tasks,  default  task

grunt.registerTask('clean-build',! 'Main clean/build task with SASS preprocessing.',! ['clean:all', 'build', 'sass']);!!// Task to run when running ‘grunt’ without parameters!grunt.registerTask('default', ['clean-build']);!

14

Page 15: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Grunt  Tips

// Time how long tasks take. Can help optimize build times.!require('time-grunt')(grunt);!!// Load grunt tasks automatically!require('load-grunt-tasks')(grunt);!

• You  also  need  this  in  package.json:  ! "devDependencies": {! "time-grunt": "^0.4.0",! "load-grunt-tasks": "^0.4.0",! }

15

Page 16: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Moving  from  Maven  to  Maven  +  Grunt.js

16

Page 17: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Changing  the  project’s  source  structureAfter  (Maven  +  Grunt.js)  project!!"# client!$ !"" bower_components!$ !"" node_modules!$ !"" public_html!$ !"" dist!$ !"" bower.json!$ !"" Gruntfile.js!$ %"" package.json!%"# server! !"" src! !"" target! %"" pom.xml!

17

Before  (Maven)  project!!"" src!!"" target!%"" pom.xml!!• Sources  moved from  src/main/webapp to  client/public_html!

• Need CORS (cross-origin resource sharing) filter for development-time  

Page 18: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

• Bower  libraries  downloaded  to  a  separate  staging  area  

• Bower  libraries  copied  to  source  tree  – NetBeans  recommended  approach    

• SASS  compilation              

• Unit  testing

18

• Concatenation  • Minification  

• Static  resource  revisions  

From  Source  to  Production

Development  Environment

Production  Distribution

Source  

Page 19: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Manage  libraries  using  Bower

• Declare  libraries  in  bower.json,  instead  of  placing  them  directly  under  the  web  root  

• Copy  them  under  e.g.  public_html/libs/vendor  using  the  bowercopy  grunt  task  (from  the  grunt-­‐bowercopy  node  plugin)  

• Many  Bower  components  contain  “junk”  other  than  the  binary  itself,  so  need  to  be  careful  what  to  copy

19

Page 20: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Bundle  client  and  server  into  a  .war  file

• Top-­‐level  maven  project  called  bundle  (next  to  client  and  server)  

• pom.xml  uses  war  packaging  type  • uses  grunt-maven-plugin  to  call  Grunt  before  packaging  the  result  – https://github.com/allegro/grunt-­‐maven-­‐plugin

20

Page 21: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Compilation,  Minification,  Unit  testing,  …

21

Page 22: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Compile  SASS  to  CSS

• Uses  sass  task  (from  the  grunt-contrib-sass  node  plugin)  !sass: {! dist: {! files: {! 'main.css': 'main.scss',! 'widgets.css': 'widgets.scss'! }! }!}

22

Page 23: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Minify  and  concatenate  JavaScript  and  CSS

• Several  tasks  orchestrated  by  the  grunt-usemin  node  plugin  – useminPrepare  prepares  the  configuration  – concat  concatenates  files  (usually  JS  or  CSS).  – uglify  minifies  JS  files.  

– cssmin  minifies  CSS  files.  

– filerev  revisions  static  assets  through  a  file  content  hash.  – usemin  replaces  references  in  HTML  files  

• Output  should  be  written  to  a  separate  dist  directory  • copy  task  should  copy  all  the  other  files  from  public_html  to  dist

23

Page 24: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Unit  testing  using  Karma

• place  test  sources  under  client/test  (sibling  of  public_html)  • karma.conf.js  file  controls  the  configuration  of  Karma  

• grunt-karma  plugin  provides  karma  task  with  several  subtasks  – grunt.registerTask('test', ['karma:run']); // PhantomJS!– grunt.registerTask('test-chrome', ['karma:run-chrome']);!– grunt.registerTask('test-coverage', ['karma:coverage']);!– grunt.registerTask('test-debug', ['karma:debug']);

24

Page 25: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Development  Cycle  with  Grunt.js  and  NetBeans  IDE

25

Page 26: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Development  workflow  from  the  command  line

• watch  task  (grunt-contrib-watch  plugin)  watches  for  changes  in  compiled  files  and  recompiles  them  

• Serve  files  using  a  lightweight  web  server  • Reload  files  in  the  browser

26

Page 27: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

NetBeans  IDE

• Great  editor  for  JavaScript,  HTML,  CSS,  SASS,  LESS,  …  – Supports  frameworks  and  libraries  like  require.js,  AngularJS,  Knockout,  …  

• Running,  debugging  and  Visual  CSS  editing  not  only  on  Chrome  —  also  on  iOS  and  Android  devices  and  simulators  – Including  support  for  packaging  applications  using  the  Cordova  framework  

• Built-­‐in  lightweight  web  server,  recompile  and  refresh  browser  on  save  

• Built-­‐in  test  runner  • …  and  many  more  features

27

Page 28: Extending Build to the Client: A Maven User's Guide to Grunt.js

Copyright  ©  2014,  Oracle  and/or  its  affiliates.  All  rights  reserved.    

Resources

• Grunt.js:  gruntjs.com  

• Node.js:  nodejs.org  • Bower:  bower.io  • Karma:  karma-­‐runner.github.io  

• SASS:  sass-­‐lang.com  

• NetBeans  IDE:  netbeans.org  • Project  sources:  https://github.com/pjiricka/affablebean-­‐maven-­‐grunt  

• Slides:  http://www.slideshare.net/PetrJiricka28

Page 29: Extending Build to the Client: A Maven User's Guide to Grunt.js
Page 30: Extending Build to the Client: A Maven User's Guide to Grunt.js