RailsConf 2011

Keynote: The Asset Pipeline and Our Postmodern Hybrid JavaScript Future

RailsConf 2011, David Heinemeier Hansson

RailsConf 2011

00:00:08.000 right so rails 3.1 is just around the corner and it includes a lot of
00:00:15.080 wonderful things I am going to talk mainly about one of those wonderful things today but uh I'm sure we'll have
00:00:22.000 plenty of information about the rest so this talk is entitled the acid
00:00:28.080 Pipeline and postmodern Hy hbd and our postmodern hybrid JavaScript future
00:00:34.000 let's start with the first part um the acid pipeline which is by far my
00:00:39.600 favorite new element in rails 3.1 and I think it's going to have a huge impact
00:00:45.559 on how we all create rep applications rails applications going
00:00:50.879 forward but before we go into the mechanics of of how it works I want to
00:00:56.600 focus a little bit about on the origins about how this came came about all of the things that I try to
00:01:03.440 work on in rails start out as as problems something that's just a nagging
00:01:11.159 sense of some kind that that this stuff could be could be better because there's a direct pain there's something that's
00:01:19.799 just um jumping out at me when I'm looking at a rails code base and thinking this is really not good enough
00:01:27.240 we have to do do better here uh this is is annoying me every time I look at it a
00:01:32.759 lot of the time that's actually a visual pain I'll be looking at a piece of code and it just offends me like there's
00:01:40.439 something here that's just this is supposed to be simpler this is supposed to be cleaner why is this a mess so
00:01:49.399 we've been going through this cycle over and over and over again with rails and that's how we usually release new
00:01:55.200 version we reduce pain we take it out and leave it with something more
00:02:01.600 pleasurable and I think that that's really a good cycle to be in when you're trying to design a framework is to focus
00:02:09.360 on the problems focus on the pain that you have because then you sort of know when you're done it's very easy to just
00:02:16.959 continue on programming when you're a framework Builder and and before you know it you have much more than that
00:02:22.519 original pain and how did this all come to be and and you have too much stuff we
00:02:27.680 try really hard not to have too much stuff the stuff that goes into a new version of rails is because somebody was
00:02:33.879 personally annoyed uh about the old way now one of the key things I've been
00:02:39.879 annoyed about for a very long time is this this is a directory in base camp of
00:02:47.640 all the JavaScript files that we have in just one big directory called JavaScript now just seeing this image
00:02:55.040 when I took this um screenshot I was like huh this is
00:03:00.239 [ __ ] terrible like why are all these files here why are they just in one big
00:03:05.360 uh lump and then when you start to dive into it it offence you even more because
00:03:10.440 look at this for example calendar date JS calendar date format calendar date select this is obviously a unit this is
00:03:17.560 a unit of work that is supposed to be grouped together and the only way we're grouping it together is by underscores
00:03:23.920 that's a pretty poor form of uh of grouping and not only that it's at a
00:03:29.400 complete completely different level of abstraction than say fancy Zoom which is an external library that we just dumped
00:03:35.720 into the same directory too like here I have Cod that I wrote right next to Cod
00:03:40.840 that somebody else wrote that doesn't feel right um it might both elements
00:03:46.159 might be sort of Library code but um it feels like it should be separate it gets even worse when you look at other
00:03:51.920 elements of it for example Milestones tojs this is Javascript that goes with a single controller we're mixing levels of
00:03:58.959 abstraction here that have nothing to do with each other and it's just one big
00:04:04.480 cluster or it's a junk drawer it's not that junk drawers are
00:04:10.079 not useful they have useful tools there's uh a measuring tape in there
00:04:15.959 sometimes you need a measuring tape but if you have to go into a junk drawer to get it that's going to just start off
00:04:22.240 the day on the wrong foot that's not a great way of getting getting stuff done you want the measuring tape to be
00:04:28.080 together with other things that have to do with measuring and cutting not rubber bands or uh uh pencils or something else
00:04:35.080 like that what I found is that I think there's a general rule here and the
00:04:40.560 general rule is roughly if you have more than 13 things together if you have more than
00:04:48.800 that it's not good there's something wrong here just the the sheer number 13
00:04:55.840 when I've been looking at at files that has methods or uh directories or something as soon as we get above that
00:05:01.960 it just instinctively feels messy it gets a lot worse when you then
00:05:08.199 add things at different level of abstraction but but even just when you have more than 13s of the same things it
00:05:14.080 feels messy and when it feels messy you need push back you need somebody to or
00:05:20.800 something to enforce the rules you need a cop of some kind um for
00:05:28.319 folders they have this this problem of sort of the boiling frog um you slowly
00:05:33.960 get boiled no folders start out with 20 files in them they start out with two files in them then you add one more and
00:05:40.039 then you have three and then you add a few more and then you have 15 and you sort of how did I get here like I felt
00:05:46.160 that this project was nice and clean when I started out and something happened and all of a sudden wasn't very clean anymore you didn't have this push
00:05:53.120 back so I was thinking how can we combat that how can we sort of enforce this
00:05:59.680 this metric and it's like what if um we just had folders that could only hold 13 files that was it you couldn't add
00:06:05.960 another file to it like yeah that's that's kind of arbitrary which is of
00:06:11.680 course how a lot of laws come to be there's sort of just arbitrary restrictions that don't tell you any
00:06:18.160 about why it's there so you want the rule in place to
00:06:23.599 enforce that you you you keep develop a a nice clean application but you also
00:06:28.759 want that just ification of why the rule is there in place we had that with
00:06:36.080 rest rest was exactly the same problem just applied to a different scope it was
00:06:41.919 applied to controllers controllers had a very easy tendency to get to 13 methods
00:06:47.199 or more just because you pour junk into them because just adding one more method doesn't feel that bad and before you
00:06:52.800 know it you have 13 so we put in a natural restriction of seven oh six
00:06:59.560 can't even count um so six methods that's the default methods if you have one more than that it feels wrong
00:07:05.400 because you're somehow breaking uh the conventions we have there so that was good that's nice we we should think
00:07:11.360 about ways we could apply something similar to to the JavaScript drunk drawer problem but at least it's better
00:07:17.120 than than what we used to have which was just one megabit file where everything got dumped into um that's more like uh
00:07:24.720 trash back development and I much prefer junk drawer development to trash back development and the reason we got there
00:07:32.520 was we we had this thing so JavaScript include Tac include everything now this
00:07:39.199 made it really easy just to have all those files you saw on the first slide in in one big directory because it would
00:07:44.400 concatenate all of them and it would cash it nicely so we made one of the problems really easy to solve we made
00:07:50.759 the problem of concatenation of speed something that's easy the tradeoff was
00:07:56.639 that we also made it very easy to to make that mesh you saw now this is a
00:08:03.080 powerful Insight people will do what's easy so it's easy right now to write St
00:08:08.800 stre include tag everything right which means it's easy to concatenate everything which means it's easy to dump
00:08:15.000 everything into just one big folder okay well that's that's good if
00:08:20.560 if we could somehow flip that around such that something else becomes easy then then we're on the right path in any
00:08:26.599 case the conclusion to all of this is the conclusion to making it easy to turn
00:08:33.519 JavaScript and stylesheets and all sorts of other assets into a big junk drawer
00:08:38.599 is that we treat them as second class citizens we don't care about the CSS and
00:08:46.120 the JavaScript code nearly as much as we care about the rubby code because the rubby code is nicely organized we have
00:08:52.760 sort of um schemes for dealing with that and thus we care about that more I think
00:08:58.760 that that's not a winning strategy I think that uh web applications and web
00:09:04.399 developers have to sort of come out of that we've already had this this big blend where we used to have just
00:09:10.279 front-end developers who would touch the messy HTML and JavaScript stuff and then
00:09:15.440 we had the backend developers who focused on the nice clean Ruby stuff uh
00:09:20.480 I think that's blending and I think that that's a wonderful thing I don't think that these should be separate
00:09:25.800 roles so what the solution here um the
00:09:32.040 solution sort of takes inspiration from I think one of the greatest Innovations
00:09:37.680 of Ruby un rails one of the things I'm most proud about in in in everything we've set up with this framework which
00:09:44.120 is two things one empty folders empty folders and empty files I
00:09:53.399 think empty folders and empty files are two of the pivotal innov ations in rails
00:10:00.760 that has uh encouraged us to write clean applications since the framework
00:10:07.320 appeared and I think this is true because when you have a place for everything and everything is in its
00:10:13.399 place things feel nice they feel clean and you feel calm about it when
00:10:18.640 everything is a big mess it's sort of you're dreading working with it I dread working with that JavaScript folder
00:10:25.160 because I know that everything is just piled in together and I know the effects the Broken Window Theory of piling
00:10:31.640 everything in together is that nobody gives a [ __ ] of what's in the individual files this is all a big mess anyway so
00:10:38.360 who cares if I just add another piece of crappy JavaScript code to the end of this one file in this one big pile
00:10:45.480 nobody cares when everything is in its place and and everything has a place we do
00:10:51.440 care like nobody's going to be the [ __ ] that throws trash on a clean
00:10:56.720 Street nobody's going to be the [ __ ] that add nasty code to a nice pristine
00:11:02.000 code base so as long as you can keep that idea going that this is clean that this
00:11:09.320 is nicely organized and this is good um people will try very hard to live up to
00:11:16.000 that so with the acid pipeline we're introducing a set of new
00:11:23.959 Innovations empty folders there is going to be three empty
00:11:29.160 folders in three different places uh the asset pipeline deals with images stylesheets and javascripts and makes it
00:11:36.440 really clean to have all of these things in the places where they feel home so we
00:11:42.000 have app assets lip assets and vendor assets if you take the example from before milestones. JS would go into app
00:11:49.480 assets because it's JavaScript that relates to the application itself to one
00:11:54.600 of the controllers we would put in calendar date into lip assets because
00:11:59.720 it's sort of a little um library that I wrote for my own application is not particular to this application but it it
00:12:06.240 goes with this application and I wrote it and finally you would put in fancy zoom in Vendor Assets Now just doing
00:12:13.600 that just having three different places to put these three scopes of assets is a
00:12:19.440 huge win as soon as I started doing this I went from having 40 files in one
00:12:24.800 folder to having I don't know 15 in each folder not below the 13 still feels
00:12:30.000 messy much better though so these are just the
00:12:35.360 defaults um the wonderful thing about the asset pipeline that we have is that
00:12:41.240 it's very easy to extend so there's a new config uh that you can set an
00:12:46.959 application RB or in an initializer um where you can add paths
00:12:53.040 to the acid pipeline this path can come from anywhere when you add it to the pipeline
00:13:00.000 it's accessible from anywhere so you add Disneyland and and there's a Goofy image
00:13:05.480 in there and you can access that from the uh Slash assets pipeline the SL
00:13:12.320 assets pipeline pulls in everything you have uh and exposes it from one single
00:13:18.720 place which is really nice here's a concrete example of how I've been using
00:13:24.800 this as I've been converting applications to rails 3.1 one the first
00:13:30.440 thing is a signal ID gem which is sort of a a gem that controls all the login logic that we use for the 37 signals
00:13:37.880 applications um that gem itself has a app assets directory which has a
00:13:45.000 JavaScript subdirectory and in there we sort of have just like namespaced uh controllers and models we have
00:13:52.079 namespaced Assets Now um inside is a a file called index.js which is basically
00:14:00.360 uh what do you call it manage script for for this collection of assets and inside
00:14:06.759 of that you can say okay this gem depends on these three files identity
00:14:11.800 validation launch bar and uh toggle credentials the really cool thing is
00:14:17.279 that now we're starting to do basically abstraction we are hiding things that the app itself shouldn't really know or
00:14:23.440 care about which is what are the JavaScript files that this plugin depends on former to that you sort of
00:14:30.279 had to manually dump it into that same junk drawer that you saw everything in in the beginning and thus expose
00:14:35.519 yourself to the internals of uh the plug-in which is nasty now the way you
00:14:41.880 require this is that you go to to your specific application go to base camp uh
00:14:47.600 app assets JavaScript again application JS has sort of the same specialness to
00:14:52.680 it as um application controller or application helper which means this is where you compile everything that is to
00:14:59.160 be about your application and we just require signal ID and Signal ID will go up and find that signal id/ index.js and
00:15:06.680 thus in turn require the things again okay well what is all this good
00:15:12.160 for all this is good for dependency management and sort of for a long time I even poo
00:15:20.079 pooed the idea that rail should have plugins or that plugin should have dependencies and before you know it um
00:15:27.560 you start using it all over the place and now whenever I use an application that that doesn't have a centralized
00:15:34.560 dependency management system for its uh for its libraries and you have to manually read a read me file or
00:15:39.920 something to figure out all the things you have to install I'm like this is nasty so the wonderful thing is here
00:15:46.240 that we can now use bundler to manage all our asset dependencies as well so
00:15:51.480 you can manage all your dependencies on things like JavaScript images and
00:15:56.600 stylesheets sometimes those things will be in packaged um plugins or engines
00:16:03.680 like I had the signal ID Gem and sometimes there will be uh more general purpose things that are just JavaScript
00:16:09.839 or just Styles sheets and we'll dive into that in in a second or two cool thing as I said there's no copying of
00:16:16.720 assets anymore I have a bunch of plugins that requireed some rake task that would
00:16:21.759 copy all these assets over into my own public directory and then when you update it you have to remember to sort
00:16:28.120 of run that R test again it's just nasty it's kind of like dumping all of rails into your git repository and just
00:16:34.880 checking it all in and just trying to keep it up today uh no fun at all so
00:16:40.560 that's what we would do sort of on the application side of things the wonderful thing about the asset pipeline is we can
00:16:45.959 extend it to everything that has something to do with with javascript's Styles sheets and images so for rail
00:16:54.040 31 we have a new gem or an updated gem called called jQuery rails gem jQuery
00:17:01.639 rails includes a directory vendor assets JavaScript that includes the actual
00:17:06.760 jQuery files so now we've taken those jQuery files the framework files we've
00:17:13.079 moved them out of rails itself move them into its own dependency which can has its own have its own version number can
00:17:20.240 be tracked through bundler on its own accord and then in the application
00:17:27.559 itself we can just reference that which makes it very easy to update and it
00:17:33.280 makes very easy to bundle these things together oh by the way jQuery is the new
00:17:52.120 coming but the wonderful thing about setting it up like this making it a
00:17:59.080 external dependency is that all that's required now to switch from jQuery to
00:18:04.840 say prototype is this jQuery rails is a line in your gem
00:18:14.280 file so it's no longer part of rails itself we have a convention set up um to
00:18:22.000 use these and reference these things but it's not baked in rails the the rails
00:18:27.200 repository no longer includes any JavaScript framework files so that makes
00:18:32.640 switching back and forth incredibly easy um now I'm talking a lot about
00:18:38.559 JavaScript because this is where I've been using it mostly but all of these
00:18:43.760 principles apply equally to CSS so for example if you want to include a CSS
00:18:51.320 framework like blueprint uh it works exactly the same way you can bundle this up in nice external gems and you can
00:18:59.039 just say let's depend on it on the side awesome all right just what I've shown
00:19:05.600 you right now the load path Alone um solves that initial problem I
00:19:11.280 had now that you have the load path you don't need this junk drawer files um and
00:19:17.039 you can split everything out into nice neat discret dependencies and you can
00:19:22.840 depend on those awesome we could have stopped here we could have said just declared Victory we the load path
00:19:29.880 Hallelujah um but we're else developers
00:19:34.960 so it's not really enough just to solve the problem we have to have the
00:19:43.679 pleasure so um we introduced this pleasure in
00:19:49.799 sort of a painful way
00:19:56.880 um so the way we I won't go further down that path
00:20:02.559 um disc commit um where Jos Peak added coffee
00:20:09.559 script to the default gem file in rails he didn't give any justification he just
00:20:15.039 popped it in there and sat back with a big troll face on his uh as
00:20:24.960 his Avatar and of course um the response was predictable and this turned into I
00:20:32.960 think one of the longest common threats on GitHub and it had wonderful things
00:20:38.600 like JavaScript is a toy it's nothing more than aggregation of features it's simplistic it's a hugely newsest thing
00:20:45.600 to do so lame this is not a sane default by any
00:20:51.559 stretch of imagination just because you guys use it doesn't mean that I want to use it thanks but no
00:20:57.120 thanks and finally I smell a
00:21:03.080 fork which is sort of like the um rubian rails perhaps open source equivalent of
00:21:10.679 all reasonable debates always devolve into somebody calling somebody else
00:21:15.799 Hitler um the open source equivalent is all going to Fork this thing
00:21:23.520 um so the sort of response from this uh from this whole thread was
00:21:31.120 um these defaults are really near and dear to a lot of people's hearts which I
00:21:37.159 can actually I can sympathize with um and and in some perverted way I
00:21:45.559 actually sort of appreciate that level of visual feedback that comes from
00:21:51.360 people um and all these images sort of came out
00:21:57.520 in um in that threat all right but one thing is the
00:22:04.559 initial visceral reaction the knee-jerk reaction that people have when they see
00:22:10.840 something like this without any justification or without any explanation and it's it's good fun I I must say I I
00:22:18.039 enjoyed that uh thread you should look it up on GitHub I think if you search on uh rails coffee script is the first hit
00:22:24.440 and there's about I don't know 500 comments there with lots of more funny pictures now okay fine we've had that
00:22:31.840 moment we can step back breathe and then we can perhaps listen to some more
00:22:37.760 recent um Arguments for this so this is a great quow uh coffee script is well
00:22:44.120 done and more convenient to use than JavaScript You' say all right I would have written that because I like coffee
00:22:49.919 script or the guy who made coffee script would have written that um but uh
00:22:55.120 actually the guy who wrote that was uh Brendan Ike uh the inventor of JavaScript
00:23:00.440 um so maybe sometimes it's just time to chill
00:23:07.200 the [ __ ] out and wait to sort of let this internalize and see where it goes
00:23:12.919 before you you freak out he has another wonderful uh followup from that we
00:23:18.039 should continue to grow the language keeping support for old forms while adding new forms to help users
00:23:23.240 themselves grow language I really respond to quotes like
00:23:28.919 that I really like that because as I talked about at Ruby conf this year this
00:23:34.200 is exactly why I like Ruby this is exactly why I'm still using Ruby after
00:23:39.760 eight or nine years because Ruby allows us to extend
00:23:45.080 and grow the language while keeping the old forms that is basically what active
00:23:50.400 support is and active support is probably my favorite part of rails okay
00:23:56.559 I'm just going to take you quick quickly through a few sort of Snippets of of what's cool in in coffee script uh
00:24:03.400 here's actually a I've only been writing is for for a little while here's a piece of code just I'm using in my own
00:24:08.960 application uh and the only thing that this really shows is how little line nose line nose line noise this has
00:24:17.840 compared to the um JavaScript function so just taking all this out which is
00:24:23.080 it's kind of ironic because a lot of Ruby people I know are what uh significant whites space that's crazy
00:24:29.559 that's what the python guys do and like that was never what I had against python like the significant whites space I
00:24:34.919 thought is actually nice it takes out a a lot of things it makes a few things difficult solvable things but that
00:24:40.240 wasn't the beef I had with with python um and thus it's not the beef I have with coffee script I think it's
00:24:45.799 wonderful so coffee script uses significant white space and it cuts drastically down on the amount of Cru
00:24:51.640 that you have to use particularly because JavaScript has a whole lot more CR to deal with scoping than say Robby
00:24:58.960 all right um here's another neat example um coffee script uh doing a direction
00:25:04.760 and calling a method with a call back very nice and clean the equivalent
00:25:09.840 JavaScript version of that not so nice and clean um here's a few things that that
00:25:17.039 you can do in in coffee script that I would actually like to even do in Ruby looking at coffeescript was the first
00:25:23.399 time I got a little bit of language Envy the first time I was like
00:25:28.559 damn why doesn't Ruby do that um is and isn't is a great way of putting it I
00:25:35.320 thought at first it was a little gimmicky and then I started using it in my applications and I thought that was actually pretty cool so it just makes
00:25:42.960 for really nice readable codes it's a few just drizzles of keywords and yet um
00:25:49.080 pretty neat um really neat to maybe this is the one thing I I I I really like is
00:25:55.039 that uh in Constructors you can sort of um there's a short hand for doing the standard getter and Setter so this class
00:26:02.840 has a Constructor that just takes at name which basically expands into
00:26:07.880 assigning an instance variable called name from the first parameter really nice we do that all the time in Ruby
00:26:14.480 wouldn't that be great if we had that in Ruby all right now I won't go too much into the specifics of coffee script
00:26:20.520 because there's a whole um session on that uh that Trevor is giving tomorrow
00:26:26.520 uh I think at this time might actually be a little bit change of uh of a schedule these things were put on top of
00:26:32.480 each other a little bit but uh I encourage you to go to to check that out and otherwise go to coffeescript
00:26:46.039 toorgle and the really nice things about coffeescript is that uh it is just JavaScript it's just like a nicer
00:26:52.600 cleaner more well spoken version of JavaScript we're still speaking about the same Concepts it still all boils
00:26:59.440 down to JavaScript you still constantly compile this into JavaScript to see what's actually going to happen but it's
00:27:05.000 just a nicer way to get there just like uh Ruby compiles into or Ruby's written
00:27:11.799 in C and it compiles into something else that's not Ruby directly being run uh I think that this is a great step forward
00:27:17.640 for uh for JavaScript basically treating it like it's it's more kind to to
00:27:23.440 assembler um okay so that's the JavaScript side of things um
00:27:30.279 the Styles sheet side of things is um is pretty interesting too so it uses the
00:27:37.159 same asset pipeline which means it has a load path just like JavaScript has a load path and it can use pre-processors
00:27:44.559 just like JavaScript can use a pre-processor Coffey script is just a pre-processor we're putting on top of um
00:27:52.120 of JavaScript and when it's in the load path it just happens automatically you will be writing coffee script and you
00:27:58.679 don't have to do anything you go straight to your browser and you reload and it'll automatically compile it it'll check if it's new it'll go through all
00:28:05.000 the motions and it'll just work part of the trouble with this before it was integrated this neatly um was that you
00:28:11.799 had to do things by hand there's been a couple of gems that done sort of some of this stuff but uh now we picked it
00:28:17.240 straight in anyway SAS or scss is a um pre-processor for sty
00:28:25.080 sheets which basically does the same thing that coffeescript just to JavaScript just as a at a less expansive
00:28:31.000 scope and it was originally created by by this guy Hampton Gatlin who I first met in um
00:28:39.919 in Canada for the very first rails conference in I think 2005 Canada on Rails and he presented um in much the
00:28:49.360 same manner actually as he's displayed on this image with a beer in his hand um
00:28:54.720 and he was swearing worse than a sailor and I thought I like this guy this is a great guy to have in our
00:29:01.679 community and I walked away from there thinking I really should give a uh whatever he's talking about a chance
00:29:08.440 whatever he was talking about of course was Hamill which is uh uh Hampton's uh
00:29:14.960 approach to sort of clean up HTML now I never took on that like I
00:29:20.960 really enjoyed the presentation I I never took on and enjoyed uh haml that much uh perhaps because I didn't find
00:29:27.880 found the uh transformation from HTML to to Hamill to be aesthetically pleasing to me but I
00:29:35.360 can completely appreciate and understand why why people would still want to do it um even if it doesn't fancy my aesthetic
00:29:41.919 it follows the same pattern so you can say well if you like cycript and you want that compile into JavaScript why
00:29:47.000 wouldn't you want something to compile into to HTML and it's it's a very fair it's a fair point
00:29:52.720 but um Hamill then to bring it back to SAS um was sort of married to to SAS
00:30:00.279 here there sort of this uh Loft connection going on which meant for a very long time I didn't care about sass
00:30:05.559 either because I'd sort of ritten off haml as something that didn't apply to my sense of Aesthetics um and and those
00:30:12.679 since these two things were were bound together it wasn't something I could use for a whole lot
00:30:19.480 well here's a Ryan Singer putting it uh sort of how I felt it like requiring a haml to use SAS feels like inviting
00:30:26.519 somebody you don't like over to your house because they have a cute
00:30:31.720 friend um of course Hammer which I I one
00:30:37.200 of the reasons I appreciate it still is sort of uh the fan base is as rapid as
00:30:44.279 anything so Ryan actually had to go out and uh afterwards almost apologize for
00:30:49.399 making a joke about it I hope the Hamil topic didn't overshadow the important points of my talk thanks for the
00:30:55.000 feedback so far um I think he brought brought this up at uh at a conference and spent half his talk defending why he
00:31:01.519 just said what he just said so um anyway back to
00:31:07.120 SAS so SAS basically drips just a few things on top of CSS to make it more
00:31:14.600 like uh programming to take some of those repetitive things out that we keep
00:31:19.919 doing over and over again and and replace them in programming uh the thing I've actually seen used the most and the
00:31:25.960 one feature that I appreciate the most from this is just nesting which is just about indention and not repeating
00:31:32.320 yourself over and over again it also has variables and has a bunch of other features uh I don't think
00:31:38.159 that transformation is as dramatic as it is going from JavaScript to coffeescript
00:31:43.240 that feels like whoa this was big I now enjoy it so much more this is more like
00:31:49.039 nice awesome we can do this too this is great why would I want why would I want to write regular uh CSS again now now
00:31:57.279 that I know this and as lock have it we have a guy who's
00:32:03.440 been working on uh SAS project Chris Epstein uh giving another talk which was
00:32:08.919 originally planned on top of the coffee script talk but I think we're trying to work out how to move those things around
00:32:14.039 so you can go to seat both thanks okay um but of course we will
00:32:22.519 always want to take this one step further so this is not just about making it possible this is also about making it
00:32:28.600 easy and making it something that people will actually use thus we have baked it
00:32:34.480 straight into the generators the default assumption will be that if you change
00:32:39.600 nothing you will want to want write Coffey script and SAS instead of JavaScript and CSS so generators like
00:32:48.039 the um resource generator will now generate stop files for you uh when you
00:32:53.159 generate a new post resource you get the controller you get the model and you're now also going to get a stop file for uh
00:33:00.440 the JavaScript that goes with it and the stylesheet that goes with it which sort of ties it into that whole um sphere we
00:33:07.760 have where you also automatically get a Helper you also automatically get testing you get all the things that's
00:33:13.159 reasonable for somebody to want to use when they're creating a new resource
00:33:19.080 which means that we're elevating all of this stuff up to the same level of importance as the Rubik code itself
00:33:27.760 it even lives in app now it doesn't live in in public anymore public is just a
00:33:33.159 deploy Target and uh soon enough it'll just be empty uh and there'll be nothing
00:33:39.279 to it uh another neat little uh side note is that um the pre-processing
00:33:45.519 pipeline for this uses something called tilt which is kind of like rack for
00:33:50.559 template handlers um we're going to integrate that into rails more shortly but in the meanwhile we're just using it
00:33:56.600 for the pipeline it has this cool feature that you can keep appending um pre-processors so you can apply SAS to
00:34:04.600 Styles sheets and then you can also apply Erb on top of the SAS which allows you to do things like this to reference
00:34:12.040 helpers straight inside the JavaScript which is really neat
00:34:22.800 for example other assets um that you want to use straight in there awesome aome all right
00:34:31.119 so SAS Coffey script defaults well there are other ways to
00:34:38.000 achieve these things uh there are competitors or Alternatives or whatever you want to call it to something like
00:34:43.760 SAS less is one example we've made it really easy to integrate that stuff too
00:34:49.800 so if if you want to use less instead of sub SAS it'll be almost trivial to do um
00:34:58.280 but that sort of debate uh brought up an older debate that we've been having for
00:35:03.480 a long time I just want to settle it once and for all now on the one hand we
00:35:09.440 have the idea or the notion that that rail should have defaults that we will pick things we will pick choices where
00:35:18.280 there are alternatives and then there's sort of the other argument that rail should have no defaults and we should
00:35:23.680 instead leave it to the programmer to figure out what's best in his particular or hers particular situation and um
00:35:31.320 they'll sort of string it all together as as as they please
00:35:36.359 now defaults won it's over rails will
00:35:41.880 have opinions about things and it will pick winners for its default stack that
00:35:47.320 we will promote it's a settled score it's not going to change
00:35:53.839 um so sort of something I I I I keep thinking about
00:36:00.119 whenever this topic comes up is uh is the first time I ordered a uh Burger when I came to the us about 10 years ago
00:36:08.079 um and it looked something like this and when I got that plate delivered
00:36:13.119 I was like what the [ __ ] why didn't they finish
00:36:21.000 it like presumably there's a chef out there who's preparing the food but comes
00:36:27.119 out disassembled why do I have to get a construction kit to just get a meal like
00:36:34.560 I ask for a burger presumably there's somebody back there cooking and preparing it who knows something about
00:36:41.480 put putting a burger together yet I have to get this [ __ ] and I have to put it together myself and I'll get all greasy
00:36:47.920 and it's nasty this is not a civilized way to eat when you order a burger in
00:36:55.079 Copenhagen you get a knife and a fork and a prepared meal and I was like why can't it just be
00:37:01.960 like that so I swore that uh rails was not going to be construction kid food we
00:37:08.440 were going to have a chef in the back kitchen who would present you with a finished dish that you can enjoy
00:37:14.839 straight away without thinking oh how much lettuce am I going to put on here um uninteresting
00:37:22.160 choices like the lettuce is the lettuce and whether you have one or two
00:37:27.240 Tomatoes doesn't matter as long as you sort of don't have to get all greasy so
00:37:33.800 um this sort of has another corat which is the idea of the curated framework
00:37:39.839 which is that that we will pick things that since the beginning of time we presented as what most people would want
00:37:46.000 to do most of the time I firmly believe that most people most of the time will want to use coffee script and SAS so it
00:37:53.119 makes for great defaults and people who are not interested interested in going into the intricate details of whether I
00:38:00.040 should have one or two slices of tomato can just start enjoying the framework right away and for people who are
00:38:05.400 interested in doing that it's still possible it's a little messy you have to sort of take the Tomato out afterwards
00:38:11.640 but but you can do it so this is what we start with in the default gem file um
00:38:17.280 something we sort of called Soft dependencies so in ruby gems there are hard dependencies if you name another
00:38:24.200 gem in your Ruby spec that gem is forcefully installed when you install
00:38:29.599 the parent gem not an option you can't choose not to have it so we wanted to step that back just one step and which
00:38:37.040 means that we're going to include these in the default gem file instead and the gem file of course is uh available for
00:38:42.680 anybody to edit and all they have to do is this and there will be no SAS and
00:38:48.720 there will be no coffee script and by default the generators will not generate coffee or SAS so this is all it takes
00:38:57.400 um pretty easy to do but still worth flipping out over for just one day
00:39:05.839 um now this is sort of a long process and
00:39:10.960 and I I remember hearing a lot of people fearing like well if you're adding all these pre-processors and you have the
00:39:16.920 load path and everything how will it scale well um this is not just some
00:39:24.359 hippie love thing this actually is sort of carefully thought out and the way we
00:39:29.560 thought it out was uh pre-compilation so by default we've added a new R task that you will pop
00:39:36.000 into your capestrano script or whatever else you're using to deploy uh it's called Rake assets pre-compile it'll go
00:39:43.319 through your entire load path um and by default it'll pre-compile application JF
00:39:50.640 an application CSS which will include all the JavaScript that you've said it should include and all the CSS and it'll
00:39:56.839 copy over all the images too such that these are all just um static
00:40:02.560 hits the way it copies them over though is pretty interesting and and a big step up from what we have today so what we
00:40:08.920 have today is rails by default uses M time to figure out whether this is a new
00:40:13.960 asset or not and it sort of just appends that to the to the parameters now M time
00:40:20.000 is is fine if you never deploy your app if you deploy your app you're going to change your M times and you're going to
00:40:25.599 ask your uses to request the same uh Styles and uh javascripts again
00:40:32.880 even though you didn't change them not very nice so we moved instead to using uh I think just md5 for hashing
00:40:40.800 these asset files and then appending the hash to the file name itself um which is
00:40:48.000 then referenced so static file uh no longer prams all wonderful and the way
00:40:53.359 you just include it is just say JavaScript include t back application and it will automatically figure out oh
00:40:59.599 there's an application file it has a um uh md5 stamp on its file name and it'll
00:41:05.599 just work the great thing about that as I just said it's file based it's not params based which means it's stable it
00:41:12.359 also means um you can keep it around from deploy to deploy so one of the
00:41:17.400 problems some apps have is if they deploy a new version that changes things in the JavaScript or the stylesheets
00:41:23.760 there's sort of a mid-flight moment where somebody might be halfway through a request and they're requesting uh what
00:41:31.359 the application needs is the old version of the Styles sheets or the javascripts and what it's getting is the new
00:41:36.480 versions since you can keep both versions side by side it'll just work which is really nice it also passes much
00:41:43.160 better through proxies uh and caching schemes there's a lot of caching schemes that do not work well with the uh
00:41:49.599 parameter-based way of doing exploration it just works when it's just a part of the fem really nice uh to top that off
00:41:58.520 um we have compressors built straight in so for JavaScript we compress with
00:42:05.200 something called ugly fire we're still sort of going through the last moments of making that work but it'll strip out
00:42:11.240 all the comments it'll sort of concatenate and make it small and make it easy just to the next step is G
00:42:16.400 sipping which you can do on your web server and then it's going to be really nice neat and and tight and the same
00:42:21.960 thing we do with uh CSS which means that there's no penalty to writing nice code there's no penalty to having um comments
00:42:29.720 or anything else in there we'll just automatically strip that out now all this is based on something called
00:42:36.880 sprockets which um Sam Stevenson and Josh Peak have been working on for for
00:42:43.040 quite some time this is the underpinning the underlying engine that makes all this work so I just want to say great
00:42:49.359 job to Sam and and Josh thank you um all right
00:42:57.520 now I can sort of almost see the mouth waterer drling down uh your chin and
00:43:02.599 you're like when can I get my hands on this amazing technology I have a junk drawer I treat
00:43:10.240 CSS and JavaScript like second class citizens will this happen before the world ends
00:43:16.599 yes we're releasing the release candidates for 31 this week at this
00:43:38.520 I think it's absolutely wonderful I've been building a couple of apps with it and um I would not want to go
00:43:45.079 back now the second part of that is sort of a larger question where is all this
00:43:51.559 going where is this taking us um we're making it easier to do more JavaScript
00:43:58.760 we're making it more pleasurable to write JavaScript which means that most people would want to write more of it
00:44:04.599 and have more of it in their applications um but at the same time we have all these other things coming up on
00:44:10.400 the side that sort of um are ad justing for our attention
00:44:16.800 so one of those things is is the idea of
00:44:22.599 the complete split so we launched something called Base Cam mobile a couple of months ago um
00:44:29.800 that uses a rails backend but uses the rails back end as though it was just an
00:44:35.200 API there was nothing else to it doesn't do any views or anything else like that and then on the front end everything was
00:44:41.839 made entirely in JavaScript yes it was made with coffeescript and it was made with uh Eco and and a few other
00:44:48.440 Frameworks and and that was all nice um we sort of announced that at 37 signals as as syo and then we sort of didn't
00:44:55.520 talk about it again um and and not because we don't want to push it out there I I think it's it's a wonderful
00:45:01.359 thing I I love that we did the uh the Base Cam mobile apps in it it gave us access to all of the mobile platforms
00:45:08.520 which is it's surprising to me that we somehow have to relearn that it's nice to write
00:45:14.440 platform independent code um but we do because iOS iOS apps are sexy and and we
00:45:22.119 all want sexy until we realize that customers always also wanted on Android and there's a Windows phone and there's
00:45:27.880 other phones and then before you know it sexy is kind of a nightmare and you have to maintain a bunch of different
00:45:33.280 versions all right some people still want to do that God bless them uh I want
00:45:38.640 to write things for the web that's what I care about I do not care about being inside somebody else's Walled Garden I
00:45:45.720 love the web and I love the fact that uh these phones are now getting good enough that using HTML 5 is is a great way
00:45:52.200 forward so our alternative to writing a native app was to write it using syo and
00:45:57.319 getting something that's very close to the speed of a native app but using HTML 5 using JavaScript and so forth now
00:46:04.400 Singo splits these things up so there's a there's a front end that's all JavaScript it has its own little MVC B
00:46:12.559 uh bubble where you make models that are backed by the API back end you have controllers that sort of Route things
00:46:18.800 around and you have the view everything is is niely nicely written in JavaScript and then on the back end you have rails
00:46:24.599 which has its own see on top two and just serves as an API and then
00:46:31.000 um you're sort of writing a distributed app right you're writing these things with separate things and and I as I got
00:46:37.240 more into it and and as I saw the speed of development that that the results from that I was like I don't know like I
00:46:45.920 like this because I mean we're still using rails that's great for the back end so we can have all our domain logic in there but then we're using all this
00:46:52.040 stuff on the front end that's um actually pretty heavy and and it's a tall stack to keep in mind you basically
00:46:58.720 have MVC times two that you have to keep in your head at one time um that's a
00:47:05.559 pretty hard and pretty tall mental stack and what I fear is that we'll go back
00:47:13.680 to the time I just tried to pull us away from which was the split when there's a
00:47:19.040 guy who works on the front end and then there's a guy that works on the back end and they sort of only talk to each other
00:47:24.760 by throwing [ __ ] over the wall uh that's not really a very nice
00:47:30.400 future anyway it can certainly be done we we did it for the Base Cam mobile I really like the output of it but I fear
00:47:37.559 that maybe this is not that future I was hoping it would be it seems too
00:47:44.800 hard um all right well so that's one alternative right that's that's one way
00:47:50.200 we can go and and um that does work I don't think necessarily it's the right
00:47:56.119 way to go for everything but uh another alternative is to to use something like nodejs so node.js basically is is using
00:48:04.599 JavaScript on the server side it has some really interesting uh ideas that makes it easy to write fast socket like
00:48:12.280 stuff um and it's all JavaScript all the time which is which is pretty neat right
00:48:18.400 I have an natural inclination to like that sort of modernist approach we will
00:48:25.079 just come up with one theme one Paradigm and we will apply it to everything I
00:48:30.599 think programmers in general really like that they like that modernist
00:48:35.720 approach from sort of uh an instinctual level there's just an instinctual
00:48:41.119 attraction to that one thing all the time this is just one uh split even the
00:48:46.160 syco stuff has that where there's sort of a very strict wall rails is just responsible for the API um Singo and the
00:48:53.680 front end is just responsible for the JavaScript SCP and we have clear separation and no bleeding no drawing
00:48:59.559 across the lines now sort of the instinctual reaction
00:49:05.440 that I had to this was like awesome is then replaced afterwards with this nagging feeling that H all right this is
00:49:14.040 nice this is modern but um I I I don't really like the workflow I don't really like what comes of it of the few things
00:49:20.920 I've looked at the code I've looked for say something like no JS it it I like the Simplicity when I'm just looking at
00:49:27.079 one screen of code I don't like the Simplicity when I'm looking at five or
00:49:32.160 10 screens of code like it loses that to me which is the same thing I have the affection I have for something like
00:49:38.160 Sinatra I love Sinatra for something that's clean and can fit on one two
00:49:43.280 three screens of scroll I really don't like it when it goes beyond that because it sort of goes back to me it feels a
00:49:50.640 lot like that garbage back style coding everything just in one thing which works
00:49:56.119 when it's very neat and clear and there's just a few things less than 13 you have to keep in your head wonderful
00:50:03.480 doesn't work so well when it goes beyond that to me now as I was thinking through
00:50:08.920 this I was thinking of uh of one particular guy who's been talking about this for quite some time uh Larry wall
00:50:15.240 had this wonderful uh talk back in 1999 about uh Pearl as a postmodern
00:50:22.920 programming language and here's a wonderful quote a modernist has to decide whether this is
00:50:29.559 true or that is true the modernist believes in or more than and
00:50:35.280 postmodernists believe in and more than or and I really I encourage you guys to
00:50:41.680 to after this talk Google uh postmodern Larry wall and you'll find the whole speed and it's it's wonderful because
00:50:47.839 this explains exactly um divide I want rails to be a a postmodern
00:50:56.400 framework I want rails to take a little bit here a little bit there not have a
00:51:01.920 single driving idea uh not have a all JavaScript all the time that's the the
00:51:07.240 main model idea as driving everything and I think that we can apply this to how we build web applications even in
00:51:14.720 this um world where things have to be snappier and they have to be faster and there are people doing native apps and
00:51:21.040 there are people doing things just in JavaScript and that's that's all great now
00:51:26.440 a short presentation here of of how that postmodern relationship could work and
00:51:32.280 how I've been working on it for any new apps that I work on so here's just a sample screen from from base camp and
00:51:38.680 you see it has a lot of elements some of these elements are more interactive than others there's a project settings link
00:51:46.599 that's just a vanilla HTML link it doesn't do anything special it's very easy for us now at this point to write a
00:51:52.920 new HTML screen there's no mechanics involved there's no replacement there's no fanciness which is fine for things
00:51:58.520 that happens very rarely the project settings screen is not something you go to very often I have not bother to make
00:52:04.520 that ajaxified or anything else to make it faster because who cares when people only see it once a month if that now the
00:52:13.079 second part is things you use slightly more frequent than that the tabs for example you want to jump between
00:52:19.000 different sections in your app and you don't want to wait for a whole page reload for that to happen because that feels too slow um
00:52:25.920 um we have something I'll talk to you about in a second called pxs which is a
00:52:31.359 wonderful approach to to to dealing with that and making that fast so that brings it up just one level all right it's not
00:52:38.400 just straight HTML so it's faster than that it's still using replacement though so it's it's not ultimately fast if you
00:52:44.680 take something like the to-do list for example you want to drag things up and down you want to check them off that needs to be highly interactive and needs
00:52:50.799 to be very fast and the faster you can make that the better people going to use that all the time there might be 20
00:52:57.319 clicks on this little area um when a person is on this page if you can take
00:53:02.799 just that part and say all right we'll go full board on it um we'll go backbone
00:53:08.920 and Echo and all of these other wonderful JavaScript Technologies where you sort of have almost small little V
00:53:14.400 widgets um that'd be great now the cool thing when I look at this page is that
00:53:20.079 the amount of effort that goes into creating the full highly interactive approach of of uh something backbone
00:53:27.119 echo which is basically what we were using for Base Cam mobile we can localize that to just the
00:53:33.480 spot that requires it and then we can use sort of a degrading um degrading
00:53:40.720 that's not the word I was looking for we can use sort of like a a scale uh of other techniques when you we don't need
00:53:46.760 that level of interactivity um here's a quick video showing um pjx so as you can see right
00:53:54.680 now I'm just clicking around links um and they reload and the whole page reloads I'll actually show you that
00:53:59.720 again it goes a little fast so look at that look at the address bar this thing is reloading all right takes a little while it's replacing these things with
00:54:05.839 full page reload that would be the project settings things pjx turn that on now things are much faster you're
00:54:12.720 replacing things in line it still works with the full address bar
00:54:18.200 um I've been using this on a new app and uh for the sections of the app we were
00:54:23.280 using this on you could not tell the difference in speed between something just using PJs and something using a
00:54:29.640 full syo style development form it is really fast the way it works is that it
00:54:35.079 basically treats the layout as being stable which means that the application
00:54:41.040 uh um JS and CSS are kept stable they're not requested you're just replacing the
00:54:46.079 inner part of of the app so if you see something like um base camp like all the
00:54:52.520 red stuff would just stay stable you're only replacing the stuff in the middle when you do that it's actually really
00:54:58.559 really fast and most importantly on the server side you can have this as um no
00:55:05.880 change the only thing you're not doing when you're doing PJs is rendering the
00:55:10.960 layout over and over again which means that each of the individual pages will still work when you go directly to them
00:55:16.200 because you're still serving them with a layout and when you go to them through pjx the only thing you're not doing is
00:55:22.200 serving them the layout which can be completely abstracted away um so you
00:55:27.760 don't even care about it in your regular development flow I think this is absolutely awesome uh this is Chris from
00:55:33.920 from GitHub that uh that made this thing and uh I'd be very surprised if if pjx
00:55:39.240 is not a a standard part of the the rail stack from the next version on I'm already using it on all my new stuff and
00:55:46.079 I highly encourage you guys to look into it um and what's really nice about it is
00:55:51.680 it uses HTML 5 uh get what's called like location storage or something else like
00:55:57.640 that um where you can manipulate the address bar without doing nasty stuff
00:56:03.599 like the hashbang that you see in a lot of uh Dynamic apps these days uh I really don't like the Aesthetics of the
00:56:09.760 hashbang I understand why it's there but now we have something much better in in HTML 5 and it's supported in Firefox 4
00:56:17.480 um latest Safari uh latest Chrome and I
00:56:22.760 don't know if it's supporting II yet but the wonderful thing about it is that it has an obvious uh dropback if it's not
00:56:28.799 supported all they get is full page changes and you have to change nothing in your app to make that happen really
00:56:34.799 nice all right um finally the the fast version the one where we want the high
00:56:39.839 interactivity on the app itself um backbone is really a great way of of
00:56:45.559 getting there it's made by the same guy uh Jeremy that made a coffee script we used it for basam mobile and it
00:56:51.000 basically allows you to encapsulate just at one piece of functionality into a full MVC model which uh means you're
00:56:58.119 just transporting Json back and forth really fast really nice combine that with uh something like um Eco which is
00:57:06.640 coffee script template language like Erb it looks a lot like Erb but this is actually coffee script um and you can
00:57:14.160 use those templates with your backbone models and and it feels a lot like uh what you've already been doing and then
00:57:21.000 finally I think that this pattern is still completely clickable and awesome
00:57:26.760 this pattern is basically what we've had for a long time which is you have a form on the client side uh it's set up with
00:57:33.799 remote true which means it's going to do an ax request that hits a controller and
00:57:38.839 then the controller will actually do the JavaScript update now this model does not fit into the modernist approach of
00:57:46.400 just one thing um or one approach for everything all the time this generates
00:57:52.799 the the view or the response on the server side um which to some people comes across as being not right because
00:58:00.280 the generation of all this stuff should just happen on the JavaScript side and I've seen some in my mind little silly
00:58:06.119 things where people are rendering templates as Json uh in Json wrappers
00:58:12.280 just to send them down the wire just so they can replace them from in there which doesn't make any sense to me at all because the wonderful thing about
00:58:18.520 this is that we can reuse everything so when you're rendering your responses here you can just render the same
00:58:24.079 templates you would do as when you were rendering the first thing in the first place all right that is the asset
00:58:42.880 you