Reusing your frontend JS on the server with V8/Rhino
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Reusing your frontend JS on the server with V8/Rhino

on

  • 1,033 views

Writing modern web applications requires a ton of JS, and somewhere in that JS lies some application logic (we're not just talking DOM manipulations here). If you require that same logic on the ...

Writing modern web applications requires a ton of JS, and somewhere in that JS lies some application logic (we're not just talking DOM manipulations here). If you require that same logic on the server-side for say, generating reports, what do you do? I'll show you how ValuationUP.com pushes the single responsibility principle to the max by "embedding" V8 into our report generation code so the same JS that powers our Backbone.js frontend powers our PDF's generated by Prawn.

Thin wrappers, no duplication, practical IoC, ultimate SRP.

Statistics

Views

Total Views
1,033
Views on SlideShare
1,028
Embed Views
5

Actions

Likes
2
Downloads
2
Comments
0

2 Embeds 5

http://www.linkedin.com 3
https://twitter.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

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

Reusing your frontend JS on the server with V8/Rhino Presentation Transcript

  • 1. Reusing your frontend JSon the server with V8/RhinoPushing SRP & DI/IoC to whole new level
  • 2. Kenneth KalmerChief Rocket Scientist @ ValuationUP.com@kennethkalmergithub/kennethkalmerwww.opensourcery.co.za kennethkalmer
  • 3. ValuationUP.com Help entrepreneurs make REAL sense of their management accounts Comparative analysis within industry Refactoring financials by getting from red to green Take actions to increase their valuations Valuation is the ultimate metric
  • 4. The challengeWe need a very responsive UIRealtime updates as the user inputs informationThe RTT to the server is not worth the wait for such asimple formula
  • 5. Done!Repeat that for 50+ financial modelsBuild fully buzzword compliant frontend
  • 6. Panic! Let’s offer a PDF with all the information A PDF... ...WITH ALL THE INFORMATION
  • 7. We did it!But how?
  • 8. DilemmaDuplicate?Reuse?wkhtmltopdf? (a.k.a. wtftopdf)
  • 9. Reuse!Single Responsibility PrincipleDependency Injection/Inversion on ControlUse as much JS on the server as possible, wherepossible!
  • 10. By using therubyracer (github.com/cowboyd/rubyracer) therubyrhino (github.com/cowboyd/rubyrhino) coffee-script1 gem therubyracer, platforms: :ruby2 gem therubyrhino, platforms: :jruby34 gem coffee-script
  • 11. That’s WACC!
  • 12. With coffee 1 # Determine the WACC of the business (weighted average cost of capital) 2 class Demo.WACC 3 4 constructor: (statement) -> 5 @statement = statement 6 7 @cost_of_equity = statement.cost_of_equity 8 unless _.isFinite( @cost_of_equity ) 9 @cost_of_equity = 0.301011 calculate: ->1213 e = ( @statement.equity / ( @statement.debt + @statement.equity ) ) * @cost_of_equity14 d = ( @statement.debt / ( @statement.debt + @statement.equity ) ) * @statement.costOfDebt15 t = ( 1 - @statement.taxRate )1617 e + d * t1819 # Return the calculated WACC20 value: ->21 @wacc or= @calculate()
  • 13. Present it 1 class Demo.WaccLayout 2 3 # The view that will render our information 4 view: null 5 6 initialize: (data, view = null) -> 7 @data = data 8 @view = view 910 render: ->11 wacc = new Demo.WACC( @data.statement )1213 @view.render( wacc: wacc.value() )
  • 14. Client-side view & usage 1 # Simple backbone view 2 class Demo.WaccView extends Backbone.View 3 4 render: (options) -> 5 wacc = options.wacc 6 7 @$el.empty().append( "<h1>#{wacc}</h1>" ) 8 910111213 # Initialize a view14 view = new Demo.WaccView( el: #wacc )1516 # Load and render our layout17 layout = new Demo.WaccLayout( view: view, data: data )18 layout.render()
  • 15. Reuse on the server...
  • 16. JavaScript Context 1 require v8 2 # require rhino 3 4 # This service wraps a JS context and allows us to interact with our Javascript 5 # directly in Ruby. 6 class Javascript 7 8 # Our V8 context object 9 attr_reader :context1011 # Some delegations12 delegate :load, :eval, :[], :[]=, to: :context1314 def initialize()15 @context = V8::Context.new16 #@context = Rhino::Context.new1718 # Setup a fake window object19 @context[window] = FakeWindow.new( @context )20 @context[console] = FakeConsole.new2122 # Load our global setup23 load_coffee Rails.root.join( app/assets/javascripts/setup.js.coffee )24 end2526 # truncated, lots more detracting stuff down below...2728 end
  • 17. CoffeeScript sprinkles1 # Compile and load a CoffeeScript file into the current context2 def load_coffee( path )3 compiled_coffeescript = CoffeeScript.compile( File.read( path ) )4 context.eval compiled_coffeescript5 end
  • 18. PauseWe have a JavaScript context (V8) at our finger tipsHave some basic CoffeeScript loading abilitiesAnd some additional plumbingFar from a DOM
  • 19. Server-side wrapper 1 class WaccLayout 2 3 def initialize( view, context = Javascript.new ) 4 @context = context 5 6 load_dependencies 7 8 # Pass our Ruby view into the context 9 @context["view"] = view1011 # Setup12 @context.eval <<-EOJS13 var layout = new Demo.WaccLayout({14 view: view, data: data15 });16 EOJS17 end1819 def render20 context[layout][render].methodcall( context[layout] )21 end2223 def load_dependencies24 @context.load_coffee Rails.root.join("app/assets/javascripts/wacc.js.coffee")25 @context.load_coffee Rails.root.join("app/assets/javascripts/wacc_layout.js.coffee")26 end27 end
  • 20. Server-side view & usage 1 class WaccPdf 2 3 def initialize 4 @pdf = Prawn::Document.new 5 end 6 7 def render( options ) 8 wacc = options.wacc 910 @pdf.text "WACC: #{wacc}"11 end1213 end141516 # Setup a view17 view = WaccPdf.new1819 # Setup a layout and render20 layout = WaccLayout.new( view )21 layout.render
  • 21. 1,000 ft view
  • 22. Reminder why we did it?
  • 23. Yes please! https://github.com/kennethkalmer/rubyfuza-2013 https://rubyfuza-2013-wacc.herokuapp.com Later this weekend, you’re all getting drunk tonight anyway!!
  • 24. Thank you!It’s been wild!