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

Introducing RaveJS: Zero-config JavaScript appl...

Introducing RaveJS: Zero-config JavaScript applications

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

unscriptable

May 28, 2014
Tweet

More Decks by unscriptable

Other Decks in Technology

Transcript

  1. 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
  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 for Pivotal's Frameworks and Runtimes group 2
  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/ I work on the cujoJS Toolkit - cujojs.com 3
  4. 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
  5. 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
  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/ “JavaScript needs a build step.” WTF? 6
  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/ 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
  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/ 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
  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/ Example: recent project ~400 LOC in Gruntfile.js ~70 LOC in RequireJS main.js >100 LOC in karma configs 9
  10. 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
  11. 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
  12. 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
  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/ Can we simplify this mess? We must 13
  14. 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
  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/ 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
  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/ 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
  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/ 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
  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 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
  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/ 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
  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/ How? Metadata 20
  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/ 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
  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/ 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
  23. 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
  24. 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!
  25. 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
  26. 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