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

The Grunt(Js) work of single-page apps

The Grunt(Js) work of single-page apps

When developing single page apps it's important to know what you're getting into. This talk give some insight into a workflow with GruntJs which includes compilation; templates; scripts; pre-rendering for organic SEO and deployment to the Google Cloud.

46b656be55256ced0695c9f6af82c7d4?s=128

Johann du Toit

May 31, 2014
Tweet

Transcript

  1. The grunt(js) work of single page apps by Johann du

    Toit
  2. Johann du Toit hailing from Cape Town

  3. None
  4. None
  5. NodeJS Cape Town meetup.com/nodecpt

  6. Google Developer Groups developers.google.com/groups/directory/

  7. This Talk Walk you through my workflow that I use

    for a Single Page JS app running on App Engine. THIS IS MEANT TO GET YOU THINKING
  8. The plan 1. The story of what I’m building (the

    why) 2. Grunt what is it and how to use it in your workflow (the what) 3. Use case examples for Grunt (the how) a. Local Development Workflow b. SEO for JS apps c. deploying with Grunt 4. Conclusions and Q&A
  9. The plan 1. The story of what I’m building (the

    why) 2. Grunt what is it and how to use it in your workflow (the what) 3. Use case examples for Grunt (the how) a. Local Development Workflow b. SEO for JS apps c. deploying with Grunt 4. Conclusions and Q&A
  10. twify.io

  11. None
  12. None
  13. Connected Routes on Client Premises router status updates

  14. Connected Web Users websockets !

  15. So the entire app is JS From the about page

    to the page showing live traffic. So we have a few things to consider when building an app like this.
  16. • Compiling my Coffeescript for local development and production •

    Compiling LESS/SASS for local and production • Building cache-busting revision numbers and naming files accordingly • Organic SEO for Google on the JS site ! • One line deployment
  17. The plan 1. The story of what I’m building (the

    why) 2. Grunt what is it and how to use it in your workflow (the what) 3. Use case examples for Grunt (the how) a. Local Development Workflow b. SEO for JS apps c. deploying with Grunt 4. Conclusions and Q&A
  18. None
  19. None
  20. It’s all about automation Grunt allows you to automate tasks.

    Being it something common like minification and concatenation. But also any custom task you find yourself repeating.
  21. ERRORS Manual tasks run by Humans === even if with

    best intention
  22. ERRORS Manual tasks run by Humans === even if with

    best intention Strict Equality FTW !
  23. The VERY quick “how-to-use” GruntJS Intro

  24. Download and install the Grunt-cli (sudo) npm install grunt-cli -g

    Install in Grunt in your local project npm install grunt --save-dev Create your Gruntfile.js touch Gruntfile.js
  25. Gruntfile.js ??? Is your file specifying your tasks and the

    logic. Register a task with any name you see fit. Then when you run: grunt <yourtask> BOOM DONE !
  26. Register your Task module.exports = exports = function(grunt) { //

    Metadata. grunt.initConfig({ meta: { version: '0.0.1' }, banner: ‘Some variable in this a case banner’ }); grunt.registerTask(‘moo’, function(){ console.log(‘ === mooooo ! === ’ }); });
  27. Run your Task grunt moo Will run your task and

    output === mooooo ! ===
  28. BUT there are 1000’s of already-built plugins

  29. None
  30. None
  31. If you haven’t tried it, please do ! It might

    just change your life …
  32. I’m a sucker for variables ...

  33. Because if’s ...

  34. None
  35. None
  36. • What’s it’s about • Getting started • Available Options

    • Usage Examples
  37. Install the plugin npm install grunt-contrib-coffee --save-dev

  38. Register your Plugin Task module.exports = function(grunt) { // Metadata.

    grunt.initConfig({ meta: { version: '0.0.1' } }); grunt.loadNpmTasks('grunt-contrib-coffee'); grunt.registerTask(‘moo’, function(){ console.log(‘ === mooooo ! === ’ }); });
  39. Configure module.exports = function(grunt) { // Metadata. grunt.initConfig({ coffee: {

    options: { join: true }, files: { 'public/gen/js/app.js': [ 'scripts/*.coffee' ] } }, }); grunt coffee
  40. Multiple Configuration module.exports = function(grunt) { // Metadata. grunt.initConfig({ coffee:

    { module_one: { options: { join: true }, files: { 'public/gen/js/app.js': [] }, module_two: { options: { join: true }, files: { 'public/gen/js/app2.js': [] }, }, }); “grunt coffee:module_one” and “grunt coffee:module_two”
  41. Run each task EVERY TIME ??? ... grunt clean grunt

    less:app grunt coffee:module_one grunt coffee:module_two grunt.registerTask(‘super-moo’, [ ‘clean’, ‘less:app’, ‘coffee:module_one’ ]); You can … but you can also chain grunt super-moo
  42. The plan 1. The story of what I’m building (the

    why) 2. Grunt what is it and how to use it in your workflow (the what) 3. Use case examples for Grunt (the how) a. Local Development Workflow b. SEO for JS apps c. deploying with Grunt 4. Conclusions and Q&A
  43. How we are having fun with Grunt 1. Dev Workflow

    2. SEO 3. Deployment
  44. Local Development Workflow compilation / minification and packaging for deployment

    & development
  45. Project Folder Structure public Normal public asset folder scripts JS

    for the app, so all client-side logic ... styles Contains all the styles for the site templates All client-side templates test Unit Tests twify Actual Python code, for the sake of namespace views Server-side views
  46. Idea of Client and Server templates Early on there was

    a conscious decision made to split templates that are rendered on the client and templates that are rendered on the server. This allows us to focus on building only a API that our users and api consumers use.
  47. Our Commands ‘grunt --help’

  48. ‘grunt build’

  49. ‘grunt build’ clean Clean previous build artifacts less:app Compiles our

    style to bundled css file less:vendor Compiles External Vendor libs coffee:app Compiles our actual app code handlebars:build Compiles our .hbs files to JS
  50. ‘grunt watch’

  51. ‘grunt package’

  52. ‘grunt package’ revision-init Creates a timestamp build Does the entire

    compile command uglify Compiles External Vendor libs cssmin Compiles our actual app code pre-render Compiles our .hbs files to JS revision-save Save variables about latest build
  53. None
  54. How a crawler sees your JS-App <html> <head> </head> <body>

    <div class=”content”> {{ nothing :( }} </div> <script type=”text/javascript” src=”/js/templates.js”></script> <script type=”text/javascript” src=”/js/app.js”></script> </body> </html>
  55. None
  56. 1. Inbound Links

  57. 2. Pogo Sticking

  58. 3. Social

  59. 4. Performance

  60. 5. On Page Content

  61. • Performance • Actual Page Content

  62. How Google sees your JS-App <html> <head> </head> <body> <div

    class=”content”> {{ nothing :( }} </div> <script type=”text/javascript” src=”/js/templates.js”></script> <script type=”text/javascript” src=”/js/app.js”></script> </body> </html>
  63. 4 Choices 1. Normal server side pages 2. Render client

    pages when requested by a browser 3. Pre-render pages then serve when requested by the server 4. Hope the crawler renders it correctly
  64. None
  65. 3 Choices 1. Normal server side pages 2. Render client

    pages when requested by a browser 3. Pre-render pages then serve when requested by the server 4. Hope the crawler renders it correctly
  66. Google Escape Fragment Specification www.example.com?myquery&_escaped_fragment_=key1=value1%26key2=value2

  67. How does Google know ?? • Either by looking at

    the url for ‘#!’ • Or looking for a meta tag in the header <meta name="fragment" content="!">
  68. None
  69. None
  70. None
  71. 3 Choices 1. Normal server side pages 2. Render client

    pages when requested by a browser 3. Pre-render pages then serve when requested by the server 4. Hope the crawler renders it correctly
  72. ‘grunt render’

  73. Deployment

  74. Reasons for Google Cloud • Quick Deployments • I can

    just keep selling • Unified Project
  75. ‘appcfg.py . update --oauth2’

  76. None
  77. ‘grunt deploy’

  78. ‘grunt deploy’ package Builds the assets run Runs a local

    server render Renders cached HTML of app push Pushes to App Engine
  79. None
  80. Cloud Starter Pack $500 credits for 3 months just use

    the code “GDE-IN”
  81. None
  82. The plan 1. The story of what I’m building (the

    why) 2. Grunt what is it and how to use it in your workflow (the what) 3. Use case examples for Grunt (the how) a. Local Development Workflow b. SEO for JS apps c. deploying with Grunt 4. Conclusions and Q&A
  83. Thanks ! Find the presentation at goo.gl/vmqYCc or browse all

    my other talks at johanndutoit.net