SlideShare ist ein Scribd-Unternehmen logo
1 von 26
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Kürzlich hochgeladen

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 

Kürzlich hochgeladen (20)

Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 

Empfohlen

Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 

Empfohlen (20)

Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 

Introducing RaveJS: Zero-config JavaScript applications

  • 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