1 00:00:18,609 --> 00:00:19,539 JUSTIN SEARLS: Good morning everybody. 2 00:00:19,539 --> 00:00:21,140 That was an excellent talk that we just 3 00:00:21,140 --> 00:00:22,890 saw from Brandon. Happy Friday. 4 00:00:22,890 --> 00:00:24,769 It's been a long conference. 5 00:00:24,769 --> 00:00:27,660 Thanks for being here. Friday hug to you all. 6 00:00:27,660 --> 00:00:29,140 This, if the house lights were 7 00:00:29,140 --> 00:00:30,640 up I'd take a picture. Yes. 8 00:00:30,640 --> 00:00:34,180 The title of this talk is The Rails of 9 00:00:34,180 --> 00:00:36,219 JavaScript won't be a framework. 10 00:00:36,219 --> 00:00:37,149 And the slightly less 11 00:00:37,149 --> 00:00:40,280 provocative version of that title is, the Rails of 12 00:00:40,280 --> 00:00:43,769 JavaScript will be more than just a framework. 13 00:00:43,769 --> 00:00:46,989 My name is Justin. We're not gonna have time 14 00:00:46,989 --> 00:00:48,989 for questions afterwards. It's gonna be a very, very 15 00:00:48,989 --> 00:00:51,699 fast talk-y slide-decky thing. 16 00:00:51,699 --> 00:00:53,229 So please Tweet me with 17 00:00:53,229 --> 00:00:55,699 questions, feedback, praise is always 18 00:00:55,699 --> 00:00:57,699 welcome, at searls, and 19 00:00:57,699 --> 00:00:58,869 critical feedback is always welcome 20 00:00:58,869 --> 00:00:59,879 at hello at testdouble 21 00:00:59,879 --> 00:01:00,799 dot com. 22 00:01:00,799 --> 00:01:04,828 Let's just talk about three of my favorite things. 23 00:01:04,828 --> 00:01:08,380 One is cupcakes. Two is the planet earth. And 24 00:01:08,380 --> 00:01:14,380 three is monolithic application architecture. So, on cupcakes, say 25 00:01:14,380 --> 00:01:17,670 that you own a bakery and a customer walks 26 00:01:17,670 --> 00:01:20,390 in and they say they want something sweet. So 27 00:01:20,390 --> 00:01:23,090 you bake them up a beautiful cupcake, and they 28 00:01:23,090 --> 00:01:24,500 say hey, you know, this is really good but 29 00:01:24,500 --> 00:01:26,740 I like a little bit more sweetness. Maybe a 30 00:01:26,740 --> 00:01:28,780 little crunch. So you put some sprinkles on top. 31 00:01:28,780 --> 00:01:31,220 The customer is, like, digging the cupcake, but says 32 00:01:31,220 --> 00:01:32,790 you know, on second thought, I really think I 33 00:01:32,790 --> 00:01:35,450 want something like with some hot fruit filling. And 34 00:01:35,450 --> 00:01:36,820 then you just think to yourself as the baker, 35 00:01:36,820 --> 00:01:39,610 ah god damn it. What they really wanted was 36 00:01:39,610 --> 00:01:41,560 a fresh-baked pie. 37 00:01:41,560 --> 00:01:43,590 So you throw away the cupcake and you make 38 00:01:43,590 --> 00:01:45,400 them a pie. And that's an honest mistake if 39 00:01:45,400 --> 00:01:47,450 it happens once. But if your workflow as a 40 00:01:47,450 --> 00:01:49,840 baker is to assume everyone needs a cupcake only 41 00:01:49,840 --> 00:01:51,840 to have to inevitably throw it away and then 42 00:01:51,840 --> 00:01:54,729 bake something else, that's a real problem, you know, 43 00:01:54,729 --> 00:01:56,090 for your business. 44 00:01:56,090 --> 00:01:59,610 So say you own a software studio, and a 45 00:01:59,610 --> 00:02:01,619 customer walks in and says hey, I need a 46 00:02:01,619 --> 00:02:03,250 web application, and so you say, oh great. What's 47 00:02:03,250 --> 00:02:09,179 its name so that I can type rails new. 48 00:02:09,179 --> 00:02:10,799 And you build them a little graph, you know, 49 00:02:10,799 --> 00:02:12,200 you render it on the server and they say, 50 00:02:12,200 --> 00:02:13,920 hey, you know, this graph is great but I 51 00:02:13,920 --> 00:02:16,480 need some zooms and some filters. And so you're 52 00:02:16,480 --> 00:02:19,129 like, hey, you know, I, we can do that. 53 00:02:19,129 --> 00:02:21,450 Sprinkle some JavaScript on top. And then they say, 54 00:02:21,450 --> 00:02:23,290 you know, this is awesome, but let's load all 55 00:02:23,290 --> 00:02:24,879 of the data all at once so that the 56 00:02:24,879 --> 00:02:27,670 user can really, really like just see absolutely everything 57 00:02:27,670 --> 00:02:30,640 at a glance, really dynamically, like an app, you 58 00:02:30,640 --> 00:02:32,450 know? And then you, the developer, are like ah, 59 00:02:32,450 --> 00:02:35,530 god damn it. Cause there's no logical path from 60 00:02:35,530 --> 00:02:37,560 that solution to what they really wanted, which was 61 00:02:37,560 --> 00:02:39,120 a fat-client JavaScript application. 62 00:02:39,120 --> 00:02:42,450 I mean, Rails is probably still involved, providing API 63 00:02:42,450 --> 00:02:45,250 services. But it's not the center of the application. 64 00:02:45,250 --> 00:02:48,680 That monolithic approach doesn't work. And it's an honest 65 00:02:48,680 --> 00:02:51,209 mistake, if it happens once. But if part of 66 00:02:51,209 --> 00:02:54,440 your workflow is to immediately assume that Rails is 67 00:02:54,440 --> 00:02:56,450 the solution to every single web application, and then 68 00:02:56,450 --> 00:02:58,440 you only realize later that you've guilt a gigantic 69 00:02:58,440 --> 00:03:01,910 mess with JavaScript, that's a problem. 70 00:03:01,910 --> 00:03:03,370 The reason that I think that a lot of 71 00:03:03,370 --> 00:03:05,270 web developers fall into this trap is that Rails 72 00:03:05,270 --> 00:03:09,530 is too convenient. When you're a Ruby developer, you 73 00:03:09,530 --> 00:03:12,470 have all these awesome tools right at your disposal. 74 00:03:12,470 --> 00:03:14,420 We've got this great convention-based framework so I can 75 00:03:14,420 --> 00:03:16,459 just add a gem and it, maybe a couple 76 00:03:16,459 --> 00:03:18,150 lines, and then I get all this great behavior 77 00:03:18,150 --> 00:03:20,730 on the cheap. And when we ask Ruby developers 78 00:03:20,730 --> 00:03:22,750 about their favorite client-side tools, they usually come up 79 00:03:22,750 --> 00:03:28,480 empty. Nobody hates JavaScript more than Rubyists. 80 00:03:28,480 --> 00:03:30,200 So they, they, they just can't think of any. 81 00:03:30,200 --> 00:03:32,200 And of course it's not like there's no client-side 82 00:03:32,200 --> 00:03:35,430 tools. I'm just kidding. There are plenty of client-side 83 00:03:35,430 --> 00:03:41,629 tools available to Rubyists. But this is their reputation, 84 00:03:41,629 --> 00:03:45,739 right. They're jagged and rusty and terrible. So, every 85 00:03:45,739 --> 00:03:47,390 time a new story comes down the pike, we 86 00:03:47,390 --> 00:03:49,670 have to make a decision, right. Where's the best 87 00:03:49,670 --> 00:03:52,269 place for this to live? What's the concern here. 88 00:03:52,269 --> 00:03:54,909 If a user brings me a, a user interface 89 00:03:54,909 --> 00:03:57,220 card, it might be that the best place to 90 00:03:57,220 --> 00:03:58,450 write that, the best place for that to live 91 00:03:58,450 --> 00:04:00,489 is in the browser. But the second thing I 92 00:04:00,489 --> 00:04:02,060 ask when I get a new card is like 93 00:04:02,060 --> 00:04:04,310 hey, where's, what'd be the easiest thing for me 94 00:04:04,310 --> 00:04:06,159 to actually do to build this? Take the least 95 00:04:06,159 --> 00:04:08,400 time? Be the quickest to market? And because Rails 96 00:04:08,400 --> 00:04:11,799 is so convenient, the answer is often Rails. So 97 00:04:11,799 --> 00:04:13,450 even though the best place for the code to 98 00:04:13,450 --> 00:04:16,529 live might be the frontend, I'm incentivised to start 99 00:04:16,529 --> 00:04:19,629 solving client-side problems on the server-side, and taken to 100 00:04:19,629 --> 00:04:21,779 an extreme that's really unhealthy. 101 00:04:21,779 --> 00:04:25,470 So I have a provocative statement to make. Non-Rubyists 102 00:04:25,470 --> 00:04:28,870 write better JavaScript. I went to a dot NET 103 00:04:28,870 --> 00:04:31,440 conference, my first dot NET conference, last year in 104 00:04:31,440 --> 00:04:35,020 Sophia, Bulgaria, and I was blown away by how 105 00:04:35,020 --> 00:04:37,110 much we were talking the same language. We were 106 00:04:37,110 --> 00:04:41,159 using great, brand new node.js based tooling. Everyone was 107 00:04:41,159 --> 00:04:45,139 talking about and excited about Angular, even Ember. But 108 00:04:45,139 --> 00:04:47,949 what my expectations were was it's dot NET, this 109 00:04:47,949 --> 00:04:50,259 is crusty, you know. And what I found in 110 00:04:50,259 --> 00:04:52,930 actually talking to people was, because dot net wasn't 111 00:04:52,930 --> 00:04:56,949 so incredibly awesome, they didn't have that same moral 112 00:04:56,949 --> 00:04:59,180 hazard, you know. They were willing to solve the 113 00:04:59,180 --> 00:05:02,039 problem in the right place. 114 00:05:02,039 --> 00:05:03,830 And when I think back over my own experience, 115 00:05:03,830 --> 00:05:08,039 before Rails was easy, for me, whether that was 116 00:05:08,039 --> 00:05:10,240 before 2005 or when I was doing projects in 117 00:05:10,240 --> 00:05:13,930 other tech stacks, JavaScript wasn't hard. You know, I 118 00:05:13,930 --> 00:05:16,669 actually really quite enjoyed JavaScript until I was told, 119 00:05:16,669 --> 00:05:18,369 you know, to hate it. 120 00:05:18,369 --> 00:05:21,719 And granted, we can have a long discussion. We 121 00:05:21,719 --> 00:05:24,789 can have a lot, like, screencast here about why, 122 00:05:24,789 --> 00:05:26,889 is asking, is JavaScript a terrible language? And I 123 00:05:26,889 --> 00:05:33,199 would just like clear the air, right. Yes definitely. 124 00:05:33,199 --> 00:05:35,110 I spend most of my time in JavaScript. I 125 00:05:35,110 --> 00:05:37,469 agree, it is terrible. But I'm careful not to 126 00:05:37,469 --> 00:05:41,360 conflate that with hey, well, is that why writing 127 00:05:41,360 --> 00:05:43,550 JavaScript is terrible? The problems I have always had 128 00:05:43,550 --> 00:05:45,589 with JavaScript have nothing to do with, have nothing 129 00:05:45,589 --> 00:05:47,719 to do with map and parsein and fundamental problems 130 00:05:47,719 --> 00:05:49,009 with the language, because I'm usually working at a 131 00:05:49,009 --> 00:05:50,149 higher level of abstraction, right. 132 00:05:50,149 --> 00:05:52,339 The problems I have with JavaScript are all of 133 00:05:52,339 --> 00:05:56,080 the tooling. The ecosystem. The community. So I, I 134 00:05:56,080 --> 00:05:58,300 challenge you to ask again later if you think 135 00:05:58,300 --> 00:06:02,180 the language is the one at fault. After this 136 00:06:02,180 --> 00:06:03,849 talk, hopefully I'll be able to persuade you a 137 00:06:03,849 --> 00:06:04,869 little bit. 138 00:06:04,869 --> 00:06:09,219 Let's talk about the planet earth. I love Ruby 139 00:06:09,219 --> 00:06:11,990 and I love Ruby mostly for the community. I 140 00:06:11,990 --> 00:06:14,199 love the language, but I love the community, because 141 00:06:14,199 --> 00:06:16,389 they changed the world when it comes to web 142 00:06:16,389 --> 00:06:18,729 application development. If you were to chart all of 143 00:06:18,729 --> 00:06:20,409 the great new tools for the web that have 144 00:06:20,409 --> 00:06:23,879 released over time, starting in 2005, the fantastic gems 145 00:06:23,879 --> 00:06:26,179 that were sort of the foundation for, for, for 146 00:06:26,179 --> 00:06:29,800 Ruby on Rails and this community. Over time, haml, 147 00:06:29,800 --> 00:06:33,089 sass, all of these great extensions. Alternate stacks that 148 00:06:33,089 --> 00:06:35,039 we can have an Omakase and a Prime stack. 149 00:06:35,039 --> 00:06:38,490 Rspec. Cucumber. These great innovations, helping us build better 150 00:06:38,490 --> 00:06:41,619 web applications. The world, Ruby with gems became this 151 00:06:41,619 --> 00:06:44,550 mature market place of free stuff that would help 152 00:06:44,550 --> 00:06:46,129 us write better code. 153 00:06:46,129 --> 00:06:49,369 But then, right around 2012, I started to notice 154 00:06:49,369 --> 00:06:51,729 that when a new feature would come out for, 155 00:06:51,729 --> 00:06:54,659 like, say, webkit, it wasn't immediately followed by gems 156 00:06:54,659 --> 00:06:57,619 that would exploit it. Instead I was finding JavaScript 157 00:06:57,619 --> 00:07:01,830 tooling written in JavaScript on node. And that started 158 00:07:01,830 --> 00:07:03,749 popping up, and in 2013 it really seemed to 159 00:07:03,749 --> 00:07:06,089 take off. And you come into 2014 and a 160 00:07:06,089 --> 00:07:08,349 lot of Rubyists, I think, have this latent fear 161 00:07:08,349 --> 00:07:13,129 that JavaScript is gonna devour planet earth. And I'm 162 00:07:13,129 --> 00:07:16,580 here to tell you that it probably will. 163 00:07:16,580 --> 00:07:18,009 Where the best tools? If you were to ask 164 00:07:18,009 --> 00:07:19,469 yourself this, you can add up a, add up 165 00:07:19,469 --> 00:07:22,050 a bunch of fact values. For example, Ruby's tool 166 00:07:22,050 --> 00:07:24,860 ecosystem, it's mature but it's crowded. That's not a 167 00:07:24,860 --> 00:07:26,979 lot of room for growth because everyone already has 168 00:07:26,979 --> 00:07:28,839 a lot of tools available that they, that they 169 00:07:28,839 --> 00:07:34,199 love. But node's ecosystem, it's immature, right. It's innovative, 170 00:07:34,199 --> 00:07:36,629 because so much new stuff gets pushed up, and 171 00:07:36,629 --> 00:07:40,089 it's frustrating, but it's great, because as soon as 172 00:07:40,089 --> 00:07:41,449 a new feature hits a browser, there's a tool 173 00:07:41,449 --> 00:07:43,240 to exploit it. I mean, granted, I get as 174 00:07:43,240 --> 00:07:44,839 frustrated as anybody else that when I run MPM 175 00:07:44,839 --> 00:07:47,399 install on something, like, by the time the install 176 00:07:47,399 --> 00:07:49,669 finally finishes at least two of those dependencies have 177 00:07:49,669 --> 00:07:53,059 probably had updates pushed. 178 00:07:53,059 --> 00:07:55,279 But that's the fantastic, that's what I loved about 179 00:07:55,279 --> 00:07:59,559 Ruby in 2006 and 2007. And tool authors are 180 00:07:59,559 --> 00:08:01,110 not immune to trends. I read a lot of, 181 00:08:01,110 --> 00:08:02,520 like, open source tools and I want to go 182 00:08:02,520 --> 00:08:04,509 where the people are. I want to go where 183 00:08:04,509 --> 00:08:06,809 I'm gonna have a big impact. And so tool 184 00:08:06,809 --> 00:08:09,389 authors are now gravitating to, to the world of 185 00:08:09,389 --> 00:08:11,300 JavaScript, because the universe of people who have to 186 00:08:11,300 --> 00:08:14,039 deal with JavaScript is about seven billion people, and 187 00:08:14,039 --> 00:08:15,119 the universe of people who have to deal with 188 00:08:15,119 --> 00:08:18,469 Ruby is in the tens of thousands. 189 00:08:18,469 --> 00:08:21,550 Yeah. All seven billion are JavaScript developers. I realize 190 00:08:21,550 --> 00:08:22,349 that's flawed. 191 00:08:22,349 --> 00:08:26,879 Also, tools, they address the problems of their day. 192 00:08:26,879 --> 00:08:29,239 A gem that was written in 2008 was written 193 00:08:29,239 --> 00:08:32,299 to solve problems that person was facing in 2008. 194 00:08:32,299 --> 00:08:35,208 Not 2014. A tool that was written in 2014 195 00:08:35,208 --> 00:08:36,950 surely must be useful in 2014, and so it's 196 00:08:36,950 --> 00:08:38,750 just a better fit for the web as it 197 00:08:38,750 --> 00:08:41,010 exists today. You add all that up and I, 198 00:08:41,010 --> 00:08:42,510 you know, I really believe that web tools in 199 00:08:42,510 --> 00:08:46,480 node tend to better solve today's problems. 200 00:08:46,480 --> 00:08:48,850 And this is maddening for those who insist on 201 00:08:48,850 --> 00:08:52,110 only using Rails for absolutely everything. But, hey, speaking 202 00:08:52,110 --> 00:08:57,100 of Rails, let's talk about monolithic application architecture. 203 00:08:57,100 --> 00:08:59,360 Rails won the war, right, on web application frameworks. 204 00:08:59,360 --> 00:09:01,300 It came in with a whole bunch of great 205 00:09:01,300 --> 00:09:03,670 reasons that we can go into later about why 206 00:09:03,670 --> 00:09:05,490 it was just the best. It was, it was 207 00:09:05,490 --> 00:09:08,540 fantastic, and all of these frameworks since then have 208 00:09:08,540 --> 00:09:11,230 adopted a ton of great ideas from Rails. But 209 00:09:11,230 --> 00:09:13,540 what we don't often think about when we consider 210 00:09:13,540 --> 00:09:16,550 that phenomenon is to ask ourselves, which war did 211 00:09:16,550 --> 00:09:20,790 Rails win? All web applications? Like, generally? Or is 212 00:09:20,790 --> 00:09:23,060 there some sub-set of applications for the web that 213 00:09:23,060 --> 00:09:25,180 are a better fit for Rails than others? 214 00:09:25,180 --> 00:09:28,040 DHH last year at RailsConf said that good frameworks 215 00:09:28,040 --> 00:09:31,879 are extractions, not inventions. Extracted from real applications and 216 00:09:31,879 --> 00:09:35,170 not just invented. And so when you look at 217 00:09:35,170 --> 00:09:37,930 Rails, obviously the story is that the company Basecamp 218 00:09:37,930 --> 00:09:40,670 made Basecamp and they extracted the good bits, the 219 00:09:40,670 --> 00:09:42,110 common bits that they were seeing across a lot 220 00:09:42,110 --> 00:09:45,610 of their projects into Ruby on Rails. 221 00:09:45,610 --> 00:09:47,060 And those kinds of bits that are common to 222 00:09:47,060 --> 00:09:51,399 many of us, almost all web applications: url routing, 223 00:09:51,399 --> 00:09:54,579 to point you to custom actions that you write. 224 00:09:54,579 --> 00:09:57,490 Modeling behavior of, of the models in your objects, 225 00:09:57,490 --> 00:09:59,269 the validations and all of that at a fundamental 226 00:09:59,269 --> 00:10:03,100 level. Persistence. Storing stuff in a database, querying for 227 00:10:03,100 --> 00:10:07,480 the stuff. The relationships between stuff. Session management and, 228 00:10:07,480 --> 00:10:08,920 in a way that's abstracted from where the session 229 00:10:08,920 --> 00:10:11,540 stuff was stored was hugely convenient, obviously. All of 230 00:10:11,540 --> 00:10:13,230 those ancillary concerns of the wheels that you don't 231 00:10:13,230 --> 00:10:16,209 want to reinvent like mailers. And then there's this 232 00:10:16,209 --> 00:10:19,019 last little bit that's like all these JavaScript alternatives. 233 00:10:19,019 --> 00:10:21,560 Like there's sort of like the, the means by 234 00:10:21,560 --> 00:10:24,290 which to sprinkle JavaScript on top. Like, AJAX erb 235 00:10:24,290 --> 00:10:26,689 tags that dump a whole bunch of JavaScript into 236 00:10:26,689 --> 00:10:29,839 your on-click handlers in your, in your markup, or 237 00:10:29,839 --> 00:10:33,670 later on r.js, or later on unintrusive AJAX erb 238 00:10:33,670 --> 00:10:37,889 tags. Or later on, turbolinks, right. It's not that 239 00:10:37,889 --> 00:10:40,629 those are bad, that those alternatives are bad tools. 240 00:10:40,629 --> 00:10:43,129 It's that they're there to solve, they've been abstracted 241 00:10:43,129 --> 00:10:46,439 from an application that just didn't have the problem 242 00:10:46,439 --> 00:10:48,980 of trying to solve and, and write JavaScript in 243 00:10:48,980 --> 00:10:51,000 the way that I want to write JavaScript. 244 00:10:51,000 --> 00:10:53,300 Because if you consider Basecamp, you start a page. 245 00:10:53,300 --> 00:10:55,029 It's a traditional web workflow. You start on a 246 00:10:55,029 --> 00:10:56,180 page, you click on a thing, you get another 247 00:10:56,180 --> 00:10:57,430 page, you click on a thing, you get another 248 00:10:57,430 --> 00:11:00,290 page. It's a, it's a multi-break process, and that 249 00:11:00,290 --> 00:11:03,000 represents a huge proportion of the web. And that 250 00:11:03,000 --> 00:11:05,180 percentage of the web was almost 100% in 2005 251 00:11:05,180 --> 00:11:07,509 but it's much lower now. If your app isn't 252 00:11:07,509 --> 00:11:09,490 a one to one mapping of, like, CRUD in 253 00:11:09,490 --> 00:11:11,139 the database and you're just exposing that as an 254 00:11:11,139 --> 00:11:13,670 interface to users, if there's any layer of indirection 255 00:11:13,670 --> 00:11:16,189 you, it might not be a good fit. 256 00:11:16,189 --> 00:11:21,629 Yesterday, Sandi Metz made the comment, as an aside, 257 00:11:21,629 --> 00:11:22,959 that there are Rails apps and then there are 258 00:11:22,959 --> 00:11:26,040 apps that use Rails. I'm finding that more and 259 00:11:26,040 --> 00:11:27,639 more, the apps that I'm writing are apps that 260 00:11:27,639 --> 00:11:30,240 use Rails. I can love Rails and not necessarily 261 00:11:30,240 --> 00:11:31,839 take advantage or, or really find a lot of 262 00:11:31,839 --> 00:11:35,959 benefit from the front-end aspects. 263 00:11:35,959 --> 00:11:39,550 So Rails promotes an html user interface in the 264 00:11:39,550 --> 00:11:42,699 frontend, cause that's what Basecamp needed. And what I 265 00:11:42,699 --> 00:11:43,579 mean when I say that is you're writing stuff 266 00:11:43,579 --> 00:11:45,939 like html markup. I have an anchor tag here 267 00:11:45,939 --> 00:11:48,120 with a, with a ref and, and content, or 268 00:11:48,120 --> 00:11:50,160 I might have a form action here with, you 269 00:11:50,160 --> 00:11:53,420 know, an input submit, and when you're writing html 270 00:11:53,420 --> 00:11:55,819 like this, it feels like you're making the UI. 271 00:11:55,819 --> 00:11:58,209 But you're not writing, like, UI programming. What this 272 00:11:58,209 --> 00:12:00,850 is is this is the specification of a UI. 273 00:12:00,850 --> 00:12:02,699 The user agent, the browser, is the thing responsible 274 00:12:02,699 --> 00:12:04,250 for figuring out how to render a link and 275 00:12:04,250 --> 00:12:06,180 what to do when you click it. It's how 276 00:12:06,180 --> 00:12:07,970 to render and what to do when, you know, 277 00:12:07,970 --> 00:12:09,540 how to paint a button and so forth. 278 00:12:09,540 --> 00:12:13,069 It's, you're not, you're kind of outsourcing the UI 279 00:12:13,069 --> 00:12:15,550 programming. If you're building an application with the browser 280 00:12:15,550 --> 00:12:17,139 as your runtime, though, I'd call that a JavaScript 281 00:12:17,139 --> 00:12:19,699 UI, and fundamentally the activity is just different and 282 00:12:19,699 --> 00:12:22,649 more complex. You know, you're responsible for finding the 283 00:12:22,649 --> 00:12:24,230 point and the DOM where you want to render 284 00:12:24,230 --> 00:12:27,129 stuff into. Or you're responsible for binding to an 285 00:12:27,129 --> 00:12:29,220 event that the user does something, and then you 286 00:12:29,220 --> 00:12:31,360 need to take some custom action. You're the one 287 00:12:31,360 --> 00:12:34,899 in the driver's seat. They're fundamentally different concerns. 288 00:12:34,899 --> 00:12:39,029 But our tools, I think, file, I like tree, 289 00:12:39,029 --> 00:12:40,889 to tree stuff out, because I think that tools 290 00:12:40,889 --> 00:12:44,350 tend to betray their biases based on the layout 291 00:12:44,350 --> 00:12:46,399 of the files that they give us. You know, 292 00:12:46,399 --> 00:12:47,870 a naive Rails app might look like this, and 293 00:12:47,870 --> 00:12:51,529 it screams MVC and it screams server-side. But, of 294 00:12:51,529 --> 00:12:54,279 course, in reality, one of the kind of, like, 295 00:12:54,279 --> 00:12:57,079 you know, dust-bin corners is that we have this, 296 00:12:57,079 --> 00:13:00,829 this ghetto, right, under assets, and then the most, 297 00:13:00,829 --> 00:13:06,170 you know, unfortunately named directory ever, javascripts, and then 298 00:13:06,170 --> 00:13:08,089 application.js, and it's telling us, all this stuff at 299 00:13:08,089 --> 00:13:09,870 the top - this matters. And this thing at 300 00:13:09,870 --> 00:13:12,189 the bottom, just write one big long bowl of 301 00:13:12,189 --> 00:13:13,970 spaghetti, and it'll work out. And that's how a 302 00:13:13,970 --> 00:13:16,060 lot of people write, you know, JavaScript and Rails 303 00:13:16,060 --> 00:13:18,240 applications, still. 304 00:13:18,240 --> 00:13:19,720 Some people, though, that's not good enough, and so 305 00:13:19,720 --> 00:13:22,370 they, they, they realize that they need to write 306 00:13:22,370 --> 00:13:24,079 more structured JavaScript, and so we end up with 307 00:13:24,079 --> 00:13:26,560 this new thing, like an html UI and a, 308 00:13:26,560 --> 00:13:28,610 and a JavaScript UI combined. And you might notice 309 00:13:28,610 --> 00:13:32,350 a pattern here, right. There is a, a, an 310 00:13:32,350 --> 00:13:34,470 MVC in the back, and then it's also MVC 311 00:13:34,470 --> 00:13:37,680 in the front. It makes command T really difficult, 312 00:13:37,680 --> 00:13:41,279 but it, you know, we see this duplication of 313 00:13:41,279 --> 00:13:44,939 backend concerns and frontend concerns, and there's also this, 314 00:13:44,939 --> 00:13:49,069 this little nit, negging doubt about, do we really 315 00:13:49,069 --> 00:13:50,439 need this views here? Right, if we're building a 316 00:13:50,439 --> 00:13:54,399 full-blown fat-client JavaScript application, the backend views that Rails 317 00:13:54,399 --> 00:13:56,499 provides just are less useful. So those often get 318 00:13:56,499 --> 00:13:59,079 cut out now, and we, we just have sort 319 00:13:59,079 --> 00:14:01,149 of a JSON API in Rails, and then this 320 00:14:01,149 --> 00:14:03,180 deeply-nested JavaScript UI. 321 00:14:03,180 --> 00:14:04,149 And so at this point, if like a new 322 00:14:04,149 --> 00:14:05,920 person comes to your project and they ask, hey, 323 00:14:05,920 --> 00:14:08,829 so what exactly is that thing? Right. I would 324 00:14:08,829 --> 00:14:12,430 call that a vestigial appendage. Because it can only 325 00:14:12,430 --> 00:14:14,930 be explained in terms of the past. You have 326 00:14:14,930 --> 00:14:17,129 to pull up your, you know, your forensics of 327 00:14:17,129 --> 00:14:18,829 like, well, in 2008 we were all, you know, 328 00:14:18,829 --> 00:14:21,519 thinking this and now it's still like this. 329 00:14:21,519 --> 00:14:24,170 What's wrong with that vestigial appendage? Well, what's fundamentally 330 00:14:24,170 --> 00:14:28,249 wrong is that, a fundamental problem in, in programming, 331 00:14:28,249 --> 00:14:30,149 is that when we move way faster when we 332 00:14:30,149 --> 00:14:31,579 can fit the whole application in our head at 333 00:14:31,579 --> 00:14:33,920 once, and when, on day one of any project, 334 00:14:33,920 --> 00:14:35,040 you can fit the whole thing in your head 335 00:14:35,040 --> 00:14:36,759 at once. But on day 1000 of the project 336 00:14:36,759 --> 00:14:38,360 that's probably not gonna be true. 337 00:14:38,360 --> 00:14:39,999 So if you build a monolithic thing up front, 338 00:14:39,999 --> 00:14:41,730 as that app gets bigger, eventually you reach a 339 00:14:41,730 --> 00:14:42,809 point where you can't fit it all in your 340 00:14:42,809 --> 00:14:46,170 head and you start to page, right. Part of 341 00:14:46,170 --> 00:14:47,709 the application that you're working in you can think 342 00:14:47,709 --> 00:14:49,620 of, and then over here you sort of page 343 00:14:49,620 --> 00:14:52,430 out. And if you don't modularize things well, then 344 00:14:52,430 --> 00:14:55,309 that, that, that thrashing is really, really risky. Because 345 00:14:55,309 --> 00:14:56,699 it might mean that, like, I'm in this part 346 00:14:56,699 --> 00:14:57,699 of the app, and I just kind of have 347 00:14:57,699 --> 00:15:00,209 to hope that my tests are gonna cover me. 348 00:15:00,209 --> 00:15:01,870 Although by the time you're this big, your tests 349 00:15:01,870 --> 00:15:03,670 in a typical Rails app are like ten hours 350 00:15:03,670 --> 00:15:05,660 long. So maybe tomorrow you can find out that 351 00:15:05,660 --> 00:15:07,509 it worked. 352 00:15:07,509 --> 00:15:10,139 But if you, via common concerns, and find a 353 00:15:10,139 --> 00:15:14,309 good module point to, to separate on, if you 354 00:15:14,309 --> 00:15:15,790 were to identify that you could have, like, a 355 00:15:15,790 --> 00:15:17,779 frontend app and a backend app, as those two 356 00:15:17,779 --> 00:15:20,930 things grew, even if the net complexity is higher, 357 00:15:20,930 --> 00:15:22,249 at some point they're not gonna fit in your 358 00:15:22,249 --> 00:15:26,279 head either, but the paging story is much nicer. 359 00:15:26,279 --> 00:15:29,209 Because they have a clean, well-defined separate contract. So 360 00:15:29,209 --> 00:15:32,660 the application that you're working in the backend application, 361 00:15:32,660 --> 00:15:33,839 if you have to work in it, you can 362 00:15:33,839 --> 00:15:35,689 work in it, and then when you page out, 363 00:15:35,689 --> 00:15:38,189 it's not thrashing, cause there's a clear, understood contract 364 00:15:38,189 --> 00:15:40,620 between the two. 365 00:15:40,620 --> 00:15:43,490 Relatedly, I like to say that late extraction costs 366 00:15:43,490 --> 00:15:46,089 more than early abstraction. Yesterday, Sandi's talk was great 367 00:15:46,089 --> 00:15:49,009 at telling us about wrong abstractions that have been 368 00:15:49,009 --> 00:15:51,100 found and refactoring away from those, but when we've 369 00:15:51,100 --> 00:15:54,209 seen the same project a dozen different times, I 370 00:15:54,209 --> 00:16:00,459 would much rather extract seldom and, and, and abstract 371 00:16:00,459 --> 00:16:02,319 early, and that's really confusing sounded so I'm gonna 372 00:16:02,319 --> 00:16:03,860 talk about yarn now. 373 00:16:03,860 --> 00:16:07,550 Imagine you have two balls of yarn. If you 374 00:16:07,550 --> 00:16:09,220 decided, like, man, I really just wish instead of 375 00:16:09,220 --> 00:16:10,910 these two ugly balls of yarn, I had a 376 00:16:10,910 --> 00:16:13,619 big know of yarn all tangled together, that's really 377 00:16:13,619 --> 00:16:15,759 easy to do, thanks to the basic laws of 378 00:16:15,759 --> 00:16:18,220 entropy. But if I have a big tangled know 379 00:16:18,220 --> 00:16:20,410 of yarn and decide that I really would love 380 00:16:20,410 --> 00:16:23,730 two nicely-balled, you know, nice balls of yarn, turns 381 00:16:23,730 --> 00:16:26,999 out that's very, very difficult to do. That doesn't 382 00:16:26,999 --> 00:16:27,899 work. 383 00:16:27,899 --> 00:16:29,170 So that's why, what I mean when I say 384 00:16:29,170 --> 00:16:32,249 that late abstraction, all of these, like, fancy refactorings 385 00:16:32,249 --> 00:16:34,439 that we can do, cost a lot more than 386 00:16:34,439 --> 00:16:36,110 just knowing you needed two things in the first 387 00:16:36,110 --> 00:16:40,249 place. So, back to this, this two step that 388 00:16:40,249 --> 00:16:41,660 I see in a lot of Rails applications, where 389 00:16:41,660 --> 00:16:43,089 one project, you've got the JSON API but you 390 00:16:43,089 --> 00:16:46,339 also have all the JavaScript. This isn't problematic until 391 00:16:46,339 --> 00:16:49,800 you consider this kind of stuff. You, you have 392 00:16:49,800 --> 00:16:51,860 a template that renders a script tag at the 393 00:16:51,860 --> 00:16:54,709 top, and then in the erb certain bits of 394 00:16:54,709 --> 00:16:57,709 data are kind of taking this sneaky back door 395 00:16:57,709 --> 00:17:00,569 instead of actually using the, the proper API, to 396 00:17:00,569 --> 00:17:03,709 just dump data into the JavaScript application needs. When 397 00:17:03,709 --> 00:17:05,630 you see this, it really means your yarn is 398 00:17:05,630 --> 00:17:08,020 tangled, right. Even though you think you have separate 399 00:17:08,020 --> 00:17:10,240 things. And your API is a lie. Because it 400 00:17:10,240 --> 00:17:12,140 means that even though your application is mostly using 401 00:17:12,140 --> 00:17:13,609 that API, if somebody were to come and say, 402 00:17:13,609 --> 00:17:14,619 hey, I want to build a mobile app for 403 00:17:14,619 --> 00:17:16,329 your site, they're gonna have to spend a month 404 00:17:16,329 --> 00:17:20,619 figuring out how to get that token, right. 405 00:17:20,619 --> 00:17:23,279 But it's hard not to cheat. And I agree. 406 00:17:23,279 --> 00:17:25,260 It's very, very difficult, especially given what we talked 407 00:17:25,260 --> 00:17:27,619 about earlier, where the tooling is so bad. So 408 00:17:27,619 --> 00:17:29,230 my objective in the last four years of, of, 409 00:17:29,230 --> 00:17:31,940 of my, my open source contributions, and now at 410 00:17:31,940 --> 00:17:34,880 TestDouble, where we spend a lot of our time? 411 00:17:34,880 --> 00:17:37,760 We want to help make JavaScript apps easy. As 412 00:17:37,760 --> 00:17:39,049 easy as Rails. 413 00:17:39,049 --> 00:17:41,960 When you think about Rails and the responsibilities of 414 00:17:41,960 --> 00:17:45,649 Rails, there's really three distinct parts. We have an 415 00:17:45,649 --> 00:17:47,890 application framework. Stuff that we extend - ActionController and 416 00:17:47,890 --> 00:17:51,200 so forth. We have conventions and configurations that are 417 00:17:51,200 --> 00:17:52,870 laid out for us, that we learn through the 418 00:17:52,870 --> 00:17:56,370 community and the documentation. And we have build automation 419 00:17:56,370 --> 00:18:00,520 stuff, like Rails CLI and Rake. And Rails owns 420 00:18:00,520 --> 00:18:01,610 the whole stack. 421 00:18:01,610 --> 00:18:04,049 If I had to grade them separately, I'd say 422 00:18:04,049 --> 00:18:06,250 that Rails as an application framework - when I 423 00:18:06,250 --> 00:18:07,760 first found it, I loved it. But I found 424 00:18:07,760 --> 00:18:09,899 on, like, many year, five year, six year projects, 425 00:18:09,899 --> 00:18:12,090 it encourages a lot of things that problematic. So 426 00:18:12,090 --> 00:18:14,039 maybe I'd give that a B minus, if I 427 00:18:14,039 --> 00:18:16,659 was grading it separately. But the conventions and configurations, 428 00:18:16,659 --> 00:18:18,190 that's awesome. I love that I can hit a 429 00:18:18,190 --> 00:18:20,770 new Rails team's project and, because of the tribal 430 00:18:20,770 --> 00:18:22,270 knowledge that we have as well as the conventions 431 00:18:22,270 --> 00:18:24,250 laid out and the sensible defaults, I can see 432 00:18:24,250 --> 00:18:26,169 how is their app different from the norm really 433 00:18:26,169 --> 00:18:27,580 easily. 434 00:18:27,580 --> 00:18:29,640 Build automation stuff is pretty good. I think it's 435 00:18:29,640 --> 00:18:32,470 gotten a little bit stagnant. Fantastic in 2005 and 436 00:18:32,470 --> 00:18:33,830 I haven't seen a lot of really cool stuff 437 00:18:33,830 --> 00:18:37,350 lately. But it's still solid. What I really want 438 00:18:37,350 --> 00:18:39,520 to talk about today is convention and configuration and 439 00:18:39,520 --> 00:18:41,220 the value that that can bring to our JavaScript 440 00:18:41,220 --> 00:18:43,630 tooling. Also keep in mind that a lot of 441 00:18:43,630 --> 00:18:45,130 people that are new in Rails or have only 442 00:18:45,130 --> 00:18:47,350 ever worked in Rails just see one big things. 443 00:18:47,350 --> 00:18:49,390 They don't see these as separate problems. So if 444 00:18:49,390 --> 00:18:52,220 that's you, try to think about these responsibilities separately, 445 00:18:52,220 --> 00:18:53,559 because I think they can be solved by separate 446 00:18:53,559 --> 00:18:54,370 tools. 447 00:18:54,370 --> 00:18:57,659 For example, in JavaScript, application frameworks are everywhere. If 448 00:18:57,659 --> 00:18:59,480 I decided I wanted to solve that middle problem 449 00:18:59,480 --> 00:19:02,140 by writing another application framework, then I'd have to, 450 00:19:02,140 --> 00:19:04,070 you know, go and popularize it against all the 451 00:19:04,070 --> 00:19:06,120 other application frameworks. I think that they can be 452 00:19:06,120 --> 00:19:08,809 separated. You know, whether I'm writing backbone or Angular 453 00:19:08,809 --> 00:19:10,520 or Ember - lately I've been writing a lot 454 00:19:10,520 --> 00:19:12,929 of Ember and I love it. But every six 455 00:19:12,929 --> 00:19:15,220 months I keep changing my mind. It's a fact. 456 00:19:15,220 --> 00:19:16,860 So, so at this point I just wanna be 457 00:19:16,860 --> 00:19:19,010 like, eh, I want to write awesome tools that 458 00:19:19,010 --> 00:19:21,399 are framework agnostic that anybody can, can exploit. 459 00:19:21,399 --> 00:19:25,500 From the build automation perspective, like I said, the 460 00:19:25,500 --> 00:19:28,590 community is already in node.js. Worldwide. As soon as 461 00:19:28,590 --> 00:19:30,850 stuff is happening, great tools are showing up in 462 00:19:30,850 --> 00:19:33,690 node.js first. I just want to be this little 463 00:19:33,690 --> 00:19:35,090 guy in the middle, right. I want to be 464 00:19:35,090 --> 00:19:36,590 the convention and the configuration, right. And that's why 465 00:19:36,590 --> 00:19:38,460 we built lineman. 466 00:19:38,460 --> 00:19:42,909 Lineman, like a, like a lineman on a railroad, 467 00:19:42,909 --> 00:19:45,370 is on Twitter here, and you can find his 468 00:19:45,370 --> 00:19:47,659 url. And you install him with npm. So you 469 00:19:47,659 --> 00:19:49,010 have node.js install and you can just say npm 470 00:19:49,010 --> 00:19:51,870 install globally lineman, and you create a new app 471 00:19:51,870 --> 00:19:53,890 really easily with the cli, just like Rails. Lineman 472 00:19:53,890 --> 00:19:55,710 new app. 473 00:19:55,710 --> 00:20:00,480 So, here's me typing in lineman new, start a 474 00:20:00,480 --> 00:20:02,059 new project, and I get a little. I get 475 00:20:02,059 --> 00:20:05,169 a handful of commands that I can run. But 476 00:20:05,169 --> 00:20:08,059 first I'm just gonna cd in and I'm gonna 477 00:20:08,059 --> 00:20:11,130 tree out all of the files that I have. 478 00:20:11,130 --> 00:20:12,669 Like I said, it betrays the biases, right. One 479 00:20:12,669 --> 00:20:14,679 way to learn the conventions is see what it 480 00:20:14,679 --> 00:20:16,529 generates. So you can see I have an app 481 00:20:16,529 --> 00:20:19,120 directory with css and images and JavaScript and then 482 00:20:19,120 --> 00:20:20,880 pages that render on the backend and templates on 483 00:20:20,880 --> 00:20:23,720 the front. A handful of configuration files. A whole 484 00:20:23,720 --> 00:20:25,929 bunch of spec helpers to help you test. And 485 00:20:25,929 --> 00:20:30,690 then places for all of your vendored third-party libraries. 486 00:20:30,690 --> 00:20:32,720 And it's convenient, right. It's nice to get that 487 00:20:32,720 --> 00:20:34,820 bootstrap for you. But our goal is to make 488 00:20:34,820 --> 00:20:36,990 it convenient throughout, to switch between projects to reduce 489 00:20:36,990 --> 00:20:39,500 duplication to make things more common across all of 490 00:20:39,500 --> 00:20:41,890 our work. 491 00:20:41,890 --> 00:20:44,740 One aspect of that is our productivity workflow. I 492 00:20:44,740 --> 00:20:46,500 want to be able to write some code, save 493 00:20:46,500 --> 00:20:48,880 the code, have that code automatically compile for me 494 00:20:48,880 --> 00:20:51,429 every time I save. Have it concatenate every time 495 00:20:51,429 --> 00:20:53,019 that I save, and then I want to be 496 00:20:53,019 --> 00:20:54,840 able to hit command r and refresh and play 497 00:20:54,840 --> 00:20:56,330 with it. But I want to be able to 498 00:20:56,330 --> 00:20:57,559 do all of that in less than a hundred 499 00:20:57,559 --> 00:20:59,250 milliseconds, because I want a fast feedback loop so 500 00:20:59,250 --> 00:21:01,080 that I can keep working quickly. 501 00:21:01,080 --> 00:21:02,490 In lineman, we do this with a command called 502 00:21:02,490 --> 00:21:04,649 lineman run. So you say lineman run, it does 503 00:21:04,649 --> 00:21:06,669 a whole bunch of initial build stuff, but then 504 00:21:06,669 --> 00:21:08,230 it just starts watching for file changes. So I 505 00:21:08,230 --> 00:21:10,899 can hit this server, the dev server. It says 506 00:21:10,899 --> 00:21:13,600 Hello, World! I'm gonna make a quick changes, say 507 00:21:13,600 --> 00:21:16,740 Goodbye, World! It's already updated. I refresh the page 508 00:21:16,740 --> 00:21:17,570 and that's that. 509 00:21:17,570 --> 00:21:19,630 Now, this is a simple app, but even on 510 00:21:19,630 --> 00:21:22,220 large apps it scales very well. On our large 511 00:21:22,220 --> 00:21:26,289 applications it's still roughly a hundred milliseconds. 512 00:21:26,289 --> 00:21:30,760 So, this is great. But command-r driven development isn't 513 00:21:30,760 --> 00:21:32,640 the whole story, right. I also like to write 514 00:21:32,640 --> 00:21:35,490 tests, too. Sometimes I'm doing test-driven development. When I 515 00:21:35,490 --> 00:21:39,049 do, I also want the same story to slot 516 00:21:39,049 --> 00:21:41,690 in really nicely with, with tests. And I want 517 00:21:41,690 --> 00:21:44,890 the same feedback cycle to be super duper fast. 518 00:21:44,890 --> 00:21:47,600 Lineman ships with a cool tool called testem, written 519 00:21:47,600 --> 00:21:49,960 by Toby Ho, that's really fantastic. What you do 520 00:21:49,960 --> 00:21:51,779 is you open up another shell, a second shell, 521 00:21:51,779 --> 00:21:53,649 and you run lineman spec. And you get this 522 00:21:53,649 --> 00:21:58,350 interactive test runner, launches Chrome here, and here I'm 523 00:21:58,350 --> 00:22:01,880 running a test already. Gonna just change the spec 524 00:22:01,880 --> 00:22:04,470 to say that I'm specifying that that function returned 525 00:22:04,470 --> 00:22:05,730 Goodbye, World! 526 00:22:05,730 --> 00:22:09,950 Save it off. Got a failure. That quickly. I 527 00:22:09,950 --> 00:22:12,110 can debug cause it's in the browser. I'm just 528 00:22:12,110 --> 00:22:14,690 gonna fix it. Save. And that's it. My tests 529 00:22:14,690 --> 00:22:17,399 are passing. In addition to the interactive runner, we 530 00:22:17,399 --> 00:22:19,500 want a really solid CI story. So you just 531 00:22:19,500 --> 00:22:21,659 quit out of testem with the q key, and 532 00:22:21,659 --> 00:22:24,090 you can type lineman spec ci, and this is 533 00:22:24,090 --> 00:22:26,950 gonna run it all in phantom.js with a nice 534 00:22:26,950 --> 00:22:31,070 reporter output. And every lineman project generates a travis.yml 535 00:22:31,070 --> 00:22:32,960 file when you lineman new. So you literally just 536 00:22:32,960 --> 00:22:34,740 push it to GitHub, and if you use Travis 537 00:22:34,740 --> 00:22:37,019 as your CI service, it's a one button thing 538 00:22:37,019 --> 00:22:38,309 and now you have a CI build for your 539 00:22:38,309 --> 00:22:41,370 JavaScript. Which if we were to ask people to 540 00:22:41,370 --> 00:22:43,059 raise hands, I don't think every hand would go 541 00:22:43,059 --> 00:22:46,710 up if, if I asked if you have one. 542 00:22:46,710 --> 00:22:48,950 The deploy story is similar easy, because since lineman 543 00:22:48,950 --> 00:22:51,880 is just a static asset generating tool, can your 544 00:22:51,880 --> 00:22:54,750 server host static files? Then yeah, you're good. When 545 00:22:54,750 --> 00:22:56,880 you write a lineman build, and then you tree 546 00:22:56,880 --> 00:22:59,010 out its dist directory, which is where it puts 547 00:22:59,010 --> 00:23:00,970 its built artifacts, it looks a little like this 548 00:23:00,970 --> 00:23:02,840 out of the box. You have an html file 549 00:23:02,840 --> 00:23:05,000 that references a css file and a JavaScript file 550 00:23:05,000 --> 00:23:06,390 and both of those have already been concatted and 551 00:23:06,390 --> 00:23:08,720 minified for you and they're ready to deploy. 552 00:23:08,720 --> 00:23:10,200 There's a single flag in the config that you 553 00:23:10,200 --> 00:23:12,000 can set, and then just like Rails, you get 554 00:23:12,000 --> 00:23:13,970 asset fingerprinted that makes it really nice for deploying 555 00:23:13,970 --> 00:23:16,840 when you have a CDN. Everything else that ever 556 00:23:16,840 --> 00:23:18,220 is gonna end up in your dist directory is 557 00:23:18,220 --> 00:23:20,130 gonna be stuff that you added, so it'll be 558 00:23:20,130 --> 00:23:23,070 stuff that you understand. It's a really easy build 559 00:23:23,070 --> 00:23:25,130 story. 560 00:23:25,130 --> 00:23:27,130 Pushing to Heroku is also really easy. We host 561 00:23:27,130 --> 00:23:29,700 most of our testable stuff on Heroku, so we 562 00:23:29,700 --> 00:23:32,260 just set, we wrote a custom buildpack. You set 563 00:23:32,260 --> 00:23:34,390 that up and then you say git push. It'll 564 00:23:34,390 --> 00:23:36,679 build it with node.js, but then at runtime we 565 00:23:36,679 --> 00:23:38,299 don't need it and so it just runs statically 566 00:23:38,299 --> 00:23:41,690 without node. 567 00:23:41,690 --> 00:23:42,570 And we also have a whole bunch of starter 568 00:23:42,570 --> 00:23:45,210 projects to help get people up and running quickly. 569 00:23:45,210 --> 00:23:48,269 Not everyone's just writing vanilla JavaScript, right. We have 570 00:23:48,269 --> 00:23:49,909 some people who want to get started with Angular 571 00:23:49,909 --> 00:23:53,919 quickly, Backbone or Ember. You can just clone and 572 00:23:53,919 --> 00:23:55,710 go. Clone the project and get started. You'll have 573 00:23:55,710 --> 00:23:57,380 a little bit of example code. It's a great 574 00:23:57,380 --> 00:23:59,230 way, if you want to learn Angular or learn 575 00:23:59,230 --> 00:24:01,340 Ember, just to clone our example project, because it'll 576 00:24:01,340 --> 00:24:03,070 build right away. Like, you already know how to 577 00:24:03,070 --> 00:24:04,309 run it. 578 00:24:04,309 --> 00:24:07,179 We also have a, a really cool. It's because 579 00:24:07,179 --> 00:24:08,490 it's all flexible, we also use lineman to build 580 00:24:08,490 --> 00:24:12,210 all of our JavaScript libs, libs that we maintain, 581 00:24:12,210 --> 00:24:14,110 as well as our blog and, and you're free 582 00:24:14,110 --> 00:24:16,260 to use lineman, of course, to, to write a 583 00:24:16,260 --> 00:24:18,639 markdown blog. It's really, really convenient. 584 00:24:18,639 --> 00:24:23,549 So back to planet earth. We're using Grunt. We, 585 00:24:23,549 --> 00:24:26,760 Grunt is a build tool descended from, you know, 586 00:24:26,760 --> 00:24:29,899 a whole bunch of other build tools, that is 587 00:24:29,899 --> 00:24:31,940 used for task definition. There's a lot of different, 588 00:24:31,940 --> 00:24:33,340 there's a lot of competition here right now in 589 00:24:33,340 --> 00:24:35,380 node.js. A lot of people using Gulp. A thing 590 00:24:35,380 --> 00:24:38,019 called Broccoli came out recently. It's really cool. But 591 00:24:38,019 --> 00:24:40,630 what we use Grunt for, primarily, is a place 592 00:24:40,630 --> 00:24:43,500 to get awesome stuff from the community. 593 00:24:43,500 --> 00:24:46,289 All these tasks ship with lineman out of the 594 00:24:46,289 --> 00:24:48,389 box. Or are, and, and so many more are 595 00:24:48,389 --> 00:24:52,399 available. We really, really love that we're able to 596 00:24:52,399 --> 00:24:56,510 so easily pull in new behavior through Grunt in 597 00:24:56,510 --> 00:25:01,380 a consistent manner. Lineman itself is comically extensible. We 598 00:25:01,380 --> 00:25:03,350 have a plugin system that is built a little 599 00:25:03,350 --> 00:25:06,240 bit around this mental model. We'll talk about it 600 00:25:06,240 --> 00:25:08,750 in a second. But it's really easy from a 601 00:25:08,750 --> 00:25:12,029 user's perspective. All you do is save it. npm 602 00:25:12,029 --> 00:25:15,600 install, then you save the, save the dependency. Run, 603 00:25:15,600 --> 00:25:18,590 like, lineman-bower. When you do that, after you run 604 00:25:18,590 --> 00:25:20,620 lineman run, the next time after you save that, 605 00:25:20,620 --> 00:25:22,240 lineman will pick it up from your packaged JSON, 606 00:25:22,240 --> 00:25:24,000 know that it needs to load it, and bower 607 00:25:24,000 --> 00:25:25,940 will be slotted in at the appropriate step into 608 00:25:25,940 --> 00:25:28,730 your build's workflow. No more configuration. It even generates 609 00:25:28,730 --> 00:25:30,080 your bower JSON for you if it's not there. 610 00:25:30,080 --> 00:25:33,860 Cause deep down, there is an npm module out 611 00:25:33,860 --> 00:25:37,309 there, bower, right, published by Twitter, and around it 612 00:25:37,309 --> 00:25:39,950 is the, a, a grunt-bower-task that somebody in the 613 00:25:39,950 --> 00:25:42,100 community published, and then at the top we have 614 00:25:42,100 --> 00:25:45,480 this lineman-bower plugin that we maintain. Bower is the 615 00:25:45,480 --> 00:25:47,210 thing that actually does the thing. That's where most 616 00:25:47,210 --> 00:25:48,370 of the hard work is. 617 00:25:48,370 --> 00:25:52,340 This, this power-task here, from Grunt, it automates the 618 00:25:52,340 --> 00:25:54,820 thing. There's a lot of hard work there, too. 619 00:25:54,820 --> 00:25:57,289 What lineman does is it just knows, given lineman's 620 00:25:57,289 --> 00:25:59,399 conventions, how to configure the thing for you. And 621 00:25:59,399 --> 00:26:01,389 so we have this kind of boxed approached to, 622 00:26:01,389 --> 00:26:03,549 to how we conceptualize plugins. 623 00:26:03,549 --> 00:26:05,299 So you, in your application, you might have a 624 00:26:05,299 --> 00:26:06,750 lineman-bower plugin that you use, but you can also 625 00:26:06,750 --> 00:26:08,600 have a lineman-ember plugin that's gonna handle all your 626 00:26:08,600 --> 00:26:11,210 templates the way that Ember likes to see it. 627 00:26:11,210 --> 00:26:13,639 And recently we, we learned and were really excited 628 00:26:13,639 --> 00:26:17,230 that RackSpace is adopting lineman for its frontend development, 629 00:26:17,230 --> 00:26:19,789 and I encouraged them to write a metaplugin, because 630 00:26:19,789 --> 00:26:22,820 you can have recursively arbitrarily many plugins down the 631 00:26:22,820 --> 00:26:24,990 line. So this plugin here - name it whatever 632 00:26:24,990 --> 00:26:27,260 you want. Maybe your company's stack or something. It 633 00:26:27,260 --> 00:26:29,260 can bundle as many plugins at the appropriate versions 634 00:26:29,260 --> 00:26:31,299 that you want, but you can also override any 635 00:26:31,299 --> 00:26:33,210 of the configurations in those plugins, get them just 636 00:26:33,210 --> 00:26:34,480 how you like. That way you don't have all 637 00:26:34,480 --> 00:26:37,419 this duplicated configuration across all of your team's files, 638 00:26:37,419 --> 00:26:40,450 team's project. 639 00:26:40,450 --> 00:26:42,690 Back to monolithic application architecture, I've painted a picture 640 00:26:42,690 --> 00:26:44,429 where we can separate into two things. But I 641 00:26:44,429 --> 00:26:45,120 want to talk a little bit more about the 642 00:26:45,120 --> 00:26:47,440 benefits of doing that. So say that you have 643 00:26:47,440 --> 00:26:49,179 a client in the server. One of the first 644 00:26:49,179 --> 00:26:51,279 questions that comes up is like, hey, well, how 645 00:26:51,279 --> 00:26:54,000 am I gonna run stuff in development, but it 646 00:26:54,000 --> 00:26:55,330 still needs to see the server? I'm not gonna 647 00:26:55,330 --> 00:26:58,159 build all these extra stubs for my server side. 648 00:26:58,159 --> 00:27:00,850 And we agree. That would be really onerous. So 649 00:27:00,850 --> 00:27:02,360 we built a feature into lineman that we call 650 00:27:02,360 --> 00:27:07,100 API Proxying. Basically, think of the browser hitting lineman, 651 00:27:07,100 --> 00:27:10,299 and maybe we have Sinatra in the backend. The 652 00:27:10,299 --> 00:27:12,350 browser's only gonna know about lineman. It's gonna make 653 00:27:12,350 --> 00:27:14,260 all of its requests to lineman. But whenever they 654 00:27:14,260 --> 00:27:16,250 ask for any API routes that lineman doesn't know 655 00:27:16,250 --> 00:27:18,840 how to respond to, we've got it configured to 656 00:27:18,840 --> 00:27:21,730 call back to Sinatra. Sinatra responds and then lineman 657 00:27:21,730 --> 00:27:23,710 proxies that request back to the browser. 658 00:27:23,710 --> 00:27:25,620 So it's a seamless environment. It's as if you're 659 00:27:25,620 --> 00:27:27,559 developing on one thing at runtime even though the 660 00:27:27,559 --> 00:27:30,090 code has all the benefits of, of, of physical 661 00:27:30,090 --> 00:27:30,850 separation. 662 00:27:30,850 --> 00:27:33,450 It looks a little bit like this. So here 663 00:27:33,450 --> 00:27:35,519 I'm gonna uncomment a little bit of configuration that 664 00:27:35,519 --> 00:27:37,710 we give you. Change the port to 4567, for 665 00:27:37,710 --> 00:27:44,710 Sinatra. My application's real simple. It's just got a 666 00:27:45,929 --> 00:27:48,059 simple route hi. It gets it and then it 667 00:27:48,059 --> 00:27:51,679 paints it onto the screen, whatever the text is. 668 00:27:51,679 --> 00:27:54,350 And my Sinatra app just returns I heart Ruby 669 00:27:54,350 --> 00:27:58,059 at that particular route. 670 00:27:58,059 --> 00:28:02,070 So when I write lineman run, you can see 671 00:28:02,070 --> 00:28:03,779 it, instead of proxying I'm gonna look at Sinatra's 672 00:28:03,779 --> 00:28:06,389 logs. I refresh, and it got the request from 673 00:28:06,389 --> 00:28:11,350 lineman and it returned through the browser. Super easy. 674 00:28:11,350 --> 00:28:13,019 Now there's other cases, too, cause the benefit of 675 00:28:13,019 --> 00:28:15,159 separating frontend and backend, a big part of that 676 00:28:15,159 --> 00:28:17,250 story is that now development of those two things 677 00:28:17,250 --> 00:28:19,500 doesn't have to run in lock step, right. We 678 00:28:19,500 --> 00:28:20,830 can make a little bit of extra progress in 679 00:28:20,830 --> 00:28:23,149 the frontend, maybe do some prototyping. We can have 680 00:28:23,149 --> 00:28:26,909 a separate backend team after we get big. But 681 00:28:26,909 --> 00:28:28,559 a lot of times we have, like, you know, 682 00:28:28,559 --> 00:28:30,039 it being handy to be able to stub stuff 683 00:28:30,039 --> 00:28:32,070 out that doesn't actually exist on the server yet, 684 00:28:32,070 --> 00:28:33,889 so we can get faster feedback cycles while we're 685 00:28:33,889 --> 00:28:35,480 developing our frontend. 686 00:28:35,480 --> 00:28:36,820 And we offered this in lineman with a tool 687 00:28:36,820 --> 00:28:40,320 that we called API stubbing. So same situation. We 688 00:28:40,320 --> 00:28:43,529 have a browser and it's gonna be hitting lineman. 689 00:28:43,529 --> 00:28:45,340 And instead of actually phoning through to Sinatra, we're 690 00:28:45,340 --> 00:28:46,960 gonna kind of stub our a particular route and 691 00:28:46,960 --> 00:28:50,169 prevent Sinatra from getting it. And we're gonna return 692 00:28:50,169 --> 00:28:52,919 that stub back to the browser. 693 00:28:52,919 --> 00:28:55,389 So same, same, same exact code base. We're gonna 694 00:28:55,389 --> 00:28:58,100 go into config slash server.js. This is a, an 695 00:28:58,100 --> 00:29:00,559 express application that's just kind of bundled in. We 696 00:29:00,559 --> 00:29:02,929 can define any route we'd like. We can overwrite 697 00:29:02,929 --> 00:29:07,230 that hi route. And we're gonna, we're gonna troll 698 00:29:07,230 --> 00:29:11,299 our coworkers here by sending that We heart Node 699 00:29:11,299 --> 00:29:13,600 Even More. Sacrilege. 700 00:29:13,600 --> 00:29:16,809 So run lineman. Refresh the page. And now our 701 00:29:16,809 --> 00:29:19,029 stubbing is in place. You can build entire toy 702 00:29:19,029 --> 00:29:22,009 applications inside of that express application. We've had clients 703 00:29:22,009 --> 00:29:24,840 in the past, TestDouble is an agency, and so 704 00:29:24,840 --> 00:29:26,330 we're, we're as consultants. We've had clients in the 705 00:29:26,330 --> 00:29:27,720 past who've asked us, hey just give us the 706 00:29:27,720 --> 00:29:30,259 specifications of the services that you want, and our 707 00:29:30,259 --> 00:29:32,090 specification is a living document of, well, just make 708 00:29:32,090 --> 00:29:34,340 it do this. And it's been a really, really 709 00:29:34,340 --> 00:29:39,149 seamless - it's certainly better than traditional documentation. 710 00:29:39,149 --> 00:29:40,360 Another case that I like a lot is I 711 00:29:40,360 --> 00:29:43,279 had a project once with a thirty-minute long test 712 00:29:43,279 --> 00:29:46,600 build, and I split it up into, I split 713 00:29:46,600 --> 00:29:48,970 the application up into two. A frontend and a 714 00:29:48,970 --> 00:29:51,700 backend, just like we're talking about. Then I went 715 00:29:51,700 --> 00:29:54,009 to recover that new application with tests, and I 716 00:29:54,009 --> 00:29:57,059 found that the frontend tests had a runtime of 717 00:29:57,059 --> 00:29:59,610 only four minutes. That made me very worried about 718 00:29:59,610 --> 00:30:01,230 the state of affairs in the backend. I figured 719 00:30:01,230 --> 00:30:03,190 that might mean that the twenty-six minutes was hiding 720 00:30:03,190 --> 00:30:05,610 there somewhere. But as it turns out, I wrote 721 00:30:05,610 --> 00:30:08,100 that, and that only took four minutes, too. 722 00:30:08,100 --> 00:30:09,259 So then I got really suspicious and I'm like, 723 00:30:09,259 --> 00:30:10,970 I should probably have some smoke test to make 724 00:30:10,970 --> 00:30:12,480 sure that when this is all plugged into, plugged 725 00:30:12,480 --> 00:30:15,179 together correctly, it works. And the smoke test, of 726 00:30:15,179 --> 00:30:16,409 course, when you plug it in both, it's a 727 00:30:16,409 --> 00:30:17,730 little bit slower, and that ran at a whole 728 00:30:17,730 --> 00:30:19,789 two minutes. 729 00:30:19,789 --> 00:30:22,659 So this thirty-minute test suite somehow got reduce to 730 00:30:22,659 --> 00:30:24,000 a ten minute build, even though the next, the 731 00:30:24,000 --> 00:30:27,190 logical and physical complexity of the system increased. And 732 00:30:27,190 --> 00:30:29,630 if you understand how build duration tends to build 733 00:30:29,630 --> 00:30:32,009 super linearly, any savings that you can get upfront 734 00:30:32,009 --> 00:30:34,100 in the beginning are going to mean a big 735 00:30:34,100 --> 00:30:36,990 difference, you're going to get a lot longer runway 736 00:30:36,990 --> 00:30:38,659 and traction out of the build suite in the 737 00:30:38,659 --> 00:30:39,899 far future. 738 00:30:39,899 --> 00:30:44,019 And, additionally, it's habit-forming, right. I mean, having a, 739 00:30:44,019 --> 00:30:46,059 a, there's a lot of operational problems that you 740 00:30:46,059 --> 00:30:48,080 have to solve when you have two different things 741 00:30:48,080 --> 00:30:50,710 to maintain and manage and version, as a deploy 742 00:30:50,710 --> 00:30:53,679 story, two different projects. You can make it simple, 743 00:30:53,679 --> 00:30:57,370 but I mean, once you solve that problem, once, 744 00:30:57,370 --> 00:31:02,320 you can have arbitrarily many microservices popping up. 745 00:31:02,320 --> 00:31:04,350 And if you're viewing the world as going in 746 00:31:04,350 --> 00:31:06,230 that direction, it's a great problem to solve now 747 00:31:06,230 --> 00:31:08,549 with a problem that you already understand really well. 748 00:31:08,549 --> 00:31:10,210 Frontends and backends. 749 00:31:10,210 --> 00:31:13,850 Additionally, this is not a frontend versus Rails talk. 750 00:31:13,850 --> 00:31:16,190 It's an and. We love Rails. We use Rails 751 00:31:16,190 --> 00:31:18,649 all the time for our services. And lineman and 752 00:31:18,649 --> 00:31:21,240 Rails play together really nicely. We've got a gem 753 00:31:21,240 --> 00:31:24,220 called Rails lineman and lineman plugin called lineman-rails. You 754 00:31:24,220 --> 00:31:27,350 install both those things and you just magically, everything 755 00:31:27,350 --> 00:31:30,350 gets auto-configured. And, and your development story is great 756 00:31:30,350 --> 00:31:32,840 and assets precompile is just wrapped with a lineman 757 00:31:32,840 --> 00:31:33,659 build first. 758 00:31:33,659 --> 00:31:36,379 You can learn more about that at linemanjs dot 759 00:31:36,379 --> 00:31:39,080 com dlash rails dot html. And we have this 760 00:31:39,080 --> 00:31:42,059 fantastic little documentation site put together for us by 761 00:31:42,059 --> 00:31:46,470 Derrick Briggs from neo. More recently, you can actually 762 00:31:46,470 --> 00:31:48,909 see me do this myself, live coding, unedited, in 763 00:31:48,909 --> 00:31:51,519 an Ember screencast that I did - how to 764 00:31:51,519 --> 00:31:54,340 get setup, like we would setup a project. And 765 00:31:54,340 --> 00:31:56,710 that's at our blog. It's the current, most recent 766 00:31:56,710 --> 00:31:58,899 article. So just hit the blog dot testdouble dot 767 00:31:58,899 --> 00:32:02,909 com and you'll see the, the embedded screencast. 768 00:32:02,909 --> 00:32:04,980 It's a fantastic tool. We love working with it. 769 00:32:04,980 --> 00:32:08,009 I also, real quickly, I just want to thank 770 00:32:08,009 --> 00:32:10,659 my friend Marissa Hile. She's a visual designer who's 771 00:32:10,659 --> 00:32:12,690 available for contract. She did all of the good 772 00:32:12,690 --> 00:32:19,659 illustrations in this talk. And, and, you know, we'd 773 00:32:19,659 --> 00:32:21,549 love to help you. If these are problems that 774 00:32:21,549 --> 00:32:23,769 are, that are, that are new and hard for 775 00:32:23,769 --> 00:32:26,139 your team, let us know. You know, we are 776 00:32:26,139 --> 00:32:27,750 consultants, and we'd love to like, engage with your 777 00:32:27,750 --> 00:32:30,379 company and, and, and work on great stuff alongside 778 00:32:30,379 --> 00:32:31,940 you, but we'd also just love to answer your 779 00:32:31,940 --> 00:32:33,919 questions, because I think we want to all make 780 00:32:33,919 --> 00:32:37,029 an impact and, and move the conversation forward. 781 00:32:37,029 --> 00:32:40,769 Also, like everyone else at RailsConf, we are hiring. 782 00:32:40,769 --> 00:32:42,389 Just set an email to join at testdouble dot 783 00:32:42,389 --> 00:32:44,340 com and we'll respond to you promptly and have, 784 00:32:44,340 --> 00:32:49,100 start the conversation. Also, a couple of my fellow 785 00:32:49,100 --> 00:32:52,740 double agents, Todd Coffman and Zack Briggs, are giving 786 00:32:52,740 --> 00:32:55,000 a, a workshop this afternoon on JavaScript testing. I 787 00:32:55,000 --> 00:32:56,830 think they'll probably be using lineman. So it might 788 00:32:56,830 --> 00:32:58,179 be a good place to practice both of those 789 00:32:58,179 --> 00:33:00,220 things. 790 00:33:00,220 --> 00:33:01,879 And I want to thank you. You know, please 791 00:33:01,879 --> 00:33:03,750 reach out. I'd love to hear from you. It 792 00:33:03,750 --> 00:33:05,490 was an absolute honor and a privilege to get 793 00:33:05,490 --> 00:33:07,089 to speak to you today. Thank you very much.