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