Volt 2015
-
Upload
ryanstout -
Category
Technology
-
view
160 -
download
1
Transcript of Volt 2015
ISOMORPHIC APP DEVELOPMENT WITH RUBY AND VOLT
@RYANSTOUT
COMPLEXITY IN WEB DEVELOPMENT
COMPLEXITY IN 2004
Server Client
ViewsControllers
Models
Routes/Auth
COMPLEXITY IN 2005
Server Client
ViewsControllers
Models
Routes/Auth
Ajax
COMPLEXITY IN 2006
Server Client
ViewsControllers
Models
Routes/Auth
Ajax
REST
Random JS
COMPLEXITY IN 2007
Server Client
ViewsControllers
Models
Routes/Auth
Ajax
REST
Random JS
COMPLEXITY IN 2009
Server Client
ViewsControllers
Models
Routes/AuthREST
Asset Packing
Ajax
Random JS
COMPLEXITY IN 2011
Server Client
Views
Controllers
ViewsControllers
Models
Models
Routes/Auth
Ajax
RESTAsset Packing
COMPLEXITY IN 2012
Server Client
Views
Controllers
ViewsControllers
Models
Models
Routes/Auth
Ajax
REST
Asset Loading
Asset Packing
COMPLEXITY IN 2013
Server Client
ViewsControllers
Models
Routes/AuthREST
Routes/Auth
Asset Packing
Views
Controllers
Models
Ajax
Asset Loading
COMPLEXITY IN 2015
Server Client
ViewsControllers
Models
Routes/AuthREST
Asset Packing
Routes/Auth
Views
Controllers
Models
Ajax
Asset Loading
COMPLEXITY IN 2004
Server Client
ViewsControllers
Models
Routes/Auth
COMPLEXITY IN 2015
Server Client
ViewsControllers
Models
Routes/AuthREST
Asset Packing
Routes/Auth
Views
Controllers
Models
Ajax
Asset Loading
THE SEA OF COMPLEXITY
WHAT’S THE SOLUTION?Turbo-links
…just kidding :-)
ISOMORPHIC“similar in form”
ISOMORPHICSharing code between
client and server
Server Shared Client
Routes/Auth
Views
Controllers
Models
Ajax
Asset Loading
COMPLEXITY IN 2015
Controllers
Models
Routes/AuthREST
Asset Packing
Views
Auto Sync
ISOMORPHICSharing code between
client and server
WHAT IS VOLT?
WHAT IS VOLT?Isomorphic Web Framework
(for ruby!)
HOW?
OPALRuby to JavaScript compiler
VOLTShare controllers, models, views, and
routes between client and server
VOLTSame code runs on the client and the server!
VOLTSame code runs on the client and the server!!
VOLTSame code runs on the
client and the server!!!!
VOLTReactive Bindings for the DOM
VOLTAutomatic Data Syncing
VOLTBuild apps as nested components
OPAL
PERCEPTIONCompiling to JS adds complexity
JavaScript Compiled Ruby
Base Language
Debugging Complexity
Base Language
FalsenessWTF’s
File SizeNo Std Lib
COMPLEXITYPerformance
JS Bridge
Type Coersionthis
JavaScript Compiled Ruby
Base LanguageDebugging
COMPLEXITY
Base Language
FalsenessWTF’s
No Std LibType Coersion
this
WTF’sthis parseInt new type coercion
semicolon insertion typeof == vs === case fall-through broken comparators
“string” instanceof String == false undefined
PERCEPTION“Experimenting with @opalrb - every time I
expected to find an issue, nothing happened. Maybe it'll be time to retire coffeescript soon…”
- Sidu Ponnappa
TRANSPILINGlocal variables => local variables instance variables => object properties methods => function on object with $ prefix classes => prototypes
DEBUGGING IN OPALTranspiling
Source Maps Framework Black Boxing
RubySpecs Opal-IRB
TRANSPILINGclass User def initialize(name, age) @name = name @byear = Time.now.year - age end def welcome “Hi #{@name}, you were born in #{@byear}" end end puts User.new('Ryan', 29).welcome
def.name = def.birth_year = nil;def.$initialize = function(name, age) { var self = this; self.name = name; return self.byear = $scope.get('Time').$now().$year()['$-'](age);}; return (def.$welcome_message = function() { var self = this; return "Hi " + (self.name) + ", you were born in " + (self.byear); }, nil) && 'welcome_message';
def.name = def.birth_year = nil;def.$initialize = function(name, age) { var self = this; self.name = name; return self.byear = $scope.get('Time').$now().$year()['$-'](age);}; return (def.$welcome_message = function() { var self = this; return "Hi " + (self.name) + ", you were born in " + (self.byear); }, nil) && 'welcome_message';
def.name = def.birth_year = nil;def.$initialize = function(name, age) { var self = this; self.name = name; return self.byear = $scope.get('Time').$now().$year()['$-'](age);}; return (def.$welcome_message = function() { var self = this; return "Hi " + (self.name) + ", you were born in " + (self.byear); }, nil) && 'welcome_message';
def.name = def.birth_year = nil;def.$initialize = function(name, age) { var self = this; self.name = name; return self.byear = $scope.get('Time').$now().$year()['$-'](age);}; return (def.$welcome_message = function() { var self = this; return "Hi " + (self.name) + ", you were born in " + (self.byear); }, nil) && 'welcome_message';
return self.$puts($scope.get('User').$new("Ryan", 29).$welcome());
puts User.new('Ryan', 29).welcome
SOURCE MAPS
FRAMEWORK BLACK BOXING
OPAL-IRB
RUBYSPECS
0Kb
400Kb
800Kb
1,200Kb
1,600Kb
jQuery 2.0.3 Bootstrap+JS Angular Opal+Volt Ember
Uncompressed Minified Minified+Deflate
FILE SIZE
0Kb
28Kb
55Kb
83Kb
110Kb
jQuery 2.0.3 Bootstrap Angular Opal+Volt Ember
MIN+DEFLATE
PERFORMANCE
Class+Method Call 100x Array Push JSON.stringify vs to_json
JS Opal
benchmarks: https://github.com/ryanstout/opal_benchmarks
JS BRIDGEdef my_alert(msg) `alert(msg);` end
JavaScript Compiled Ruby
Base Language
Debugging Complexity
Base Language
FalsenessWTF’s
File SizeNo Std Lib
COMPLEXITYPerformance
JS Bridge
Type Coersionthis
JavaScript Compiled Ruby
Base LanguageDebugging
COMPLEXITY
Base Language
FalsenessWTF’s
No Std LibType Coersion
this
VOLT
COLLECTIONSpage store
params local_store
cookies
MVCController
View
Model
MVVMController/ ViewModel ViewModel
DEMO
COMPONENTSClient code + Assets + Server Code
Can be packaged as Gems Can provide “tags”
<:pagination page="{{ params._page }}" />
EXAMPLE COMPONENTSField Error Messages
Pagination File Upload
Google Maps Login/Signup Templates
TASKSclass CompleteTask < Volt::TaskHandler def complete store._todos.each do |todo| todo._complete = true end end end
VALIDATIONS & PERMISSIONS
VALIDATIONS
class Post < Volt::Model validate :name, length: 4 validate :username, unique: trueend
PERMISSIONSclass Post < Volt::Model own_by_user permissions do # Only allow owner or admin deny unless owner? || user.admin? endend
PERMISSIONSclass Post < Volt::Model own_by_user permissions(:update, :delete) do # Only allow owner to update, or admins deny unless owner? || user.admin? endend
PERMISSIONSclass Post < Volt::Model own_by_user permissions(:update, :delete) do # Only allow owner to update, or admins deny unless owner? || user.admin? end permissions(:read) do # Only the owner can see unpublished posts deny :notes if !published? && !owner? endend
RECAPAuto-Sync
Less HTTP/REST One Language Components
Single Framework Centralized State
Unified Router
RECAP
RECAP
GETTING STARTED WITH VOLTVideo Tutorials
Docs Gitter Chat
ROAD MAPData Provider API
Rails Integration (for legacy :-) Render HTML First (for SEO/Load Time)
RubyMotion Integration
Thanks
voltframework.com Thanks!
images: https://www.flickr.com/photos/haquintero/14694249897
https://www.flickr.com/photos/38535102@N04/12273961146
@RYANSTOUT & @VOLTFRAMEWORK