Share
Embed
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
Transcript
46 slides
-
var Me = { }; • Adam Hawkins • @adman65
• https://github.com/twinturbo • https://speakerdeck.com/u/twinturbo • Lead Code Monkey at Radium • Primarily Ruby guy, now focused on JS & Ember -
“If you want to make a JS app from scratch,
you must first create the universe.” - Carl Sagan on modern JS development -
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... -
$ iridium app todos create app create app/images create app/javascripts/app.coffee
create app/javascripts/boot.coffee 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/navigation_test.coffee create test/unit/truth_test.coffee create test/models create test/views create test/controllers create test/templates create test/support/sinon.js create application.rb -
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 -
# test/integration/hello_test.coffee # 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" -
$ iridium test test/integration/hello_test.coffee Run options: --seed 17630 # Running
Tests: F 1 Test(s), 1 Assertion(s), 0 Passed, 0 Error(s), 1 Failure(s) test/integration/hello_test.coffee: App says hello Cannot call “text” on “undefined” -
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 -
# application.rb class Todos < Iridium::Application # Dependency Management config.load
:minispade config.load :jquery config.load :handlebars config.load :ember # added end -
// app.coffee - 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 -
// boot.coffee - require app and start it require ‘todos/app’
Todos.initialize() -
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... -
$ cd todos $ iridium server >> Thin web server
(v1.4.1 codename Chromeo) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:9292, CTRL+C to stop ... now hit Refresh -
• 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... -
# test/models/todo_test.coffee 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" -
$ be iridium test test/models/todo_test.coffee 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/todo_test.coffee:17 /unit/models/todo_test.coffee:29 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/todo_test.coffee:22 /unit/models/todo_test.coffee:29 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/todo_test.coffee:27 /unit/models/todo_test.coffee: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 -
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 -
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 -
$ iridium test Run options: --seed 35635 # Running Tests:
.................................. 34 Test(s), 33 Assertion(s), 34 Passed, 0 Error(s), 0 Failure(s) -
Tests Pass, Time to Deploy • Need to compile everything
to a static directory • Various build steps in involved • How do we do this? -
$ iridium compile # production $ iridium compile build/path $
iridium compile -e staging -
Rake::Pipeline • Enter Rake::Pipeline • It’s a series of tubes
• Input files mapped to output files • It can do everything we need -
Rake::Pipeline.build 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 -
$ iridium generate rackup $ git add -A $ git
commit -m “Deployable” $ git push heroku master $ heroku open # goliath online! -
It’s like Yeoman, but ya know, available now without private
beta. This is open source right? http://yeoman.io/ -
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 -
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 -
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