Painless Javascript Development

Painless Javascript Development

How to seriously level up your JS development using Iridium. Presented in totally awesome and wonder Helsinki for @HelsinkiJS


Adam Hawkins

August 29, 2012


  1. Painless Javascript Development* *Almost Made with Love for Helsinki JS

  2. var Me = { }; • Adam Hawkins • @adman65

    • • • Lead Code Monkey at Radium • Primarily Ruby guy, now focused on JS & Ember
  3. Build an ambitious app in complete isolation

  4. None
  5. None
  6. Jesus Christ. This is Hard.

  7. “If you want to make a JS app from scratch,

    you must first create the universe.” - Carl Sagan on modern JS development
  8. Our Javascript Universe 1. Figure out how to split code

    into multiple files and deliver it as a single file 2. Do #1 while using Coffeescript, SCSS, and friends 3. Do #1 and #2 while being able to hit Refresh in the browser 4. Do #1, #2 and #3 while supporting different environments (dev, test, production, staging) 5. Do #1, #2, #3, and #4 while doing TDD 6. Do all of the above without creating an HTML files 7. Think of all the tools you need to do any of these...
  9. Let’s Make a Universe

  10. $ iridium app todos create app create app/images create app/javascripts/

    create app/javascripts/ create app/javascripts/models create app/javascripts/views create app/javascripts/controllers create app/javascripts/templates create app/initializers create app/locales/en.yml create app/public create app/public/index.html.erb create app/stylesheets/app.scss create app/vendor/javascripts create app/vendor/javascripts/handlebars.js create app/vendor/javascripts/jquery.js create app/vendor/javascripts/minispade.js create app/vendor/javascripts/i81n.js create app/vendor/stylesheets create site create test create test/integration/ create test/unit/ create test/models create test/views create test/controllers create test/templates create test/support/sinon.js create application.rb
  11. That’s Quick Universe • New skeleton generated for us •

    Born from enterprise Ember requirements, but not framework specific • Integration and unit tests ready • jQuery, Handlebars, Qunit, and Sinon preloaded • Let’s build something
  12. Red, Green, Refactor

  13. # test/integration/ # straight up javascript - runs in any

    browser test "the app says hello", -> # Direct access to app code Todos.reset() Todos.userName = 'Adam' Todos.boot() assertEqual $("hello-world").text, "Adam"
  14. $ iridium test test/integration/ Run options: --seed 17630 # Running

    Tests: F 1 Test(s), 1 Assertion(s), 0 Passed, 0 Error(s), 1 Failure(s) test/integration/ App says hello Cannot call “text” on “undefined”
  15. Wait ... How? • CasperJS + PhantomJS + a bunch

    of h4x • Make your app available • Inject any test env specific code • Yes that is a full stack integration test • Great, it fails. Let’s keep going
  16. Now We Must Code

  17. ... But We Need Things

  18. # application.rb class Todos < Iridium::Application # Dependency Management config.load

    :minispade config.load :jquery config.load :handlebars config.load :ember # added end
  19. Now, We Code

  20. // - loads all the code Todos = Ember.Application.create({

    VERSION: '1.0', storeNamespace: 'todos-emberjs', }) require 'todos/router' // app/javascripts/router.js|coffee require 'todos/models' // app/javascripts/models.js|coffee require 'todos/controllers' // you get require 'todos/views' // the point require 'todos/templates' // by now
  21. // - require app and start it require ‘todos/app’

  22. That’s Not Vanilla JS • Minispade to require files •

    Module names generated from file names • Can be Coffeescript or Javascript • All files compiled into a single application.js • Let’s what our app looks like...
  23. $ cd todos $ iridium server >> Thin web server

    (v1.4.1 codename Chromeo) >> Maximum connections set to 1024 >> Listening on, CTRL+C to stop ... now hit Refresh
  24. • We haven’t written any HTML • We haven’t needed

    to configure how load our code • We’ve run a full stack integration test without any configuration • ... But we have no functionality So Far...
  25. TDD w/Unit Testing

  26. # test/models/ test "should default to not done", -> equal

    Models.todo.get('isDone'), false, "todo is not done" test "should set todo title", -> Models.todo.set 'title', "A todo" equal Models.todo.get('title'), "A todo", "todo title is set" test "should be able to signify isdone", -> Models.todo.set 'isDone', true ok Models.todo.get('isDone'), "Todo is done"
  27. $ be iridium test test/models/ Run options: --seed 14903 #

    Running Tests: EEE 3 Test(s), 3 Assertion(s), 0 Passed, 3 Error(s), 3 Failure(s) should default to not done TypeError: 'undefined' is not an object (evaluating 'Models.todo.get') # Backtrace /Users/adam/radium/iridium_tests/todos/test/support/qunit.js:340 /unit/models/ /unit/models/ should set todo title TypeError: 'undefined' is not an object (evaluating 'Models.todo.set') # Backtrace /Users/adam/radium/iridium_tests/todos/test/support/qunit.js:340 /unit/models/ /unit/models/ should be able to complete TypeError: 'undefined' is not an object (evaluating 'Models.todo.set') # Backtrace /Users/adam/radium/iridium_tests/todos/test/support/qunit.js:340 /unit/models/ /unit/models/
  28. What is this Trickery?

  29. 1. Ensure we have the correct code is there 2.

    Make an HTML file 3. Add a <script> tag for QUnit 4. Write <script> tags for support files 5. Add a <script> tag for our test(s) 6. Opens the HTML file using a browser 7. Verify results It’s All the Stuff You Used to Do
  30. Headless with PhantomJS • Open your app with your app

    code loaded • Inject test framework • Inject support code • Inject tests in Coffeescript or JS • Run a single test file • Repeat for all test files
  31. Integrated Test Runner • Execute individual tests from the CLI

    • Unified runner for integration and unit tests • QUnit by default, Jasmine support possible • File in test/support/**/*.{js,coffee} automatically loaded for you • Report test results in real time • Individual test files completely isolated
  32. $ iridium test Run options: --seed 35635 # Running Tests:

    .................................. 34 Test(s), 33 Assertion(s), 34 Passed, 0 Error(s), 0 Failure(s)
  33. Tests Pass, Time to Deploy • Need to compile everything

    to a static directory • Various build steps in involved • How do we do this?
  34. $ iridium compile # production $ iridium compile build/path $

    iridium compile -e staging
  35. Coffeescript Concatenation Minification GZip application.js | application.jz.gz

  36. Rake::Pipeline • Enter Rake::Pipeline • It’s a series of tubes

    • Input files mapped to output files • It can do everything we need
  37. input "app" output "site" match "javascripts/**/*.coffee" do coffeescript end

    match "stylesheets/**/*.scss" do scss end match "**/*.js" do concat "application.js" uglify if production? end match "**/*.css" do concat "application.css" yui_css if production? end end
  38. $ iridium generate rackup $ git add -A $ git

    commit -m “Deployable” $ git push heroku master $ heroku open # goliath online!
  39. That’s Iridium

  40. It’s like Yeoman, but ya know, available now without private

    beta. This is open source right?
  41. git clone git:// radiumsoftware/iridium.git

  42. Iridium - Architecture • Convention over Configuration • Rake::Pipeline to

    compile, compress, and minify all application files into a single static directory • Test runner built on top of PhantomJS and CasperJS • Served through a custom middleware stack ending with Rack::Directory in development and production ... or • Serve with any language or webserver (Apache/ Nginx) in production
  43. Fun Facts • Generates an HTML5 cache manifest • Works

    with Gaurd (modify a file, run its tests) • $ iridium lint • Proxies available to get around CORS or hide authentication tokens from Javascript • Use your own Assetfile if you like • i18n support built in • Automatically caches assets in production
  44. What’s Next • $ gem install iridium-ember • $ iridium

    deploy:cloudflare • $ iridium deploy:heroku • $ iridium test -b safari • $ iridium test -b IE7 • ES6 Polyfill build step
  45. Want More? • blog/2012/08/10/iridium/ by @dagda1 •

  46. Who’s Confused?