Introducing RaveJS: Zero-config JavaScript applications
Upcoming SlideShare
Loading in...5
×
 

Introducing RaveJS: Zero-config JavaScript applications

on

  • 1,470 views

Introducing RaveJS. Rave eliminates configuration, machinery, and complexity. Stop configuring and tweaking file watchers, minifiers, and transpilers just to get to a runnable app. Instead, go from ...

Introducing RaveJS. Rave eliminates configuration, machinery, and complexity. Stop configuring and tweaking file watchers, minifiers, and transpilers just to get to a runnable app. Instead, go from zero to "hello world" in 30 seconds. In the next 30 seconds, easily add capabilities and frameworks to your application simply by installing *Rave Extensions* and *Rave Starter* packages from npm and Bower, the leading JavaScript package managers. Finally, install additional *Rave Extension* packages to apply your favorite build, deploy, and testing patterns.

https://github.com/RaveJS

Statistics

Views

Total Views
1,470
Views on SlideShare
1,325
Embed Views
145

Actions

Likes
1
Downloads
5
Comments
0

4 Embeds 145

https://twitter.com 98
http://lanyrd.com 44
http://www.slideee.com 2
http://feedly.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Introducing RaveJS: Zero-config JavaScript applications Introducing RaveJS: Zero-config JavaScript applications Presentation Transcript

  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ RaveJS: Zero-config app development John Hann, JavaScript Barbarian, Pivotal @unscriptable
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ I work for Pivotal's Frameworks and Runtimes group 2
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ I work on the cujoJS Toolkit - cujojs.com 3
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 4 JavaScript is awesome Architecture Language Tooling • Package managers • Minifiers / optimizers • Bundlers / builders • Pre-processors • CI • SASS/SCSS, LESS, Stylus --> CSS • Dart --> Javascript • ES6 --> ES5 • Transpile all the things! • SPA, AOP, DI, IOC • MV-WTF • Modules, components • Linters, unit testers, integration testers
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ More is more 5  More sophistication  More complexity  More machinery  More configuration  More maintenance
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ “JavaScript needs a build step.” WTF? 6
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ What happened to the good ol' days? <!doctype html> <html lang="en"> <head> <script src="easy.js"></script> <link href="easy.css" type="stylesheet"/> </head> <body> <div class="container">click me</div> </body> </html> 7
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Problem: HTML forces crappy JavaScript  You have to choose • Simple HTML or • Architecturally sound code and best practices  Doing it the "right way" requires • Too much boilerplate, configuration, and setup  Too much work to create • Apps • Prototypes and experiments • Demos and tutorials 8
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Example: recent project ~400 LOC in Gruntfile.js ~70 LOC in RequireJS main.js >100 LOC in karma configs 9
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 'use strict'; module.exports = function (grunt) {   // Load grunt tasks automatically   require('load-grunt-tasks') (grunt);   // Time how long tasks take. Can help when optimizing build times   require('time-grunt') (grunt);   // Define the configuration for all the tasks   grunt.initConfig({     // Project settings     xd: {       app: 'app',       dist: 'dist'     },     // Set bower task's targetDir to use app directory     bower: {       options: {         targetDir: '<%= xd.app %>/lib'       },       // Provide install target       install: {}     },     // Watches files for changes and runs tasks based on the changed files     watch: {       files: ['<%= xd.app %>/ **/*', '*.js', '.jshintrc'],       tasks: ['build'],       livereload: {         options: {           livereload: '<%= connect.options.livereload %>'         },         files: ['<%= xd.app %>/**/*', '*.js', '.jshintrc']       }     },     protractor: {       options: {         //configFile: "test/ protractor.conf.js", // Default config file         keepAlive: true, // If false, the grunt process stops when the test fails.         noColor: false, // If true, protractor will not use colors in its output.         args: {           specs: [             './test/e2e/**/ *.spec.js'           ],           baseUrl: 'http:// localhost:8000',           chromeDriver: 'node_modules/protractor/ selenium/chromedriver'         }       },       run: {       }     },     // The actual grunt server settings     connect: {       options: {         port: 8000,         // Set to '0.0.0.0' to access the server from outside.         hostname: '0.0.0.0',         livereload: 35729       },       livereload: {         options: {           open: true,           base: [             '.tmp',             '<%= xd.app %>'           ],           middleware: function (connect, options) {             if (! Array.isArray(options.base)) {               options.base = [options.base];             }             var middlewares = [require('grunt-connect- proxy/lib/ utils').proxyRequest];             options.base.forE ach(function (base) {               grunt.log.warn( base);               middlewares.pus h(connect.static(base));             });             return middlewares;           }         }       },       test: {         options: {           port: 9001,           base: [             '.tmp',             'test',             '<%= xd.app %>'           ]         }       },       dist: {         options: {           base: '<%= xd.dist %>'         }       },       proxies: [         {           context: ['/batch', '/job', '/modules', '/ streams'],           host: 'localhost',           port: 9393,           changeOrigin: true         }       ]     },     // Make sure code styles are up to par and there are no obvious mistakes     jshint: {       options: {         jshintrc: '.jshintrc',         reporter: require('jshint-stylish')       },       all: [         'Gruntfile.js',         '<%= xd.app %>/ scripts/{,**/}*.js'       ],       test: {         options: {           jshintrc: 'test/.jshintrc'         },         src: ['test/spec/ {,*/}*.js']       }     },     less: {       dist: {         files: {           '<%= xd.app %>/ styles/main.css': ['<%= xd.app %>/styles/main.less']         },         options: {           sourceMap: true,           sourceMapFilename: '<%= xd.app %>/styles/ main.css.map',           sourceMapBasepath: '<%= xd.app %>/',           sourceMapRootpath: '/'         }       }     },     // Empties folders to start fresh     clean: {       dist: {         files: [           {             dot: true,             src: [               '.tmp',               '<%= xd.dist %>/*'             ]           }         ]       },       server: '.tmp'     },     // Add vendor prefixed styles     autoprefixer: {       options: {         browsers: ['last 1 version']       },       dist: {         files: [           {             expand: true,             cwd: '.tmp/ styles/',             src: '{,*/} *.css',             dest: '.tmp/ styles/'           }         ]       }     }, // imagemin: { // dist: { // files: [ // { // expand: true, // cwd: '<%= xd.app %>/images', // src: '{,*/}*. {png,jpg,jpeg,gif}', // dest: '<%= xd.dist %>/images' // } // ] // } // },     // Renames files for browser caching purposes     rev: {       dist: {         files: {           src: [             // TODO: commenting out js files for now.             // '<%= xd.dist %>/scripts/{,*/}*.js',             '<%= xd.dist %>/ styles/{,*/}*.css',             '<%= xd.dist %>/ images/{,*/}*. {png,jpg,jpeg,gif}',             '<%= xd.dist %>/ fonts/*'           ]         }       }     },     // Reads HTML for usemin blocks to enable smart builds that automatically     // concat, minify and revision files. Creates configurations in memory so     // additional tasks can operate on them     useminPrepare: {       html: '<%= xd.app %>/ index.html',       options: {         dest: '<%= xd.dist %>'       }     },     // Performs rewrites based on rev and the useminPrepare configuration     usemin: {       html: ['<%= xd.dist %>/ {,*/}*.html'],       css: ['<%= xd.dist %>/ styles/{,*/}*.css'],       options: {         assetsDirs: ['<%= xd.dist %>', '<%= xd.dist %>/ images']       }     },     htmlmin: {       dist: {         options: {           collapseWhitespace: true,           collapseBooleanAttr ibutes: true,           removeCommentsFromC DATA: true,           removeOptionalTags: true         },         files: [           {             expand: true,             cwd: '<%= xd.dist %>',             src: ['*.html', 'views/{,*/}*.html'],             dest: '<%= xd.dist %>'           }         ]       }     },     // Allow the use of non- minsafe AngularJS files. Automatically makes it     // minsafe compatible so Uglify does not destroy the ng references // ngmin: { // dist: { // files: [ // { // expand: true, // cwd: '.tmp/ concat/js', // src: '*.js', // dest: '.tmp/ concat/js' // } // ] // } // },     // Copies remaining files to places other tasks can use     copy: {       dist: {         files: [           {             expand: true,             dot: true,             cwd: '<%= xd.app %>',             dest: '<%= xd.dist %>',             src: [               '*. {ico,png,txt}',               '*.html',               'views/{,*/} *.html',               'lib/**/*',               'scripts/**/*',               'fonts/*',               'images/*'             ]           }         ]       },       styles: {         expand: true,         cwd: '<%= xd.app %>/ styles',         dest: '.tmp/styles/',         src: '{,*/}*.css'       },       testfiles: {         files: [           { src: 'test/ people.txt', dest: '/tmp/xd- tests/people.txt' }         ]       }     },     // Run some tasks in parallel to speed up the build process     concurrent: {       server: [         'copy:styles'       ],       test: [         'copy:styles'       ],       dist: [         // TODO: copy:styles copies .css files into .tmp         // TODO: hence probably not to include copy:styles in here.         // 'copy:styles' 10 Gruntfile.js
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ require.config({   paths: {     domReady: '../lib/requirejs- domready/domReady',     angular: '../lib/angular/angular',     jquery: '../lib/jquery/jquery',     bootstrap: '../lib/bootstrap/ bootstrap',     ngResource: '../lib/angular- resource/angular-resource',     uiRouter: '../lib/angular-ui-router/ angular-ui-router',     cgBusy: '../lib/angular-busy/ angular-busy',     ngGrowl: '../lib/angular-growl/ angular-growl',     angularHighlightjs: '../lib/angular- highlightjs/angular-highlightjs',     highlightjs: '../lib/highlightjs/ highlight.pack'   },   shim: {     angular: {       deps: ['bootstrap'],       exports: 'angular'     },     bootstrap: {       deps: ['jquery']     },     'uiRouter': {       deps: ['angular']     },     'ngResource': {       deps: ['angular']     },     'cgBusy': {       deps: ['angular']     },     'ngGrowl': {       deps: ['angular']     },     'angularHighlightjs': {       deps: ['angular', 'highlightjs']     }   } }); define([   'require',   'angular',   'app',   './routes' ], function (require, angular) {   'use strict';   require(['domReady!'], function (document) {     console.log('Start angular application.');     angular.bootstrap(document, ['xdAdmin']);   });   require(['jquery', 'bootstrap'], function () {     console.log('Loaded Twitter Bootstrap.');     updateGrowl();     $(window).on('scroll resize', function () {       updateGrowl();     });   });   function updateGrowl() {     var bodyScrollTop = $ ('body').scrollTop();     var navHeight = $ ('nav').outerHeight();     if (bodyScrollTop > navHeight) {       $('.growl').css('top', 10);     } else if (bodyScrollTop >= 0) {       var distance = navHeight - bodyScrollTop;       $('.growl').css('top', distance + 10);     }   } }); 11 RequireJS main.js
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ module.exports = function(config) {   config.set({     // base path, that will be used to resolve files and exclude     basePath: '',     // testing framework to use (jasmine/mocha/qunit/...)     frameworks: ['ng-scenario'],     // list of files / patterns to load in the browser     files: [       'test/e2e/*.js',       'test/e2e/**/*.js'     ],     // list of files / patterns to exclude     exclude: [],     // web server port     port: 7070,     // level of logging     // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG     logLevel: config.LOG_INFO,     // enable / disable watching file and executing tests whenever any file changes     autoWatch: false,     // Start these browsers, currently available:     // - Chrome     // - ChromeCanary     // - Firefox     // - Opera     // - Safari (only Mac)     // - PhantomJS     // - IE (only Windows)     browsers: ['PhantomJS'],     // Continuous Integration mode     // if true, it capture browsers, run tests and exit     singleRun: true,     // Uncomment the following lines if you are using grunt's server to run the tests     proxies: {         '/': 'http://localhost: 8000/'     },     // // URL root prevent conflicts with the site root     urlRoot: '/_karma_/'   }); }; module.exports = function (config) {   'use strict';   config.set({     // base path, that will be used to resolve files and exclude     basePath: '',     // testing framework to use (jasmine/mocha/qunit/...)     frameworks: ['jasmine'],     // list of files / patterns to load in the browser     files: [       'app/lib/angular/ angular.js',       'app/lib/angular-mocks/ angular-mocks.js',       'app/lib/angular-resource/ angular-resource.js',       'app/lib/angular-cookies/ angular-cookies.js',       'app/lib/angular-sanitize/ angular-sanitize.js',       'app/lib/angular-route/ angular-route.js',       'app/lib/angular-ui-router/ angular-ui-router.js',       'app/lib/angular-growl/ angular-growl.js',       'app/lib/angular-promise- tracker/promise-tracker.js',       'app/lib/angular-busy/ angular-busy.js',       'app/scripts/*.js',       'app/scripts/**/*.js',       'test/spec/**/*.js',       'test/test-main.js'     ],     // list of files / patterns to exclude     exclude: [],     // web server port     port: 7070,     // level of logging     // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG     logLevel: config.LOG_INFO,     // enable / disable watching file and executing tests whenever any file changes     autoWatch: true,     // Start these browsers, currently available:     // - Chrome     // - ChromeCanary     // - Firefox     // - Opera     // - Safari (only Mac)     // - PhantomJS     // - IE (only Windows)     browsers: ['PhantomJS'],     // Continuous Integration mode     // if true, it capture browsers, run tests and exit     singleRun: false   }); 12 karma.conf.js
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Can we simplify this mess? We must 13
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ RaveJS 14 ┏( ˆ◡ˆ)┛┗(ˆ◡ˆ )┓ https://github.com/RaveJS
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ NO NO NO NO NO  Rave JS is NOT a new framework • …but it integrates with most (if not all)  RaveJS is NOT another {AMD|script|ES6} loader • …but it is an ES6 loader extension with a built-in shim • Loads AMD, CommonJS, and (soon) ES6 • Loads other things via loader extensions  RaveJS is NOT ready for production, yet :( • …but it is ready to play with • Feedback and PRs welcome! 15
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ RaveJS's goals in 3 bullets  Provide a default, instantly-runnable configuration  Make it easy to become sophisticated  Make it easy to assert your opinion 16
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Provide a default, instantly-runnable configuration  No machinery or configuration (just a static web server) 1. Download/install a Rave Starter (or start "from scratch") 2. Launch your favorite browser 3. Open your favorite editor or IDE  Run-time is responsive to environment 1.Write code 2.Reload 3.Repeat 17
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Make it easy to become sophisticated  CLI one-liner to switch mode • Responsive / dev <--> Built / production • Easily switch back • Still zero configuration!  CLI one-liner to launch tests • Unit tests, integration tests, push to CI 18
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Make it easy to assert your opinion  Add microlibs, frameworks, third-party integrations • e.g. Knockout-Backbone  Add capabilities: loader extensions, shims • e.g. JSON loader, WebComponents shim  Install build, deploy, and testing patterns (SPA is default) • Spring, JEE, Rails • Buster, Karma 19
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ How? Metadata 20
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Metadata all the things!  Provide default, minimal metadata out of the box  Allow devs to generate metadata naturally • bower install --save • npm install --save  Allow third parties to provide metadata • Rave Integration Extensions • bower install --save awesome-third-party-integration-package • Rave Starters 21
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Rave Extensions  Add microlibs, frameworks, third-party integrations • bower install --save rave-knockout-backbone  Add capabilities: loader extensions, shims • npm install --save rave-load-css • bower install --save rave-polymer  Install build, deploy, and test patterns (SPA is default) • bower install --save-dev rave-spring-boot • bower install --save-dev rave-buster 22
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ To CLI or not to CLI?  Rave CLI • rave install <package-on-bower-or-npm> • Finds best package for your app, invokes --save (biggest newb mistake) • rave unbuild • Uses grunt or gulp (or both!) automatically  Familiar, established CLIs • npm install --save <package> • npm test • gulp rave --unbuild • grunt rave --test 23
  • Demo Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Zero config!
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 25 Rave is a Work in Progress ASAP Summer 2014 Fall 2014 • Testing patterns • Even more extensions and patterns • Showcase/directory of community Rave Extensions? • ES6 module syntax** • IE8+ compatibility** • AngularJS 1.3 extensions and patterns** • Spring, JEE patterns • Minification • Bower*, npm* • AMD*, node* • Text*, CSS*, JSON* • cujoJS extensions* • Default build & deploy patterns** *done! **in progress
  • Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Questions? John Hann, JavaScript Barbarian, Pivotal @unscriptable