0:00:18.609,0:00:19.539 JUSTIN SEARLS: Good morning everybody. 0:00:19.539,0:00:21.140 That was an excellent talk that we just 0:00:21.140,0:00:22.890 saw from Brandon. Happy Friday. 0:00:22.890,0:00:24.769 It's been a long conference. 0:00:24.769,0:00:27.660 Thanks for being here. Friday hug to you all. 0:00:27.660,0:00:29.140 This, if the house lights were 0:00:29.140,0:00:30.640 up I'd take a picture. Yes. 0:00:30.640,0:00:34.180 The title of this talk is The Rails of 0:00:34.180,0:00:36.219 JavaScript won't be a framework. 0:00:36.219,0:00:37.149 And the slightly less 0:00:37.149,0:00:40.280 provocative version of that title is, the[br]Rails of 0:00:40.280,0:00:43.769 JavaScript will be more than just a framework. 0:00:43.769,0:00:46.989 My name is Justin. We're not gonna have time 0:00:46.989,0:00:48.989 for questions afterwards. It's gonna be a[br]very, very 0:00:48.989,0:00:51.699 fast talk-y slide-decky thing. 0:00:51.699,0:00:53.229 So please Tweet me with 0:00:53.229,0:00:55.699 questions, feedback, praise is always 0:00:55.699,0:00:57.699 welcome, at searls, and 0:00:57.699,0:00:58.869 critical feedback is always welcome 0:00:58.869,0:00:59.879 at hello at testdouble 0:00:59.879,0:01:00.799 dot com. 0:01:00.799,0:01:04.828 Let's just talk about three of my favorite[br]things. 0:01:04.828,0:01:08.380 One is cupcakes. Two is the planet earth.[br]And 0:01:08.380,0:01:14.380 three is monolithic application architecture.[br]So, on cupcakes, say 0:01:14.380,0:01:17.670 that you own a bakery and a customer walks 0:01:17.670,0:01:20.390 in and they say they want something sweet.[br]So 0:01:20.390,0:01:23.090 you bake them up a beautiful cupcake, and[br]they 0:01:23.090,0:01:24.500 say hey, you know, this is really good but 0:01:24.500,0:01:26.740 I like a little bit more sweetness. Maybe[br]a 0:01:26.740,0:01:28.780 little crunch. So you put some sprinkles on[br]top. 0:01:28.780,0:01:31.220 The customer is, like, digging the cupcake,[br]but says 0:01:31.220,0:01:32.790 you know, on second thought, I really think[br]I 0:01:32.790,0:01:35.450 want something like with some hot fruit filling.[br]And 0:01:35.450,0:01:36.820 then you just think to yourself as the baker, 0:01:36.820,0:01:39.610 ah god damn it. What they really wanted was 0:01:39.610,0:01:41.560 a fresh-baked pie. 0:01:41.560,0:01:43.590 So you throw away the cupcake and you make 0:01:43.590,0:01:45.400 them a pie. And that's an honest mistake if 0:01:45.400,0:01:47.450 it happens once. But if your workflow as a 0:01:47.450,0:01:49.840 baker is to assume everyone needs a cupcake[br]only 0:01:49.840,0:01:51.840 to have to inevitably throw it away and then 0:01:51.840,0:01:54.729 bake something else, that's a real problem,[br]you know, 0:01:54.729,0:01:56.090 for your business. 0:01:56.090,0:01:59.610 So say you own a software studio, and a 0:01:59.610,0:02:01.619 customer walks in and says hey, I need a 0:02:01.619,0:02:03.250 web application, and so you say, oh great.[br]What's 0:02:03.250,0:02:09.179 its name so that I can type rails new. 0:02:09.179,0:02:10.799 And you build them a little graph, you know, 0:02:10.799,0:02:12.200 you render it on the server and they say, 0:02:12.200,0:02:13.920 hey, you know, this graph is great but I 0:02:13.920,0:02:16.480 need some zooms and some filters. And so you're 0:02:16.480,0:02:19.129 like, hey, you know, I, we can do that. 0:02:19.129,0:02:21.450 Sprinkle some JavaScript on top. And then[br]they say, 0:02:21.450,0:02:23.290 you know, this is awesome, but let's load[br]all 0:02:23.290,0:02:24.879 of the data all at once so that the 0:02:24.879,0:02:27.670 user can really, really like just see absolutely[br]everything 0:02:27.670,0:02:30.640 at a glance, really dynamically, like an app,[br]you 0:02:30.640,0:02:32.450 know? And then you, the developer, are like[br]ah, 0:02:32.450,0:02:35.530 god damn it. Cause there's no logical path[br]from 0:02:35.530,0:02:37.560 that solution to what they really wanted,[br]which was 0:02:37.560,0:02:39.120 a fat-client JavaScript application. 0:02:39.120,0:02:42.450 I mean, Rails is probably still involved,[br]providing API 0:02:42.450,0:02:45.250 services. But it's not the center of the application. 0:02:45.250,0:02:48.680 That monolithic approach doesn't work. And[br]it's an honest 0:02:48.680,0:02:51.209 mistake, if it happens once. But if part of 0:02:51.209,0:02:54.440 your workflow is to immediately assume that[br]Rails is 0:02:54.440,0:02:56.450 the solution to every single web application,[br]and then 0:02:56.450,0:02:58.440 you only realize later that you've guilt a[br]gigantic 0:02:58.440,0:03:01.910 mess with JavaScript, that's a problem. 0:03:01.910,0:03:03.370 The reason that I think that a lot of 0:03:03.370,0:03:05.270 web developers fall into this trap is that[br]Rails 0:03:05.270,0:03:09.530 is too convenient. When you're a Ruby developer,[br]you 0:03:09.530,0:03:12.470 have all these awesome tools right at your[br]disposal. 0:03:12.470,0:03:14.420 We've got this great convention-based framework[br]so I can 0:03:14.420,0:03:16.459 just add a gem and it, maybe a couple 0:03:16.459,0:03:18.150 lines, and then I get all this great behavior 0:03:18.150,0:03:20.730 on the cheap. And when we ask Ruby developers 0:03:20.730,0:03:22.750 about their favorite client-side tools, they[br]usually come up 0:03:22.750,0:03:28.480 empty. Nobody hates JavaScript more than Rubyists. 0:03:28.480,0:03:30.200 So they, they, they just can't think of any. 0:03:30.200,0:03:32.200 And of course it's not like there's no client-side 0:03:32.200,0:03:35.430 tools. I'm just kidding. There are plenty[br]of client-side 0:03:35.430,0:03:41.629 tools available to Rubyists. But this is their[br]reputation, 0:03:41.629,0:03:45.739 right. They're jagged and rusty and terrible.[br]So, every 0:03:45.739,0:03:47.390 time a new story comes down the pike, we 0:03:47.390,0:03:49.670 have to make a decision, right. Where's the[br]best 0:03:49.670,0:03:52.269 place for this to live? What's the concern[br]here. 0:03:52.269,0:03:54.909 If a user brings me a, a user interface 0:03:54.909,0:03:57.220 card, it might be that the best place to 0:03:57.220,0:03:58.450 write that, the best place for that to live 0:03:58.450,0:04:00.489 is in the browser. But the second thing I 0:04:00.489,0:04:02.060 ask when I get a new card is like 0:04:02.060,0:04:04.310 hey, where's, what'd be the easiest thing[br]for me 0:04:04.310,0:04:06.159 to actually do to build this? Take the least 0:04:06.159,0:04:08.400 time? Be the quickest to market? And because[br]Rails 0:04:08.400,0:04:11.799 is so convenient, the answer is often Rails.[br]So 0:04:11.799,0:04:13.450 even though the best place for the code to 0:04:13.450,0:04:16.529 live might be the frontend, I'm incentivised[br]to start 0:04:16.529,0:04:19.629 solving client-side problems on the server-side,[br]and taken to 0:04:19.629,0:04:21.779 an extreme that's really unhealthy. 0:04:21.779,0:04:25.470 So I have a provocative statement to make.[br]Non-Rubyists 0:04:25.470,0:04:28.870 write better JavaScript. I went to a dot NET 0:04:28.870,0:04:31.440 conference, my first dot NET conference, last[br]year in 0:04:31.440,0:04:35.020 Sophia, Bulgaria, and I was blown away by[br]how 0:04:35.020,0:04:37.110 much we were talking the same language. We[br]were 0:04:37.110,0:04:41.159 using great, brand new node.js based tooling.[br]Everyone was 0:04:41.159,0:04:45.139 talking about and excited about Angular, even[br]Ember. But 0:04:45.139,0:04:47.949 what my expectations were was it's dot NET,[br]this 0:04:47.949,0:04:50.259 is crusty, you know. And what I found in 0:04:50.259,0:04:52.930 actually talking to people was, because dot[br]net wasn't 0:04:52.930,0:04:56.949 so incredibly awesome, they didn't have that[br]same moral 0:04:56.949,0:04:59.180 hazard, you know. They were willing to solve[br]the 0:04:59.180,0:05:02.039 problem in the right place. 0:05:02.039,0:05:03.830 And when I think back over my own experience, 0:05:03.830,0:05:08.039 before Rails was easy, for me, whether that[br]was 0:05:08.039,0:05:10.240 before 2005 or when I was doing projects in 0:05:10.240,0:05:13.930 other tech stacks, JavaScript wasn't hard.[br]You know, I 0:05:13.930,0:05:16.669 actually really quite enjoyed JavaScript until[br]I was told, 0:05:16.669,0:05:18.369 you know, to hate it. 0:05:18.369,0:05:21.719 And granted, we can have a long discussion.[br]We 0:05:21.719,0:05:24.789 can have a lot, like, screencast here about[br]why, 0:05:24.789,0:05:26.889 is asking, is JavaScript a terrible language?[br]And I 0:05:26.889,0:05:33.199 would just like clear the air, right. Yes[br]definitely. 0:05:33.199,0:05:35.110 I spend most of my time in JavaScript. I 0:05:35.110,0:05:37.469 agree, it is terrible. But I'm careful not[br]to 0:05:37.469,0:05:41.360 conflate that with hey, well, is that why[br]writing 0:05:41.360,0:05:43.550 JavaScript is terrible? The problems I have[br]always had 0:05:43.550,0:05:45.589 with JavaScript have nothing to do with, have[br]nothing 0:05:45.589,0:05:47.719 to do with map and parsein and fundamental[br]problems 0:05:47.719,0:05:49.009 with the language, because I'm usually working[br]at a 0:05:49.009,0:05:50.149 higher level of abstraction, right. 0:05:50.149,0:05:52.339 The problems I have with JavaScript are all[br]of 0:05:52.339,0:05:56.080 the tooling. The ecosystem. The community.[br]So I, I 0:05:56.080,0:05:58.300 challenge you to ask again later if you think 0:05:58.300,0:06:02.180 the language is the one at fault. After this 0:06:02.180,0:06:03.849 talk, hopefully I'll be able to persuade you[br]a 0:06:03.849,0:06:04.869 little bit. 0:06:04.869,0:06:09.219 Let's talk about the planet earth. I love[br]Ruby 0:06:09.219,0:06:11.990 and I love Ruby mostly for the community.[br]I 0:06:11.990,0:06:14.199 love the language, but I love the community,[br]because 0:06:14.199,0:06:16.389 they changed the world when it comes to web 0:06:16.389,0:06:18.729 application development. If you were to chart[br]all of 0:06:18.729,0:06:20.409 the great new tools for the web that have 0:06:20.409,0:06:23.879 released over time, starting in 2005, the[br]fantastic gems 0:06:23.879,0:06:26.179 that were sort of the foundation for, for,[br]for 0:06:26.179,0:06:29.800 Ruby on Rails and this community. Over time,[br]haml, 0:06:29.800,0:06:33.089 sass, all of these great extensions. Alternate[br]stacks that 0:06:33.089,0:06:35.039 we can have an Omakase and a Prime stack. 0:06:35.039,0:06:38.490 Rspec. Cucumber. These great innovations,[br]helping us build better 0:06:38.490,0:06:41.619 web applications. The world, Ruby with gems[br]became this 0:06:41.619,0:06:44.550 mature market place of free stuff that would[br]help 0:06:44.550,0:06:46.129 us write better code. 0:06:46.129,0:06:49.369 But then, right around 2012, I started to[br]notice 0:06:49.369,0:06:51.729 that when a new feature would come out for, 0:06:51.729,0:06:54.659 like, say, webkit, it wasn't immediately followed[br]by gems 0:06:54.659,0:06:57.619 that would exploit it. Instead I was finding[br]JavaScript 0:06:57.619,0:07:01.830 tooling written in JavaScript on node. And[br]that started 0:07:01.830,0:07:03.749 popping up, and in 2013 it really seemed to 0:07:03.749,0:07:06.089 take off. And you come into 2014 and a 0:07:06.089,0:07:08.349 lot of Rubyists, I think, have this latent[br]fear 0:07:08.349,0:07:13.129 that JavaScript is gonna devour planet earth.[br]And I'm 0:07:13.129,0:07:16.580 here to tell you that it probably will. 0:07:16.580,0:07:18.009 Where the best tools? If you were to ask 0:07:18.009,0:07:19.469 yourself this, you can add up a, add up 0:07:19.469,0:07:22.050 a bunch of fact values. For example, Ruby's[br]tool 0:07:22.050,0:07:24.860 ecosystem, it's mature but it's crowded. That's[br]not a 0:07:24.860,0:07:26.979 lot of room for growth because everyone already[br]has 0:07:26.979,0:07:28.839 a lot of tools available that they, that they 0:07:28.839,0:07:34.199 love. But node's ecosystem, it's immature,[br]right. It's innovative, 0:07:34.199,0:07:36.629 because so much new stuff gets pushed up,[br]and 0:07:36.629,0:07:40.089 it's frustrating, but it's great, because[br]as soon as 0:07:40.089,0:07:41.449 a new feature hits a browser, there's a tool 0:07:41.449,0:07:43.240 to exploit it. I mean, granted, I get as 0:07:43.240,0:07:44.839 frustrated as anybody else that when I run[br]MPM 0:07:44.839,0:07:47.399 install on something, like, by the time the[br]install 0:07:47.399,0:07:49.669 finally finishes at least two of those dependencies[br]have 0:07:49.669,0:07:53.059 probably had updates pushed. 0:07:53.059,0:07:55.279 But that's the fantastic, that's what I loved[br]about 0:07:55.279,0:07:59.559 Ruby in 2006 and 2007. And tool authors are 0:07:59.559,0:08:01.110 not immune to trends. I read a lot of, 0:08:01.110,0:08:02.520 like, open source tools and I want to go 0:08:02.520,0:08:04.509 where the people are. I want to go where 0:08:04.509,0:08:06.809 I'm gonna have a big impact. And so tool 0:08:06.809,0:08:09.389 authors are now gravitating to, to the world[br]of 0:08:09.389,0:08:11.300 JavaScript, because the universe of people[br]who have to 0:08:11.300,0:08:14.039 deal with JavaScript is about seven billion[br]people, and 0:08:14.039,0:08:15.119 the universe of people who have to deal with 0:08:15.119,0:08:18.469 Ruby is in the tens of thousands. 0:08:18.469,0:08:21.550 Yeah. All seven billion are JavaScript developers.[br]I realize 0:08:21.550,0:08:22.349 that's flawed. 0:08:22.349,0:08:26.879 Also, tools, they address the problems of[br]their day. 0:08:26.879,0:08:29.239 A gem that was written in 2008 was written 0:08:29.239,0:08:32.299 to solve problems that person was facing in[br]2008. 0:08:32.299,0:08:35.208 Not 2014. A tool that was written in 2014 0:08:35.208,0:08:36.950 surely must be useful in 2014, and so it's 0:08:36.950,0:08:38.750 just a better fit for the web as it 0:08:38.750,0:08:41.010 exists today. You add all that up and I, 0:08:41.010,0:08:42.510 you know, I really believe that web tools[br]in 0:08:42.510,0:08:46.480 node tend to better solve today's problems. 0:08:46.480,0:08:48.850 And this is maddening for those who insist[br]on 0:08:48.850,0:08:52.110 only using Rails for absolutely everything.[br]But, hey, speaking 0:08:52.110,0:08:57.100 of Rails, let's talk about monolithic application[br]architecture. 0:08:57.100,0:08:59.360 Rails won the war, right, on web application[br]frameworks. 0:08:59.360,0:09:01.300 It came in with a whole bunch of great 0:09:01.300,0:09:03.670 reasons that we can go into later about why 0:09:03.670,0:09:05.490 it was just the best. It was, it was 0:09:05.490,0:09:08.540 fantastic, and all of these frameworks since[br]then have 0:09:08.540,0:09:11.230 adopted a ton of great ideas from Rails. But 0:09:11.230,0:09:13.540 what we don't often think about when we consider 0:09:13.540,0:09:16.550 that phenomenon is to ask ourselves, which[br]war did 0:09:16.550,0:09:20.790 Rails win? All web applications? Like, generally?[br]Or is 0:09:20.790,0:09:23.060 there some sub-set of applications for the[br]web that 0:09:23.060,0:09:25.180 are a better fit for Rails than others? 0:09:25.180,0:09:28.040 DHH last year at RailsConf said that good[br]frameworks 0:09:28.040,0:09:31.879 are extractions, not inventions. Extracted[br]from real applications and 0:09:31.879,0:09:35.170 not just invented. And so when you look at 0:09:35.170,0:09:37.930 Rails, obviously the story is that the company[br]Basecamp 0:09:37.930,0:09:40.670 made Basecamp and they extracted the good[br]bits, the 0:09:40.670,0:09:42.110 common bits that they were seeing across a[br]lot 0:09:42.110,0:09:45.610 of their projects into Ruby on Rails. 0:09:45.610,0:09:47.060 And those kinds of bits that are common to 0:09:47.060,0:09:51.399 many of us, almost all web applications: url[br]routing, 0:09:51.399,0:09:54.579 to point you to custom actions that you write. 0:09:54.579,0:09:57.490 Modeling behavior of, of the models in your[br]objects, 0:09:57.490,0:09:59.269 the validations and all of that at a fundamental 0:09:59.269,0:10:03.100 level. Persistence. Storing stuff in a database,[br]querying for 0:10:03.100,0:10:07.480 the stuff. The relationships between stuff.[br]Session management and, 0:10:07.480,0:10:08.920 in a way that's abstracted from where the[br]session 0:10:08.920,0:10:11.540 stuff was stored was hugely convenient, obviously.[br]All of 0:10:11.540,0:10:13.230 those ancillary concerns of the wheels that[br]you don't 0:10:13.230,0:10:16.209 want to reinvent like mailers. And then there's[br]this 0:10:16.209,0:10:19.019 last little bit that's like all these JavaScript[br]alternatives. 0:10:19.019,0:10:21.560 Like there's sort of like the, the means by 0:10:21.560,0:10:24.290 which to sprinkle JavaScript on top. Like,[br]AJAX erb 0:10:24.290,0:10:26.689 tags that dump a whole bunch of JavaScript[br]into 0:10:26.689,0:10:29.839 your on-click handlers in your, in your markup,[br]or 0:10:29.839,0:10:33.670 later on r.js, or later on unintrusive AJAX[br]erb 0:10:33.670,0:10:37.889 tags. Or later on, turbolinks, right. It's[br]not that 0:10:37.889,0:10:40.629 those are bad, that those alternatives are[br]bad tools. 0:10:40.629,0:10:43.129 It's that they're there to solve, they've[br]been abstracted 0:10:43.129,0:10:46.439 from an application that just didn't have[br]the problem 0:10:46.439,0:10:48.980 of trying to solve and, and write JavaScript[br]in 0:10:48.980,0:10:51.000 the way that I want to write JavaScript. 0:10:51.000,0:10:53.300 Because if you consider Basecamp, you start[br]a page. 0:10:53.300,0:10:55.029 It's a traditional web workflow. You start[br]on a 0:10:55.029,0:10:56.180 page, you click on a thing, you get another 0:10:56.180,0:10:57.430 page, you click on a thing, you get another 0:10:57.430,0:11:00.290 page. It's a, it's a multi-break process,[br]and that 0:11:00.290,0:11:03.000 represents a huge proportion of the web. And[br]that 0:11:03.000,0:11:05.180 percentage of the web was almost 100% in 2005 0:11:05.180,0:11:07.509 but it's much lower now. If your app isn't 0:11:07.509,0:11:09.490 a one to one mapping of, like, CRUD in 0:11:09.490,0:11:11.139 the database and you're just exposing that[br]as an 0:11:11.139,0:11:13.670 interface to users, if there's any layer of[br]indirection 0:11:13.670,0:11:16.189 you, it might not be a good fit. 0:11:16.189,0:11:21.629 Yesterday, Sandi Metz made the comment, as[br]an aside, 0:11:21.629,0:11:22.959 that there are Rails apps and then there are 0:11:22.959,0:11:26.040 apps that use Rails. I'm finding that more[br]and 0:11:26.040,0:11:27.639 more, the apps that I'm writing are apps that 0:11:27.639,0:11:30.240 use Rails. I can love Rails and not necessarily 0:11:30.240,0:11:31.839 take advantage or, or really find a lot of 0:11:31.839,0:11:35.959 benefit from the front-end aspects. 0:11:35.959,0:11:39.550 So Rails promotes an html user interface in[br]the 0:11:39.550,0:11:42.699 frontend, cause that's what Basecamp needed.[br]And what I 0:11:42.699,0:11:43.579 mean when I say that is you're writing stuff 0:11:43.579,0:11:45.939 like html markup. I have an anchor tag here 0:11:45.939,0:11:48.120 with a, with a ref and, and content, or 0:11:48.120,0:11:50.160 I might have a form action here with, you 0:11:50.160,0:11:53.420 know, an input submit, and when you're writing[br]html 0:11:53.420,0:11:55.819 like this, it feels like you're making the[br]UI. 0:11:55.819,0:11:58.209 But you're not writing, like, UI programming.[br]What this 0:11:58.209,0:12:00.850 is is this is the specification of a UI. 0:12:00.850,0:12:02.699 The user agent, the browser, is the thing[br]responsible 0:12:02.699,0:12:04.250 for figuring out how to render a link and 0:12:04.250,0:12:06.180 what to do when you click it. It's how 0:12:06.180,0:12:07.970 to render and what to do when, you know, 0:12:07.970,0:12:09.540 how to paint a button and so forth. 0:12:09.540,0:12:13.069 It's, you're not, you're kind of outsourcing[br]the UI 0:12:13.069,0:12:15.550 programming. If you're building an application[br]with the browser 0:12:15.550,0:12:17.139 as your runtime, though, I'd call that a JavaScript 0:12:17.139,0:12:19.699 UI, and fundamentally the activity is just[br]different and 0:12:19.699,0:12:22.649 more complex. You know, you're responsible[br]for finding the 0:12:22.649,0:12:24.230 point and the DOM where you want to render 0:12:24.230,0:12:27.129 stuff into. Or you're responsible for binding[br]to an 0:12:27.129,0:12:29.220 event that the user does something, and then[br]you 0:12:29.220,0:12:31.360 need to take some custom action. You're the[br]one 0:12:31.360,0:12:34.899 in the driver's seat. They're fundamentally[br]different concerns. 0:12:34.899,0:12:39.029 But our tools, I think, file, I like tree, 0:12:39.029,0:12:40.889 to tree stuff out, because I think that tools 0:12:40.889,0:12:44.350 tend to betray their biases based on the layout 0:12:44.350,0:12:46.399 of the files that they give us. You know, 0:12:46.399,0:12:47.870 a naive Rails app might look like this, and 0:12:47.870,0:12:51.529 it screams MVC and it screams server-side.[br]But, of 0:12:51.529,0:12:54.279 course, in reality, one of the kind of, like, 0:12:54.279,0:12:57.079 you know, dust-bin corners is that we have[br]this, 0:12:57.079,0:13:00.829 this ghetto, right, under assets, and then[br]the most, 0:13:00.829,0:13:06.170 you know, unfortunately named directory ever,[br]javascripts, and then 0:13:06.170,0:13:08.089 application.js, and it's telling us, all this[br]stuff at 0:13:08.089,0:13:09.870 the top - this matters. And this thing at 0:13:09.870,0:13:12.189 the bottom, just write one big long bowl of 0:13:12.189,0:13:13.970 spaghetti, and it'll work out. And that's[br]how a 0:13:13.970,0:13:16.060 lot of people write, you know, JavaScript[br]and Rails 0:13:16.060,0:13:18.240 applications, still. 0:13:18.240,0:13:19.720 Some people, though, that's not good enough,[br]and so 0:13:19.720,0:13:22.370 they, they, they realize that they need to[br]write 0:13:22.370,0:13:24.079 more structured JavaScript, and so we end[br]up with 0:13:24.079,0:13:26.560 this new thing, like an html UI and a, 0:13:26.560,0:13:28.610 and a JavaScript UI combined. And you might[br]notice 0:13:28.610,0:13:32.350 a pattern here, right. There is a, a, an 0:13:32.350,0:13:34.470 MVC in the back, and then it's also MVC 0:13:34.470,0:13:37.680 in the front. It makes command T really difficult, 0:13:37.680,0:13:41.279 but it, you know, we see this duplication[br]of 0:13:41.279,0:13:44.939 backend concerns and frontend concerns, and[br]there's also this, 0:13:44.939,0:13:49.069 this little nit, negging doubt about, do we[br]really 0:13:49.069,0:13:50.439 need this views here? Right, if we're building[br]a 0:13:50.439,0:13:54.399 full-blown fat-client JavaScript application,[br]the backend views that Rails 0:13:54.399,0:13:56.499 provides just are less useful. So those often[br]get 0:13:56.499,0:13:59.079 cut out now, and we, we just have sort 0:13:59.079,0:14:01.149 of a JSON API in Rails, and then this 0:14:01.149,0:14:03.180 deeply-nested JavaScript UI. 0:14:03.180,0:14:04.149 And so at this point, if like a new 0:14:04.149,0:14:05.920 person comes to your project and they ask,[br]hey, 0:14:05.920,0:14:08.829 so what exactly is that thing? Right. I would 0:14:08.829,0:14:12.430 call that a vestigial appendage. Because it[br]can only 0:14:12.430,0:14:14.930 be explained in terms of the past. You have 0:14:14.930,0:14:17.129 to pull up your, you know, your forensics[br]of 0:14:17.129,0:14:18.829 like, well, in 2008 we were all, you know, 0:14:18.829,0:14:21.519 thinking this and now it's still like this. 0:14:21.519,0:14:24.170 What's wrong with that vestigial appendage?[br]Well, what's fundamentally 0:14:24.170,0:14:28.249 wrong is that, a fundamental problem in, in[br]programming, 0:14:28.249,0:14:30.149 is that when we move way faster when we 0:14:30.149,0:14:31.579 can fit the whole application in our head[br]at 0:14:31.579,0:14:33.920 once, and when, on day one of any project, 0:14:33.920,0:14:35.040 you can fit the whole thing in your head 0:14:35.040,0:14:36.759 at once. But on day 1000 of the project 0:14:36.759,0:14:38.360 that's probably not gonna be true. 0:14:38.360,0:14:39.999 So if you build a monolithic thing up front, 0:14:39.999,0:14:41.730 as that app gets bigger, eventually you reach[br]a 0:14:41.730,0:14:42.809 point where you can't fit it all in your 0:14:42.809,0:14:46.170 head and you start to page, right. Part of 0:14:46.170,0:14:47.709 the application that you're working in you[br]can think 0:14:47.709,0:14:49.620 of, and then over here you sort of page 0:14:49.620,0:14:52.430 out. And if you don't modularize things well,[br]then 0:14:52.430,0:14:55.309 that, that, that thrashing is really, really[br]risky. Because 0:14:55.309,0:14:56.699 it might mean that, like, I'm in this part 0:14:56.699,0:14:57.699 of the app, and I just kind of have 0:14:57.699,0:15:00.209 to hope that my tests are gonna cover me. 0:15:00.209,0:15:01.870 Although by the time you're this big, your[br]tests 0:15:01.870,0:15:03.670 in a typical Rails app are like ten hours 0:15:03.670,0:15:05.660 long. So maybe tomorrow you can find out that 0:15:05.660,0:15:07.509 it worked. 0:15:07.509,0:15:10.139 But if you, via common concerns, and find[br]a 0:15:10.139,0:15:14.309 good module point to, to separate on, if you 0:15:14.309,0:15:15.790 were to identify that you could have, like,[br]a 0:15:15.790,0:15:17.779 frontend app and a backend app, as those two 0:15:17.779,0:15:20.930 things grew, even if the net complexity is[br]higher, 0:15:20.930,0:15:22.249 at some point they're not gonna fit in your 0:15:22.249,0:15:26.279 head either, but the paging story is much[br]nicer. 0:15:26.279,0:15:29.209 Because they have a clean, well-defined separate[br]contract. So 0:15:29.209,0:15:32.660 the application that you're working in the[br]backend application, 0:15:32.660,0:15:33.839 if you have to work in it, you can 0:15:33.839,0:15:35.689 work in it, and then when you page out, 0:15:35.689,0:15:38.189 it's not thrashing, cause there's a clear,[br]understood contract 0:15:38.189,0:15:40.620 between the two. 0:15:40.620,0:15:43.490 Relatedly, I like to say that late extraction[br]costs 0:15:43.490,0:15:46.089 more than early abstraction. Yesterday, Sandi's[br]talk was great 0:15:46.089,0:15:49.009 at telling us about wrong abstractions that[br]have been 0:15:49.009,0:15:51.100 found and refactoring away from those, but[br]when we've 0:15:51.100,0:15:54.209 seen the same project a dozen different times,[br]I 0:15:54.209,0:16:00.459 would much rather extract seldom and, and,[br]and abstract 0:16:00.459,0:16:02.319 early, and that's really confusing sounded[br]so I'm gonna 0:16:02.319,0:16:03.860 talk about yarn now. 0:16:03.860,0:16:07.550 Imagine you have two balls of yarn. If you 0:16:07.550,0:16:09.220 decided, like, man, I really just wish instead[br]of 0:16:09.220,0:16:10.910 these two ugly balls of yarn, I had a 0:16:10.910,0:16:13.619 big know of yarn all tangled together, that's[br]really 0:16:13.619,0:16:15.759 easy to do, thanks to the basic laws of 0:16:15.759,0:16:18.220 entropy. But if I have a big tangled know 0:16:18.220,0:16:20.410 of yarn and decide that I really would love 0:16:20.410,0:16:23.730 two nicely-balled, you know, nice balls of[br]yarn, turns 0:16:23.730,0:16:26.999 out that's very, very difficult to do. That[br]doesn't 0:16:26.999,0:16:27.899 work. 0:16:27.899,0:16:29.170 So that's why, what I mean when I say 0:16:29.170,0:16:32.249 that late abstraction, all of these, like,[br]fancy refactorings 0:16:32.249,0:16:34.439 that we can do, cost a lot more than 0:16:34.439,0:16:36.110 just knowing you needed two things in the[br]first 0:16:36.110,0:16:40.249 place. So, back to this, this two step that 0:16:40.249,0:16:41.660 I see in a lot of Rails applications, where 0:16:41.660,0:16:43.089 one project, you've got the JSON API but you 0:16:43.089,0:16:46.339 also have all the JavaScript. This isn't problematic[br]until 0:16:46.339,0:16:49.800 you consider this kind of stuff. You, you[br]have 0:16:49.800,0:16:51.860 a template that renders a script tag at the 0:16:51.860,0:16:54.709 top, and then in the erb certain bits of 0:16:54.709,0:16:57.709 data are kind of taking this sneaky back door 0:16:57.709,0:17:00.569 instead of actually using the, the proper[br]API, to 0:17:00.569,0:17:03.709 just dump data into the JavaScript application[br]needs. When 0:17:03.709,0:17:05.630 you see this, it really means your yarn is 0:17:05.630,0:17:08.020 tangled, right. Even though you think you[br]have separate 0:17:08.020,0:17:10.240 things. And your API is a lie. Because it 0:17:10.240,0:17:12.140 means that even though your application is[br]mostly using 0:17:12.140,0:17:13.609 that API, if somebody were to come and say, 0:17:13.609,0:17:14.619 hey, I want to build a mobile app for 0:17:14.619,0:17:16.329 your site, they're gonna have to spend a month 0:17:16.329,0:17:20.619 figuring out how to get that token, right. 0:17:20.619,0:17:23.279 But it's hard not to cheat. And I agree. 0:17:23.279,0:17:25.260 It's very, very difficult, especially given[br]what we talked 0:17:25.260,0:17:27.619 about earlier, where the tooling is so bad.[br]So 0:17:27.619,0:17:29.230 my objective in the last four years of, of, 0:17:29.230,0:17:31.940 of my, my open source contributions, and now[br]at 0:17:31.940,0:17:34.880 TestDouble, where we spend a lot of our time? 0:17:34.880,0:17:37.760 We want to help make JavaScript apps easy.[br]As 0:17:37.760,0:17:39.049 easy as Rails. 0:17:39.049,0:17:41.960 When you think about Rails and the responsibilities[br]of 0:17:41.960,0:17:45.649 Rails, there's really three distinct parts.[br]We have an 0:17:45.649,0:17:47.890 application framework. Stuff that we extend[br]- ActionController and 0:17:47.890,0:17:51.200 so forth. We have conventions and configurations[br]that are 0:17:51.200,0:17:52.870 laid out for us, that we learn through the 0:17:52.870,0:17:56.370 community and the documentation. And we have[br]build automation 0:17:56.370,0:18:00.520 stuff, like Rails CLI and Rake. And Rails[br]owns 0:18:00.520,0:18:01.610 the whole stack. 0:18:01.610,0:18:04.049 If I had to grade them separately, I'd say 0:18:04.049,0:18:06.250 that Rails as an application framework - when[br]I 0:18:06.250,0:18:07.760 first found it, I loved it. But I found 0:18:07.760,0:18:09.899 on, like, many year, five year, six year projects, 0:18:09.899,0:18:12.090 it encourages a lot of things that problematic.[br]So 0:18:12.090,0:18:14.039 maybe I'd give that a B minus, if I 0:18:14.039,0:18:16.659 was grading it separately. But the conventions[br]and configurations, 0:18:16.659,0:18:18.190 that's awesome. I love that I can hit a 0:18:18.190,0:18:20.770 new Rails team's project and, because of the[br]tribal 0:18:20.770,0:18:22.270 knowledge that we have as well as the conventions 0:18:22.270,0:18:24.250 laid out and the sensible defaults, I can[br]see 0:18:24.250,0:18:26.169 how is their app different from the norm really 0:18:26.169,0:18:27.580 easily. 0:18:27.580,0:18:29.640 Build automation stuff is pretty good. I think[br]it's 0:18:29.640,0:18:32.470 gotten a little bit stagnant. Fantastic in[br]2005 and 0:18:32.470,0:18:33.830 I haven't seen a lot of really cool stuff 0:18:33.830,0:18:37.350 lately. But it's still solid. What I really[br]want 0:18:37.350,0:18:39.520 to talk about today is convention and configuration[br]and 0:18:39.520,0:18:41.220 the value that that can bring to our JavaScript 0:18:41.220,0:18:43.630 tooling. Also keep in mind that a lot of 0:18:43.630,0:18:45.130 people that are new in Rails or have only 0:18:45.130,0:18:47.350 ever worked in Rails just see one big things. 0:18:47.350,0:18:49.390 They don't see these as separate problems.[br]So if 0:18:49.390,0:18:52.220 that's you, try to think about these responsibilities[br]separately, 0:18:52.220,0:18:53.559 because I think they can be solved by separate 0:18:53.559,0:18:54.370 tools. 0:18:54.370,0:18:57.659 For example, in JavaScript, application frameworks[br]are everywhere. If 0:18:57.659,0:18:59.480 I decided I wanted to solve that middle problem 0:18:59.480,0:19:02.140 by writing another application framework,[br]then I'd have to, 0:19:02.140,0:19:04.070 you know, go and popularize it against all[br]the 0:19:04.070,0:19:06.120 other application frameworks. I think that[br]they can be 0:19:06.120,0:19:08.809 separated. You know, whether I'm writing backbone[br]or Angular 0:19:08.809,0:19:10.520 or Ember - lately I've been writing a lot 0:19:10.520,0:19:12.929 of Ember and I love it. But every six 0:19:12.929,0:19:15.220 months I keep changing my mind. It's a fact. 0:19:15.220,0:19:16.860 So, so at this point I just wanna be 0:19:16.860,0:19:19.010 like, eh, I want to write awesome tools that 0:19:19.010,0:19:21.399 are framework agnostic that anybody can, can[br]exploit. 0:19:21.399,0:19:25.500 From the build automation perspective, like[br]I said, the 0:19:25.500,0:19:28.590 community is already in node.js. Worldwide.[br]As soon as 0:19:28.590,0:19:30.850 stuff is happening, great tools are showing[br]up in 0:19:30.850,0:19:33.690 node.js first. I just want to be this little 0:19:33.690,0:19:35.090 guy in the middle, right. I want to be 0:19:35.090,0:19:36.590 the convention and the configuration, right.[br]And that's why 0:19:36.590,0:19:38.460 we built lineman. 0:19:38.460,0:19:42.909 Lineman, like a, like a lineman on a railroad, 0:19:42.909,0:19:45.370 is on Twitter here, and you can find his 0:19:45.370,0:19:47.659 url. And you install him with npm. So you 0:19:47.659,0:19:49.010 have node.js install and you can just say[br]npm 0:19:49.010,0:19:51.870 install globally lineman, and you create a[br]new app 0:19:51.870,0:19:53.890 really easily with the cli, just like Rails.[br]Lineman 0:19:53.890,0:19:55.710 new app. 0:19:55.710,0:20:00.480 So, here's me typing in lineman new, start[br]a 0:20:00.480,0:20:02.059 new project, and I get a little. I get 0:20:02.059,0:20:05.169 a handful of commands that I can run. But 0:20:05.169,0:20:08.059 first I'm just gonna cd in and I'm gonna 0:20:08.059,0:20:11.130 tree out all of the files that I have. 0:20:11.130,0:20:12.669 Like I said, it betrays the biases, right.[br]One 0:20:12.669,0:20:14.679 way to learn the conventions is see what it 0:20:14.679,0:20:16.529 generates. So you can see I have an app 0:20:16.529,0:20:19.120 directory with css and images and JavaScript[br]and then 0:20:19.120,0:20:20.880 pages that render on the backend and templates[br]on 0:20:20.880,0:20:23.720 the front. A handful of configuration files.[br]A whole 0:20:23.720,0:20:25.929 bunch of spec helpers to help you test. And 0:20:25.929,0:20:30.690 then places for all of your vendored third-party[br]libraries. 0:20:30.690,0:20:32.720 And it's convenient, right. It's nice to get[br]that 0:20:32.720,0:20:34.820 bootstrap for you. But our goal is to make 0:20:34.820,0:20:36.990 it convenient throughout, to switch between[br]projects to reduce 0:20:36.990,0:20:39.500 duplication to make things more common across[br]all of 0:20:39.500,0:20:41.890 our work. 0:20:41.890,0:20:44.740 One aspect of that is our productivity workflow.[br]I 0:20:44.740,0:20:46.500 want to be able to write some code, save 0:20:46.500,0:20:48.880 the code, have that code automatically compile[br]for me 0:20:48.880,0:20:51.429 every time I save. Have it concatenate every[br]time 0:20:51.429,0:20:53.019 that I save, and then I want to be 0:20:53.019,0:20:54.840 able to hit command r and refresh and play 0:20:54.840,0:20:56.330 with it. But I want to be able to 0:20:56.330,0:20:57.559 do all of that in less than a hundred 0:20:57.559,0:20:59.250 milliseconds, because I want a fast feedback[br]loop so 0:20:59.250,0:21:01.080 that I can keep working quickly. 0:21:01.080,0:21:02.490 In lineman, we do this with a command called 0:21:02.490,0:21:04.649 lineman run. So you say lineman run, it does 0:21:04.649,0:21:06.669 a whole bunch of initial build stuff, but[br]then 0:21:06.669,0:21:08.230 it just starts watching for file changes.[br]So I 0:21:08.230,0:21:10.899 can hit this server, the dev server. It says 0:21:10.899,0:21:13.600 Hello, World! I'm gonna make a quick changes,[br]say 0:21:13.600,0:21:16.740 Goodbye, World! It's already updated. I refresh[br]the page 0:21:16.740,0:21:17.570 and that's that. 0:21:17.570,0:21:19.630 Now, this is a simple app, but even on 0:21:19.630,0:21:22.220 large apps it scales very well. On our large 0:21:22.220,0:21:26.289 applications it's still roughly a hundred[br]milliseconds. 0:21:26.289,0:21:30.760 So, this is great. But command-r driven development[br]isn't 0:21:30.760,0:21:32.640 the whole story, right. I also like to write 0:21:32.640,0:21:35.490 tests, too. Sometimes I'm doing test-driven[br]development. When I 0:21:35.490,0:21:39.049 do, I also want the same story to slot 0:21:39.049,0:21:41.690 in really nicely with, with tests. And I want 0:21:41.690,0:21:44.890 the same feedback cycle to be super duper[br]fast. 0:21:44.890,0:21:47.600 Lineman ships with a cool tool called testem,[br]written 0:21:47.600,0:21:49.960 by Toby Ho, that's really fantastic. What[br]you do 0:21:49.960,0:21:51.779 is you open up another shell, a second shell, 0:21:51.779,0:21:53.649 and you run lineman spec. And you get this 0:21:53.649,0:21:58.350 interactive test runner, launches Chrome here,[br]and here I'm 0:21:58.350,0:22:01.880 running a test already. Gonna just change[br]the spec 0:22:01.880,0:22:04.470 to say that I'm specifying that that function[br]returned 0:22:04.470,0:22:05.730 Goodbye, World! 0:22:05.730,0:22:09.950 Save it off. Got a failure. That quickly.[br]I 0:22:09.950,0:22:12.110 can debug cause it's in the browser. I'm just 0:22:12.110,0:22:14.690 gonna fix it. Save. And that's it. My tests 0:22:14.690,0:22:17.399 are passing. In addition to the interactive[br]runner, we 0:22:17.399,0:22:19.500 want a really solid CI story. So you just 0:22:19.500,0:22:21.659 quit out of testem with the q key, and 0:22:21.659,0:22:24.090 you can type lineman spec ci, and this is 0:22:24.090,0:22:26.950 gonna run it all in phantom.js with a nice 0:22:26.950,0:22:31.070 reporter output. And every lineman project[br]generates a travis.yml 0:22:31.070,0:22:32.960 file when you lineman new. So you literally[br]just 0:22:32.960,0:22:34.740 push it to GitHub, and if you use Travis 0:22:34.740,0:22:37.019 as your CI service, it's a one button thing 0:22:37.019,0:22:38.309 and now you have a CI build for your 0:22:38.309,0:22:41.370 JavaScript. Which if we were to ask people[br]to 0:22:41.370,0:22:43.059 raise hands, I don't think every hand would[br]go 0:22:43.059,0:22:46.710 up if, if I asked if you have one. 0:22:46.710,0:22:48.950 The deploy story is similar easy, because[br]since lineman 0:22:48.950,0:22:51.880 is just a static asset generating tool, can[br]your 0:22:51.880,0:22:54.750 server host static files? Then yeah, you're[br]good. When 0:22:54.750,0:22:56.880 you write a lineman build, and then you tree 0:22:56.880,0:22:59.010 out its dist directory, which is where it[br]puts 0:22:59.010,0:23:00.970 its built artifacts, it looks a little like[br]this 0:23:00.970,0:23:02.840 out of the box. You have an html file 0:23:02.840,0:23:05.000 that references a css file and a JavaScript[br]file 0:23:05.000,0:23:06.390 and both of those have already been concatted[br]and 0:23:06.390,0:23:08.720 minified for you and they're ready to deploy. 0:23:08.720,0:23:10.200 There's a single flag in the config that you 0:23:10.200,0:23:12.000 can set, and then just like Rails, you get 0:23:12.000,0:23:13.970 asset fingerprinted that makes it really nice[br]for deploying 0:23:13.970,0:23:16.840 when you have a CDN. Everything else that[br]ever 0:23:16.840,0:23:18.220 is gonna end up in your dist directory is 0:23:18.220,0:23:20.130 gonna be stuff that you added, so it'll be 0:23:20.130,0:23:23.070 stuff that you understand. It's a really easy[br]build 0:23:23.070,0:23:25.130 story. 0:23:25.130,0:23:27.130 Pushing to Heroku is also really easy. We[br]host 0:23:27.130,0:23:29.700 most of our testable stuff on Heroku, so we 0:23:29.700,0:23:32.260 just set, we wrote a custom buildpack. You[br]set 0:23:32.260,0:23:34.390 that up and then you say git push. It'll 0:23:34.390,0:23:36.679 build it with node.js, but then at runtime[br]we 0:23:36.679,0:23:38.299 don't need it and so it just runs statically 0:23:38.299,0:23:41.690 without node. 0:23:41.690,0:23:42.570 And we also have a whole bunch of starter 0:23:42.570,0:23:45.210 projects to help get people up and running[br]quickly. 0:23:45.210,0:23:48.269 Not everyone's just writing vanilla JavaScript,[br]right. We have 0:23:48.269,0:23:49.909 some people who want to get started with Angular 0:23:49.909,0:23:53.919 quickly, Backbone or Ember. You can just clone[br]and 0:23:53.919,0:23:55.710 go. Clone the project and get started. You'll[br]have 0:23:55.710,0:23:57.380 a little bit of example code. It's a great 0:23:57.380,0:23:59.230 way, if you want to learn Angular or learn 0:23:59.230,0:24:01.340 Ember, just to clone our example project,[br]because it'll 0:24:01.340,0:24:03.070 build right away. Like, you already know how[br]to 0:24:03.070,0:24:04.309 run it. 0:24:04.309,0:24:07.179 We also have a, a really cool. It's because 0:24:07.179,0:24:08.490 it's all flexible, we also use lineman to[br]build 0:24:08.490,0:24:12.210 all of our JavaScript libs, libs that we maintain, 0:24:12.210,0:24:14.110 as well as our blog and, and you're free 0:24:14.110,0:24:16.260 to use lineman, of course, to, to write a 0:24:16.260,0:24:18.639 markdown blog. It's really, really convenient. 0:24:18.639,0:24:23.549 So back to planet earth. We're using Grunt.[br]We, 0:24:23.549,0:24:26.760 Grunt is a build tool descended from, you[br]know, 0:24:26.760,0:24:29.899 a whole bunch of other build tools, that is 0:24:29.899,0:24:31.940 used for task definition. There's a lot of[br]different, 0:24:31.940,0:24:33.340 there's a lot of competition here right now[br]in 0:24:33.340,0:24:35.380 node.js. A lot of people using Gulp. A thing 0:24:35.380,0:24:38.019 called Broccoli came out recently. It's really[br]cool. But 0:24:38.019,0:24:40.630 what we use Grunt for, primarily, is a place 0:24:40.630,0:24:43.500 to get awesome stuff from the community. 0:24:43.500,0:24:46.289 All these tasks ship with lineman out of the 0:24:46.289,0:24:48.389 box. Or are, and, and so many more are 0:24:48.389,0:24:52.399 available. We really, really love that we're[br]able to 0:24:52.399,0:24:56.510 so easily pull in new behavior through Grunt[br]in 0:24:56.510,0:25:01.380 a consistent manner. Lineman itself is comically[br]extensible. We 0:25:01.380,0:25:03.350 have a plugin system that is built a little 0:25:03.350,0:25:06.240 bit around this mental model. We'll talk about[br]it 0:25:06.240,0:25:08.750 in a second. But it's really easy from a 0:25:08.750,0:25:12.029 user's perspective. All you do is save it.[br]npm 0:25:12.029,0:25:15.600 install, then you save the, save the dependency.[br]Run, 0:25:15.600,0:25:18.590 like, lineman-bower. When you do that, after[br]you run 0:25:18.590,0:25:20.620 lineman run, the next time after you save[br]that, 0:25:20.620,0:25:22.240 lineman will pick it up from your packaged[br]JSON, 0:25:22.240,0:25:24.000 know that it needs to load it, and bower 0:25:24.000,0:25:25.940 will be slotted in at the appropriate step[br]into 0:25:25.940,0:25:28.730 your build's workflow. No more configuration.[br]It even generates 0:25:28.730,0:25:30.080 your bower JSON for you if it's not there. 0:25:30.080,0:25:33.860 Cause deep down, there is an npm module out 0:25:33.860,0:25:37.309 there, bower, right, published by Twitter,[br]and around it 0:25:37.309,0:25:39.950 is the, a, a grunt-bower-task that somebody[br]in the 0:25:39.950,0:25:42.100 community published, and then at the top we[br]have 0:25:42.100,0:25:45.480 this lineman-bower plugin that we maintain.[br]Bower is the 0:25:45.480,0:25:47.210 thing that actually does the thing. That's[br]where most 0:25:47.210,0:25:48.370 of the hard work is. 0:25:48.370,0:25:52.340 This, this power-task here, from Grunt, it[br]automates the 0:25:52.340,0:25:54.820 thing. There's a lot of hard work there, too. 0:25:54.820,0:25:57.289 What lineman does is it just knows, given[br]lineman's 0:25:57.289,0:25:59.399 conventions, how to configure the thing for[br]you. And 0:25:59.399,0:26:01.389 so we have this kind of boxed approached to, 0:26:01.389,0:26:03.549 to how we conceptualize plugins. 0:26:03.549,0:26:05.299 So you, in your application, you might have[br]a 0:26:05.299,0:26:06.750 lineman-bower plugin that you use, but you[br]can also 0:26:06.750,0:26:08.600 have a lineman-ember plugin that's gonna handle[br]all your 0:26:08.600,0:26:11.210 templates the way that Ember likes to see[br]it. 0:26:11.210,0:26:13.639 And recently we, we learned and were really[br]excited 0:26:13.639,0:26:17.230 that RackSpace is adopting lineman for its[br]frontend development, 0:26:17.230,0:26:19.789 and I encouraged them to write a metaplugin,[br]because 0:26:19.789,0:26:22.820 you can have recursively arbitrarily many[br]plugins down the 0:26:22.820,0:26:24.990 line. So this plugin here - name it whatever 0:26:24.990,0:26:27.260 you want. Maybe your company's stack or something.[br]It 0:26:27.260,0:26:29.260 can bundle as many plugins at the appropriate[br]versions 0:26:29.260,0:26:31.299 that you want, but you can also override any 0:26:31.299,0:26:33.210 of the configurations in those plugins, get[br]them just 0:26:33.210,0:26:34.480 how you like. That way you don't have all 0:26:34.480,0:26:37.419 this duplicated configuration across all of[br]your team's files, 0:26:37.419,0:26:40.450 team's project. 0:26:40.450,0:26:42.690 Back to monolithic application architecture,[br]I've painted a picture 0:26:42.690,0:26:44.429 where we can separate into two things. But[br]I 0:26:44.429,0:26:45.120 want to talk a little bit more about the 0:26:45.120,0:26:47.440 benefits of doing that. So say that you have 0:26:47.440,0:26:49.179 a client in the server. One of the first 0:26:49.179,0:26:51.279 questions that comes up is like, hey, well,[br]how 0:26:51.279,0:26:54.000 am I gonna run stuff in development, but it 0:26:54.000,0:26:55.330 still needs to see the server? I'm not gonna 0:26:55.330,0:26:58.159 build all these extra stubs for my server[br]side. 0:26:58.159,0:27:00.850 And we agree. That would be really onerous.[br]So 0:27:00.850,0:27:02.360 we built a feature into lineman that we call 0:27:02.360,0:27:07.100 API Proxying. Basically, think of the browser[br]hitting lineman, 0:27:07.100,0:27:10.299 and maybe we have Sinatra in the backend.[br]The 0:27:10.299,0:27:12.350 browser's only gonna know about lineman. It's[br]gonna make 0:27:12.350,0:27:14.260 all of its requests to lineman. But whenever[br]they 0:27:14.260,0:27:16.250 ask for any API routes that lineman doesn't[br]know 0:27:16.250,0:27:18.840 how to respond to, we've got it configured[br]to 0:27:18.840,0:27:21.730 call back to Sinatra. Sinatra responds and[br]then lineman 0:27:21.730,0:27:23.710 proxies that request back to the browser. 0:27:23.710,0:27:25.620 So it's a seamless environment. It's as if[br]you're 0:27:25.620,0:27:27.559 developing on one thing at runtime even though[br]the 0:27:27.559,0:27:30.090 code has all the benefits of, of, of physical 0:27:30.090,0:27:30.850 separation. 0:27:30.850,0:27:33.450 It looks a little bit like this. So here 0:27:33.450,0:27:35.519 I'm gonna uncomment a little bit of configuration[br]that 0:27:35.519,0:27:37.710 we give you. Change the port to 4567, for 0:27:37.710,0:27:44.710 Sinatra. My application's real simple. It's[br]just got a 0:27:45.929,0:27:48.059 simple route hi. It gets it and then it 0:27:48.059,0:27:51.679 paints it onto the screen, whatever the text[br]is. 0:27:51.679,0:27:54.350 And my Sinatra app just returns I heart Ruby 0:27:54.350,0:27:58.059 at that particular route. 0:27:58.059,0:28:02.070 So when I write lineman run, you can see 0:28:02.070,0:28:03.779 it, instead of proxying I'm gonna look at[br]Sinatra's 0:28:03.779,0:28:06.389 logs. I refresh, and it got the request from 0:28:06.389,0:28:11.350 lineman and it returned through the browser.[br]Super easy. 0:28:11.350,0:28:13.019 Now there's other cases, too, cause the benefit[br]of 0:28:13.019,0:28:15.159 separating frontend and backend, a big part[br]of that 0:28:15.159,0:28:17.250 story is that now development of those two[br]things 0:28:17.250,0:28:19.500 doesn't have to run in lock step, right. We 0:28:19.500,0:28:20.830 can make a little bit of extra progress in 0:28:20.830,0:28:23.149 the frontend, maybe do some prototyping. We[br]can have 0:28:23.149,0:28:26.909 a separate backend team after we get big.[br]But 0:28:26.909,0:28:28.559 a lot of times we have, like, you know, 0:28:28.559,0:28:30.039 it being handy to be able to stub stuff 0:28:30.039,0:28:32.070 out that doesn't actually exist on the server[br]yet, 0:28:32.070,0:28:33.889 so we can get faster feedback cycles while[br]we're 0:28:33.889,0:28:35.480 developing our frontend. 0:28:35.480,0:28:36.820 And we offered this in lineman with a tool 0:28:36.820,0:28:40.320 that we called API stubbing. So same situation.[br]We 0:28:40.320,0:28:43.529 have a browser and it's gonna be hitting lineman. 0:28:43.529,0:28:45.340 And instead of actually phoning through to[br]Sinatra, we're 0:28:45.340,0:28:46.960 gonna kind of stub our a particular route[br]and 0:28:46.960,0:28:50.169 prevent Sinatra from getting it. And we're[br]gonna return 0:28:50.169,0:28:52.919 that stub back to the browser. 0:28:52.919,0:28:55.389 So same, same, same exact code base. We're[br]gonna 0:28:55.389,0:28:58.100 go into config slash server.js. This is a,[br]an 0:28:58.100,0:29:00.559 express application that's just kind of bundled[br]in. We 0:29:00.559,0:29:02.929 can define any route we'd like. We can overwrite 0:29:02.929,0:29:07.230 that hi route. And we're gonna, we're gonna[br]troll 0:29:07.230,0:29:11.299 our coworkers here by sending that We heart[br]Node 0:29:11.299,0:29:13.600 Even More. Sacrilege. 0:29:13.600,0:29:16.809 So run lineman. Refresh the page. And now[br]our 0:29:16.809,0:29:19.029 stubbing is in place. You can build entire[br]toy 0:29:19.029,0:29:22.009 applications inside of that express application.[br]We've had clients 0:29:22.009,0:29:24.840 in the past, TestDouble is an agency, and[br]so 0:29:24.840,0:29:26.330 we're, we're as consultants. We've had clients[br]in the 0:29:26.330,0:29:27.720 past who've asked us, hey just give us the 0:29:27.720,0:29:30.259 specifications of the services that you want,[br]and our 0:29:30.259,0:29:32.090 specification is a living document of, well,[br]just make 0:29:32.090,0:29:34.340 it do this. And it's been a really, really 0:29:34.340,0:29:39.149 seamless - it's certainly better than traditional[br]documentation. 0:29:39.149,0:29:40.360 Another case that I like a lot is I 0:29:40.360,0:29:43.279 had a project once with a thirty-minute long[br]test 0:29:43.279,0:29:46.600 build, and I split it up into, I split 0:29:46.600,0:29:48.970 the application up into two. A frontend and[br]a 0:29:48.970,0:29:51.700 backend, just like we're talking about. Then[br]I went 0:29:51.700,0:29:54.009 to recover that new application with tests,[br]and I 0:29:54.009,0:29:57.059 found that the frontend tests had a runtime[br]of 0:29:57.059,0:29:59.610 only four minutes. That made me very worried[br]about 0:29:59.610,0:30:01.230 the state of affairs in the backend. I figured 0:30:01.230,0:30:03.190 that might mean that the twenty-six minutes[br]was hiding 0:30:03.190,0:30:05.610 there somewhere. But as it turns out, I wrote 0:30:05.610,0:30:08.100 that, and that only took four minutes, too. 0:30:08.100,0:30:09.259 So then I got really suspicious and I'm like, 0:30:09.259,0:30:10.970 I should probably have some smoke test to[br]make 0:30:10.970,0:30:12.480 sure that when this is all plugged into, plugged 0:30:12.480,0:30:15.179 together correctly, it works. And the smoke[br]test, of 0:30:15.179,0:30:16.409 course, when you plug it in both, it's a 0:30:16.409,0:30:17.730 little bit slower, and that ran at a whole 0:30:17.730,0:30:19.789 two minutes. 0:30:19.789,0:30:22.659 So this thirty-minute test suite somehow got[br]reduce to 0:30:22.659,0:30:24.000 a ten minute build, even though the next,[br]the 0:30:24.000,0:30:27.190 logical and physical complexity of the system[br]increased. And 0:30:27.190,0:30:29.630 if you understand how build duration tends[br]to build 0:30:29.630,0:30:32.009 super linearly, any savings that you can get[br]upfront 0:30:32.009,0:30:34.100 in the beginning are going to mean a big 0:30:34.100,0:30:36.990 difference, you're going to get a lot longer[br]runway 0:30:36.990,0:30:38.659 and traction out of the build suite in the 0:30:38.659,0:30:39.899 far future. 0:30:39.899,0:30:44.019 And, additionally, it's habit-forming, right.[br]I mean, having a, 0:30:44.019,0:30:46.059 a, there's a lot of operational problems that[br]you 0:30:46.059,0:30:48.080 have to solve when you have two different[br]things 0:30:48.080,0:30:50.710 to maintain and manage and version, as a deploy 0:30:50.710,0:30:53.679 story, two different projects. You can make[br]it simple, 0:30:53.679,0:30:57.370 but I mean, once you solve that problem, once, 0:30:57.370,0:31:02.320 you can have arbitrarily many microservices[br]popping up. 0:31:02.320,0:31:04.350 And if you're viewing the world as going in 0:31:04.350,0:31:06.230 that direction, it's a great problem to solve[br]now 0:31:06.230,0:31:08.549 with a problem that you already understand[br]really well. 0:31:08.549,0:31:10.210 Frontends and backends. 0:31:10.210,0:31:13.850 Additionally, this is not a frontend versus[br]Rails talk. 0:31:13.850,0:31:16.190 It's an and. We love Rails. We use Rails 0:31:16.190,0:31:18.649 all the time for our services. And lineman[br]and 0:31:18.649,0:31:21.240 Rails play together really nicely. We've got[br]a gem 0:31:21.240,0:31:24.220 called Rails lineman and lineman plugin called[br]lineman-rails. You 0:31:24.220,0:31:27.350 install both those things and you just magically,[br]everything 0:31:27.350,0:31:30.350 gets auto-configured. And, and your development[br]story is great 0:31:30.350,0:31:32.840 and assets precompile is just wrapped with[br]a lineman 0:31:32.840,0:31:33.659 build first. 0:31:33.659,0:31:36.379 You can learn more about that at linemanjs[br]dot 0:31:36.379,0:31:39.080 com dlash rails dot html. And we have this 0:31:39.080,0:31:42.059 fantastic little documentation site put together[br]for us by 0:31:42.059,0:31:46.470 Derrick Briggs from neo. More recently, you[br]can actually 0:31:46.470,0:31:48.909 see me do this myself, live coding, unedited,[br]in 0:31:48.909,0:31:51.519 an Ember screencast that I did - how to 0:31:51.519,0:31:54.340 get setup, like we would setup a project.[br]And 0:31:54.340,0:31:56.710 that's at our blog. It's the current, most[br]recent 0:31:56.710,0:31:58.899 article. So just hit the blog dot testdouble[br]dot 0:31:58.899,0:32:02.909 com and you'll see the, the embedded screencast. 0:32:02.909,0:32:04.980 It's a fantastic tool. We love working with[br]it. 0:32:04.980,0:32:08.009 I also, real quickly, I just want to thank 0:32:08.009,0:32:10.659 my friend Marissa Hile. She's a visual designer[br]who's 0:32:10.659,0:32:12.690 available for contract. She did all of the[br]good 0:32:12.690,0:32:19.659 illustrations in this talk. And, and, you[br]know, we'd 0:32:19.659,0:32:21.549 love to help you. If these are problems that 0:32:21.549,0:32:23.769 are, that are, that are new and hard for 0:32:23.769,0:32:26.139 your team, let us know. You know, we are 0:32:26.139,0:32:27.750 consultants, and we'd love to like, engage[br]with your 0:32:27.750,0:32:30.379 company and, and, and work on great stuff[br]alongside 0:32:30.379,0:32:31.940 you, but we'd also just love to answer your 0:32:31.940,0:32:33.919 questions, because I think we want to all[br]make 0:32:33.919,0:32:37.029 an impact and, and move the conversation forward. 0:32:37.029,0:32:40.769 Also, like everyone else at RailsConf, we[br]are hiring. 0:32:40.769,0:32:42.389 Just set an email to join at testdouble dot 0:32:42.389,0:32:44.340 com and we'll respond to you promptly and[br]have, 0:32:44.340,0:32:49.100 start the conversation. Also, a couple of[br]my fellow 0:32:49.100,0:32:52.740 double agents, Todd Coffman and Zack Briggs,[br]are giving 0:32:52.740,0:32:55.000 a, a workshop this afternoon on JavaScript[br]testing. I 0:32:55.000,0:32:56.830 think they'll probably be using lineman. So[br]it might 0:32:56.830,0:32:58.179 be a good place to practice both of those 0:32:58.179,0:33:00.220 things. 0:33:00.220,0:33:01.879 And I want to thank you. You know, please 0:33:01.879,0:33:03.750 reach out. I'd love to hear from you. It 0:33:03.750,0:33:05.490 was an absolute honor and a privilege to get 0:33:05.490,0:33:07.089 to speak to you today. Thank you very much.