 Alright, hey everyone! So I thought why not stay with the appropriate beginning to my talk. I like to start with everything in the 70s, 80s, 90s, because those were the good heirs back when I didn't do this. Well, I guess it was in the 90s. So for the last year I've worked as a front-end developer at Coursera. And how many of you have taken at Coursera Plaza? Or signed up for Coursera? How many of you have gotten one week into a Coursera class? And anyone actually completed a class? Wow, very nice. Scala class? Is that...Sass? What else do you guys complete? Alright, rhythms? Alright, very nice. Which one? Game of vacation. Game of vacation. Okay, so there's a ton of classes, right? There's stuff like how to cook your baby. That's actually a very popular class. There's one that started a few weeks ago on volcanic eruptions. And my mom was emailing me bugs for that. And I was like, oh mom, you're so silly taking a class on volcanoes. And this is an old people do. They take silly classes. And then I found out she's like working on a research paper for NASA on analyzing the plumes from volcanic eruptions using FORTRAN. So it turns out there's actually really valid reasons to take classes on volcanic eruptions. She also got 110% in heterogeneous parallel programming. So she's basically a more accomplished person than I am at this point in life. But it's cool because she's mom, so I've got time to catch up. Alright, so Coursera, right? So any of you who haven't signed up for a class and not taken it, Coursera offers online university level classes from all these different universities. And they're across a huge range of topics. And you do stuff like watch lectures, take quizzes, do peer assessments, talk in the forums, all of that stuff. And it was actually really, really cool when you take a class and get through it. I did the irrational behavior class with Dan Ariely, which I highly recommend. Especially Dan. So anyway, so Coursera, we use Backbone a lot. Basically in all of our new modern code bases, we use Backbone everywhere. And I've actually spent the last year writing a lot of blog posts and giving various talks on Backbone. So if you're curious about how we use Backbone at Coursera, I've got links here. I put together this whole guide of writing how we write apps at Coursera, which is kind of our best practices in terms of models and views and regions and all that. Also did some deep dives on different things that we did like rewriting Django admin, rewriting our forums and some stuff on performance. So for the last year, I've been going to these conferences that are not called Backbone Calf and I've been giving talks on Backbone. So for Backbone Calf, I'm not going to give a talk on Backbone at all. So this talk is not about Backbone. Because the thing is that at Coursera, we do have multiple code bases. As in we have a legacy code base. And our legacy code base is that beautiful thing known as PHP. And it's PHP with a custom written framework written by some grad students who, you know, they just really wanted to write their own and not document it. And it's that beautiful thing where you mix together HTML and you've got PHP outputting script tags with global variables in it. So we're not using Backbone there yet because it's taking time to port it over. But we do use UI libraries there, right? Even in our old code base, we need to have modals, we need to have pop-ups, we need to have tooltips, we need all of that. And we want to have a consistent UI experience across all of Coursera, both for our users and for our developers, right? If you need a modal, you should be able to use the same modal library in the Backbone code base as in the non-Backbone code base, right? So we kept running into the issue of realizing we would need a UI library and trying to figure out which UI library we should use and trying to use the same one across our code bases, right? How many of you have used UI libraries before? Okay, it should be everyone. It's cool, you can do Backbone on the server. So we're going to be talking about UI library design and I'm not talking about aesthetic design. I tried to make that very obvious by making my slides highly unattractive. I actually think they're really, really cute, though. But we're not going to be talking about aesthetic design, right? We're going to be talking about the actual behind-the-scenes design, right? The actual layout of the code, the architecture of the libraries, right? But if you really, really like these slides, you can totally copy them. It's cool, just credit me. So when we thought about which UI libraries to, you know, what we were going to use, we obviously started with jQuery plugins, right? Because it's like, hey, we're going to use UI library. We're going to use thousands of jQuery plugins. So let's get started talking about that. So I looked up and got a history of jQuery plugins because I was kind of curious, like, where did jQuery plugins come from, right? Because a lot of times we use stuff today and we don't know their history and I always find it fascinating to find out the history of the things, right? If you've never looked at screenshots of the first browser that they made, it's fascinating because they used to, like, every image would open up in its own page because they couldn't imagine you ever wanting to have images, like, a line in the page and they thought all your images would be epic and every page had an edit button, right? Because that's why HTTP has all these verbs, because they imagined originally you would just be editing everybody else with webpages. So anyway, it's really fascinating to actually look at the history of the things we use today instead of just kind of assuming that they are what they are. So jQuery was released in January 2006 and John Resick says that he actually built it from the beginning with the idea of plugins. On the first day, you could actually make plugins with jQuery, right? And just 25 days later, the first jQuery plugin from a third-party developer came out, right? And then they started to see more and more people making plugins and so then on June 2007, they actually came up with a jQuery plugin repository to help people actually find these plugins, right? And you guys have probably all seen that. And then they started working on jQuery UI because there were so many people that were doing these kind of UI things with jQuery. They're like, all right, well, we should try and get a common library that's built on top of jQuery that works well and has even a better architecture, right? Because jQuery plugins weren't much of an architecture. You were just doing the dollar.fn thing. But jQuery UI widgets, they actually have much more of an architecture to them. And so it can be a little more consistent when you're actually using that jQuery UI, right? And so in May 2009, they came up with this jQuery UI widget factory, which was a standard way of building widgets on top of jQuery UI, right? So we accumulated jQuery plugins starting from the very first time, January 2006. So that was like, let's do math here. That was like seven years ago, right? That was ages ago. And so we've been building up all these plugins since then, right? And jQuery plugins are actually really, really awesome and we should be really thankful for them because they did a lot of good things for the developer community, right? So they generally like the approach of jQuery, like from the very beginning was to encourage people to write plugins, right? And say like, you know, if you actually want to build something on top of jQuery, do it in this plugin style. We've come up with this way for you to do that, right? So from learn.jQuery.com, the barrier to creating a plugin of your own is so low that you'll want to do it straight away. Some might argue that maybe the barrier is too low, but yeah, hey, it's nice to have low barriers. That might be true about all the web, but that's cool. It's good. Everybody in the world will be programming and it'll be awesome. There'll be a lot of bugs, but hey, it's not like none of us write bugs, right? Whatever. Let other people, like, everybody should have the right to write bugs in software. Even little babies. Okay, and then, you know, one of the big things about jQuery was its extensibility, right? So it was like a message from jQuery that they wanted, you know, the jQuery community wanted you to create plugins and wanted you to build on top of jQuery. And that's cool. It encourages people to, you know, extend jQuery how they want. And it also gave a standard way to write UI libraries, right? It wasn't just put down a bunch of JavaScript. It was, hey, attach something to this $.fn, and then with jQuery UI widget factory, it was even more specific with, you know, whatever five different methods that you would define all that stuff to say what happens when you initialize the widget. And then there's all these blog posts and articles that people would write to actually talk about the architectures for jQuery plugins, right, to try and add even more to that. So it was basically like when you thought to yourself one day, like, hey, I want to write a UI library, you would probably think to write a jQuery plugin. Because that's kind of the standard, it's the only standard really that we think of right now, at least for me, that I think of when I think of I want to write a UI library, right? So at the beginning at Coursera, whenever we would think, oh, we want to write a UI library, we would look at the how to write a jQuery plugin doc and we'd start writing it that way. And, you know, the jQuery community also encouraged sharing, right? So they've got the jQuery plugins repository and there's even alternative repositories for people who don't like the jQuery plugins repository. You like it more visual like this. But, you know, there's tons of these plugins. There's probably like three times as many as you actually see in this repository, right? You just Google for it. If you Google for jQuery date-picker plugin, the first 10 results will be all blog posts that are meta that are like top 10 jQuery date-picker plugins, right? You know, we're like, I love this. I'm like, what? Top 10? Damn, it's better than Google. It's not really. Here's a tip. Whenever you're searching for any sort of library, go to... Oh, let me like demonstrate, right? So if you go to Google, like, and let's say we want a date-picker JS library, right? Go to... Sorry, go to search tools. Go to any time and do past year or past month, right? And what you'll tend to find, I usually do this to try and get an idea for things that are more recent, like if I'm doing something really, like let's say you're doing, like, HTML5 video pro, right? Like, I was looking for like MP4 multiple. So this one, I will always limit this, pretty much always limit this to past year, even past month, right? Because when we're using this kind of, you know, really crazy new stuff, you know, and if you're trying to target mobile, a lot of the solutions wouldn't have come out until the last year, right? And if you're looking at a bug that you suspect is in like most recent version of Chrome, it's only useful to look at the last month. So, you know, just a little Google tip for you. I did work for Google before, and it was mostly because I'm really good at Googling. Like, even like my Google colleagues would like send me search terms, they're like, hey, I really want to find this. Could you Google it for me? I'm like, all right, you know, we're all Googlers here, but it's cool. I'll find it for you, no prob. Just give me a little bonus, you know? All right, so jQuery plugins are awesome because they encourage this whole community of these open source libraries and that everyone could share and learn from and use for their stuff, right? I am a big fan of not reinventing wheels because I kind of think that developers, we should just all be working on adding our own unique value to the world. I think it's like, whenever I'm writing a bit of code, I just have this like deep urge to open source it and I think to myself, what if there's somebody out there in the world who needs to write this code tomorrow? I should make sure they can find it, right? I don't know if you guys get that urge too, but like, it's really... So I just think I have to like accidentally gist it or whatever and not tell anyone. Justine is a great way of... not open source. So anyway, so jQuery plugins were great, but they're not actually perfect, right? And one of the big deals about them is they do depend on jQuery, right? So you have to have jQuery in order to run them and you may not always want to use jQuery. Now you might argue that, oh, you could just throw in something that's jQuery compatible, like Zepto. I would then tell you that I spent a year where I did actually... I was making a mobile phone gap app and I wanted to improve the performance, so I switched out jQuery for Zepto. I then discovered that jQuery plugins use the most obscure features of jQuery possible, right? None of which were supported by Zepto, right? So I would be sitting there like, I spent weeks staring at the jQuery source viewer copying like its code into the Zepto code and building up my Zepto library so that it had all this functionality. And then I was all ready to give it back to Zepto. And then the Zepto author decided that semi-colons weren't cool. So he stripped semi-colons out of Zepto and then it came really hard to diff my library with his. So if you're going to decide that semi-colons aren't cool, do it at the inception of your library, not in the middle. Anyway, so, right. So the thing is like, it's not just that you're dependent on the jQuery selectors. jQuery plugins use the craziest, most obscure things in jQuery, right? So they pretty much are dependent on jQuery and it's subtleties. And a lot of them are also dependent on jQuery UI, right? If they're built on top of the jQuery UI, so that means you need the jQuery UI JavaScript as well. You also need the jQuery UI CSS. I spent like a good week trying to take out jQuery UI from our code base as much as we could because we already had lots of other CSS and JS and it was like, well, this doesn't seem necessary. Why do we need it? And then I discovered that we were using it for the jQuery UI date picker, which is pretty much the only date picker that does dates and times and time zones all in one. So we had to keep it. And since it was built on top of those, we couldn't really strip those out. So there's that issue, right? But there's also the issue of their internal architecture, right? So a lot of these plugins were built before there were best practices about how to structure plugins. I think a lot of that stuff has been recent, right? Because we've had plugins for the last seven years. So sometimes their architecture is inconsistent with other architectures. And sometimes they just didn't really have architecture. It's just kind of a bunch of code. And look, the thing is you're pretty much always going to... Every time I use a third-party library, I end up digging into it, right? They're pretty much never a black box. There's always some little weird thing. So I always recommend, before you start using a library, look at its code first. If you puke a little bit in your mouth, you should probably find a new library because you will probably have to look at that code later. You'll probably have to set break points in it. You'll probably have to actually maybe modify it, send a patch back, right? So it should be... I don't want to offend people. I'm sure I've written code that would also make you puke your mouth, right? So it's just when you're picking something that you're going to invest time in, make sure you're going to be happy investing your time in it. It's going to make you joyful, right? If you look in the code and you see a ternary operator that's nested 12 levels deep, and this isn't... I can tell you exactly which libraries have these. Just walk away. Because it's entangling those. I once had... I had to disentangle one of those ones. It took me like an hour to disentangle it so that I could put in the correct console.logs and all that stuff, right? And using, I think it was alert because I was debugging on mobile. Anyway. So, okay. Right. So at Coursera, we started off with jQuery plugins, but then we're like, oh, we don't really want to have this dependent on jQuery. And we also just kind of want to see, you know, what kind of architecture would we come up with for our UI libraries if we kind of threw away this jQuery plugin thing and we started from scratch. So that's what we did. And, you know, we kind of tried to think, like, what are the different things we would want in a library, right? So some of the things, like, obviously with jQuery plugins, one of the great things is how easy they are to customize, and there is a consistent way that people do that. But we also didn't want them to be dependent on jQuery. We wanted them to be compatible in AMD and non-AMD environments because our back home code is AMD, our other code is not. We also wanted them to be usable by both developers and designers. We wanted to be really easy for our designers to be able to modify these libraries. And there's actually quite a few other things that we wanted. So we'll step through that. So as our example, we are going to be making a marquee library because I love marquee. Little known fact, the marquee tag works perfectly fine in Chrome. Right? You can actually, like, we could go and turn this into a marquee right now, right? Let's just do a little inspect element action. All right? And... So marquee works fine in Chrome. Flink works fine in Firefox. But not the vice versa, right? So basically they, each of them kept their own thing. But you can't have Flink and marquee on the same browser. So you're going to have to pick one. I do have a Chrome extension that will make Flink work for you on Chrome if that's a thing that you can talk to me after. I took it away from my dashboard because it wasn't getting as many stars as other things. But... I do have the code. So, all right, so we're going to make a marquee module. And we're not going to do this as a poly pool. We'll just do it as a library. So for the basic library, this is what we want, all right? So we want to be able to create a div. It has some text in it. And then to use it, we just want to be able to see, like, okay, var marquee equals new marquee. Document get element by ID marquee. And then here I just put a little marquee.stop in a set timeout because I didn't want to give you guys epilepsy. So it's going to stop after five seconds, right? I say that after showing optical illusions for you for like 10 minutes, right? So here's our HTML and our marquee. You can see it works beautifully. I did consult the CSS marquee spec when making it. Not really. So here's our JavaScript, right? So this is a pretty standard JavaScript class, right? We have a var marquee constructor function. It sets some initial position and the direction to forwards. And then we set interval for the timer. And the timer calls the moveit-moveit function. Anyone want to see that? And the moveit-moveit function, we figure out the current left. We check if it's less than the window. We set the direction to backward or forwards. And then, you know, we increment it plus or minus 10. All right? And then for our stop, we just clear the interval. So that's our basic library. And we're going to build off of this. So the first thing we want to do is that we want to hide private functionality, right? This is that thing they call encapsulation in OOP. I think encapsulation is a really weird word. And every time I hear it, I forget what it means. So it's like the kind of thing like before interviews, I have to look up all these fancy OOP words. But we can also call it information hiding. So basically, we want to hide private functionality. And then the reason to hide private functionality is so that developers don't call it, right? If you want to have a stable interface, right? So you want to only expose the functions that you intend your developers to call. Now granted, these developers, they're just developers inside our company. So you might think like, well, I don't have to worry about them. They're only going to call what I tell them to call. Like, no. They're going to call anything you let them call. That's what we do in Jaws Group. We're like, oh, I found a method on your class. I kind of called it. So the only way we can prevent them from calling it is if we hide it, we make it impossible, right? You know, the thing is when I worked at Google, I was working on the Google Maps API, developers called every possible thing they could find. They dug inside those variables so deep. So I'm very familiar with those sneaky developers. So what we can do here is that we're going to wrap everything in that special word that means anonymous function. What's that word people use? Iffy. Iffy. It's an iffy. So I wrapped it in an iffy. Anyway. And then I created this marquee module and the marquee module has private, underscore private, which is an object which has all the private functions we want. And then we have this marquee class inside here which we'll actually call private.movementmovement.callself. So the general thing is we put it inside this private object and then when we want to call it from the proper class, we're just going to use the .call and we're going to pass in the context of that class. And then from this marquee module, we only return marquee. And then window.marquee equals this module. So that means that there is no way they can access underscore private because it is a local variable that is not returned to the global marquee object. So we've succeeded in making it so that they can't call that function. That's cool. So that means that we have anything where we think we want it to be private. We'll put it inside there. And generally, I would try and start with whenever you're making an interface, you try and hide as many things as possible at first and you only make things public when people really, really want them, right? Because you're going to have to support those forever and ever. This doesn't matter as much for your internal libraries, but certainly when you're doing APIs, we always hide as much as possible and don't expose things until the developers come in at your door begging for it. Which is great when that happens. I used to get developers to send me such great little swag boxes like, hey, maybe you sent me something nice from Russia. I could expose that method, you know? All right. Another thing we'd like to be able to do is we'd like to be able to call marquee on the same DOM object twice and not have it actually re-initialize the marquee on that object, right? Because I get kind of forgetful. I forget that I already called marquee on that. 40 lines later, I call it again. Oops. And in the previous code, like if I did this in where... All right, so let's try this in the code we have open right now and see what happens. All right, so... Did it work? So you notice how it didn't stop? It didn't stop because I actually, I accidentally set up two set intervals here because I accidentally constructed it twice. So we don't want that. We want there to only be one marquee object tied to that bit of DOM. So what we'll do is we'll just remember that in the DOM. So I've added this get or make marquee function to private. And what that does is it looks to find if there's a marquee object on the element now. And if there is and if the constructor matches the public marquee constructor, then we just return that object. Otherwise, we do construct a new one and we set the marquee object on the element to that object and then we return it. So then down here, instead of just returning marquee, we're going to create this public function which will take the element and returns the private get or make marquee function. Right? So anytime they call marquee, it's actually going to that get or make marquee function instead. Everything's a little bit safer, right? You should just make it so it's hard for developers to make stupid mistakes because it's kind of easy for us to do that, right? Because probably half of you are hacking on your code base right now, kind of half paying attention to this, half paying attention to your code base. It's really easy for you to actually call a function twice there, right? You're not really paying attention to anything in life. Okay. So we keep going, right? So we want to be able to customize our library, right? You guys are probably thinking that a lot of jQuery plugins, you know, do all this already, which is true, but I think it's actually interesting to step through and see how we actually would do this from scratch and we'll add more stuff. So we want to be able to customize the library, so we want to be able to pass in an object literal of options, right? So that's pretty straightforward to do. I'm just going to add another private function which is customize marquee. It'll take in the options and it'll set the options and also set this direction property according to the options. And then I need to modify get or make marquee, because what I want to happen is that if you reconstruct marquee on an element that already has a marquee, but with a new set of options, I actually want to take those new options, right? So you can reconstruct twice and it won't really reconstruct, but it'll set options. And that's a way that we tend to like our UI libraries to work, but it's something that you could think about, right? So if we do find that there's options passed in and we did find an existing marquee, then we'll just call the customize function, but still return the same marquee. Otherwise, we pass them into the constructor and that will call it. So that's pretty cool, but whenever you have options, you want to know what your options are, right? You don't want to be scrolling through the code, trying to figure out all the possible options for your options. And you also want to know what the defaults are, right? So we're going to add some defaults. And we're just going to do this similar to, you know, how jQuery plugin would do it. So in our private, we've got our defaults and you can see it for each of the options, I list the default value and then in the comments, I say what the other values could be. And there I say, you know, it could be any integer. And then in the customize marquee function, I first go through and check to see, you know, what all the options are and all the defaults. And if we haven't actually had something set in via the options, then I set it equal to defaults. Okay. It's more interesting, right? I was saying in the beginning that one of the things that's nice is if you can have it so your designers can also customize, you know, your plugins, right? So I remember when our designers first started, when one of them first started, he was very used to doing everything via delivering Photoshop files. So the first day, he delivered a Photoshop file to me and I was like, what are your feelings on HTML and CSS? And he's like, oh, I'd love to learn that nobody ever wanted me to before. Everywhere else he'd worked, actually explicitly only wanted him to give them Photoshop files because for some reason they enjoyed the process of turning Photoshop into CSS. And I was like, no, no, go for it. Go learn it. Take some time. Also learn Git and GitHub. And he did, right? Like for a while, you know, with Git, it was kind of blindly copying and pasting commands and hoping not to delete the whole code basically. That's why you have a live branch and you don't tell them about it. So the thing, so now our designers are at the point where they know HTML and CSS. One of them even knows how to use a backbone too. But assuming that your designers can learn HTML and CSS, which is really useful because that's really what they're actually the medium they're crafting in. So once they're able to do that, like once our designer knew HTML and CSS, he felt so powerful and he felt like he was actually able to make much better designs like he was speaking the same language as the final output. So then you want to make it possible for them to edit things about the UI just in the HTML and not have to go into JavaScript because it can be a little intimidating to dive into a backbone view and try and, you know, find these things especially if you're not, you know, super familiar with JavaScript. So we want to make it so we can specify options via data attributes, right, and so they could just tweak data attributes in order to play around with these options. And hey, developers like this too, actually. Most of the time we end up using declarative customization instead of a script. So what we have, so in the HTML we've got those data attributes and then in the JavaScripts we have this code here. We've just changed customizing our keys so that it checks to see if there's actually a default on the element itself. And we still have it, so because now you have to decide what's more important, the data attributes or the objects that, you know, the JavaScript object you pass in. So we consider the JavaScript object to still be able to override the data attributes but you could make that decision yourself as to which should have precedence. So that's pretty cool. But we also want to make it so that designers don't even have to construct the library in JavaScript, right, because we still have that marquee constructor. So ideally they could just be like editing any bit of code and just say, oh this is something that I want to be a marquee and they could just throw something in there, right. So we can just add in a data attribute, data marquee, to say hey, this is something that should be turned into a data marquee. So to do that we'll look at, we change public.start or we actually add public.start so public.start is a static function which we'll check to see if it's already actually if it's already really been called and initialized on this element. So we pass it an element, which is the element that we're going to search for marquees in and then we're going to search for everything with data marquee. If we find anything with it, we'll call the public function on it which will do the whole get or make marquee and then when this library is included, we will call public.start on the whole body. So when this library is first included, it will process and look for any marquees in there. Now, if you're doing backbone code, you're probably loading your code, you probably actually have it that your HTML exists after you've loaded this file. So in many cases we'll actually explicitly call the public.start inside the view or maybe farther up in the router layer or something like that and you can just pass in the element for the view or you can pass in the whole body then again because we don't really have to worry because we have this protective constructor. So that's cool. Now, of course, we also want events, right? Events are a really nice way of finding out when things change and we obviously want an event to find out when the marquee reverses because that's incredibly important in life. So in order to do that we're going to set up a little event target on it. So you'll notice right now I'm doing everything in what they call vanilla JavaScript. So I had to actually see how to do this in vanilla JavaScript and Zaka says a really good post on it. So we create this event target object and it's responsible for basically making it possible to add listeners to our object and to fire and call back those listeners. So once we have that we can make our marquee extend that and then in our code when the reverse actually happens inside here we'll just say this.fire reverse and that means that in our outside code we can listen to that event. Now one thing actually I realized would be a better thing to do that we haven't done is we don't really have documentation of this event. So if you wanted to see which events this library triggered you'd have to go through the code and search for fire. I just realized this now but we really should have some sort of thing at the top of the library. Ideally you can get all the information about a library at the very top of the library. The read me, the default all that. So I think it'd be a good thing to try and figure out how to document all the events fired by our library at the very top. Similar to how you might do for your back bone views. Alright we want it to be AMD compatible but not required. So we ended up wrapping a lot of the code we use in this thing that makes it work in either environment. So at the very bottom we'll have this thing that checks to see if define is defined and if define.amd is defined and if so we just do this little define block and we return the module. Otherwise we just set window.marque module. So this way we can use it in our back bone code and not worry about cluttering up the global namespace. And then we can use it in our nasty gross PHP code and we'll keep cluttering up the global namespace but that's cool. Yeah for a good time just look at the window object in that codebase. So so far it's saying I was doing everything with vanilla javascript you're probably looking at some of those things going like you could probably do that better if you brought in a library and your code is not going to really work in any other browser than the specific Chrome hearing right now. That's all true so it's not that we actually do we don't actually write our libraries without you know like our libraries without other libraries. We very often pretty much all of our libraries actually do bring in jQuery right but we wanted to have the option to not bring it in right which may seem kind of silly but you know and when we do bring in jQuery it's mostly just for DOM and also the data function right so here I'll show where we can actually bring in jQuery to marquee so I can have a cross browser marquee it's really important. So we'll include jQuery on the page and at the top with the marquee module we pass in the dollar dollar and then we can use the dollar right so I changed my my ellen.marquee object so now I'm using the data function that's kind of a nicer approach to storing the object on the on the element and you know we're also using it for stuff like window width and CSS and at the very bottom I changed my define block to actually say hey we're relying on jQuery and so here we'll just you know use jQuery bring it as a dollar and return it with the dollar otherwise if we're in that whole global space then we just pass in window.dollar right so we're still compatible in AMD and non AMD environments and we can bring in these dependencies. Another great library that we use a lot is lucidjs which is a lightweight way to do event triggering so we'll often bring in lucid and the way to use lucid is you just let's say you say this dot emitter equals lucidjs dot emitter and then what you can do is do this dot emitter dot trigger so that's pretty cool because you actually don't have to extend lucidjs you can just kind of mix you know just have an emitter as part of your object and you'll still get the exact same API as I had before the dot on function and once again here we just say we've got two dependencies and we pass in the lucidjs or the window.lucidjs so that's example of where we might bring in two dependencies so I bring it in once it makes sense I probably would have brought jQuery in at the beginning because it's kind of easier to do stuff with the DOM with it and then lucidjs once I realized the event emitting. Another library we use often is Q and there's obviously like a whole talk about Q so Q is great for promises I did a scientific survey of my twitter audience to find out what's the best library for promises they all agreed it's Q so it's been proven you should use Q we also very often use underscore which is kind of an obvious one to use when you're in the backbone stack it's like you have underscore anyway so we use it for the data manipulation we often use it for extend for mixing together our options with our data attribute options with the pass in options with the defaults often used for debouncing but we'll just bring them in as we need them all right now we definitely want our library to be testable and this is something that gets me kind of sad a lot of times when I'm using a jQuery plugin especially when they announced that there's a new version of the plugin but there's still no tests because I'm like oh okay so can you just tell me what you plan on breaking or is this going to be one of those cool scoundrels so we really should be testing UI libraries and I think we should be testing them even more than we test our normal code because we're going to be using the UI libraries across multiple parts of the site and they're going they're much more often they're much more likely to be abused right because you'll end up having somebody who's never been in your part of the code base but suddenly discovers like oh hey there's this cool little library area I'm going to use it and then they kind of use it in a different way than you expected right so most of the times when people when we have bugs they're not really bugs they're just people using things in ways you didn't expect right so this is true for users using our site but it's also true for developers right is that they're just using them in ways you didn't expect and so you can try and write tests for them and then when somebody does use your code in a way you didn't expect that's fine you just introduce another test that makes sure it works right you're not it's nothing's going to you know work 100% from the beginning but when you start off with tests it's really easy to add more tests to check for those more obscure uses that you never thought of right so we typically use mocha, jstom, pie and sign on for our tests so I wrote some tests using that I'm on a chrome pixel so I had to do this whole slide deck just using everything in browser but jspin is cool so yay alright so we have our html where we include mocha and pie and sign on even though I didn't use it I just wanted to use sign on because so many people mentioned it yesterday that I was like I want to mention it too you should use it it's awesome I mean I include the script that's good right so here I'm using mocha and this is using the mocha browser runner typically I don't use the browser running typically I use the let me show you because I was really actually kind of upset that uh Trevor didn't show the awesome reporter so mocha has all these reporters so there's like the boring one which he showed um the one that everybody loves is the yawn cat reporter right that's the best right you know how do you make your codes awesome you just have a rainbow cat um anyway so you should use that one but here we've got the browser reporter and you can see I've got seven tests um so you can look at the bottom and check out these tests right so we're using the bdd style um I described my set of tests marquee I've got this mark this before each that makes a div um and sets html to scroll me baby one more time um and then we have some tests here so we checked that it sets the defaults correctly uh it checks that it takes an options correctly um it checks that it resets the options when we reconstructed with new options which is kind of a you know kind of a niche thing that we we um wanted to happen uh we check that it works to be declarative right so here I modify the original divide created and actually put the data attributes on it and then test that the options come out as expected um and I finally check the reverse event so maybe the reverse event will be the most interesting because I'm using the asynchronous um nature for the mocha test so you just pass in this done uh and this is a function callback and so once you actually get the reverse function then I call done right and so if this was never called you get this error for mocha that said uh time out of 2000 seconds exceeded right so that'll that's what'll happen with a sync test if you have this done callback but it's pretty neat how easy it is to do something like test it um so it's cool we've tested a lot of the code now I haven't run any jf coverage tool or anything to see how much we've tested but I do know there are some things I haven't tested because one thing that is very hard to test is the private functionality because remember how I hid all that functionality well now I can't I can't test it right because all I can test is the results of it I can't test um like it itself right because if this wasn't private um like if customized marquee wasn't private I would probably use sign on to stub it out and then I would check to make sure it was called once right and in some particular test right so uh we can't do that since we have no access to it from the test framework so this is something that we kind of struggled with like now that we did this fancy thing of hiding functionality how do you test it um and I've seen a few different blog posts about it I linked to one here um I can't I don't remember how we decided to do it ourselves because most of the time we just try to avoid having to test that private functionality but there are certain times when you want to um so I think in this blog post the guy actually recommends having a build process which strips that which makes it private so that in your testing environment they're not actually private but in your live environment they are that's kind of interesting other approaches that is that you could just have I could put marquee dot underscore private and assume that if you use that you knew you were using private functionality but that's that's kind of you know you guys crazy developers you're just gonna use it anyway like private I don't know what you're talking about is that a word um so yeah I think that's kind of that's a interesting question um I think that's something to explore we also want to document our libraries all right um I was kind of upset when I realized uh at the end of this year that I'd written so much code at Coursera and basically documented none of it so I basically I went on this documentation spree where all of my PRs were simply documentations for things but there's great because they get instantly uh approved you don't even have to go through a process we were like yay documentation all right so for libraries the way to document it is just you know put something at the top so I'll very often start up with why does the library exist because I think that's a very valid question right like why aren't we just using the marquee type why did we find the need to make an entire library from marquee type right in this case it's because you know the designers are constantly making us do marquees and we just figure out we'll just make a library of it right um and I might also mention like future work for the library right like emulating blame um so and then you have the how to use this library so that's what you really need to have is how to use and you might think it's really really obvious because we all think our code is really really obvious or we think that oh you should just read the code you're so lazy whatever right like we have better things to do you know how to use the library just write it in there right that's all you have to do if you're using a library that doesn't have documentation and you've now used it successfully just document it because clearly you at least know one usage of it that works right um so you like you'll show the basic example you might show the declarative example you might show some some things about options right um and then every time I use the library and I didn't find out what I wanted in the read me I'll just add it add it to it right and the bonus is like if one day you decided like open source it make it all legit and shit you'd already have your documentation legit and shit it's time to work all right so uh the marquee library is something that I only just made up for uh this talk um but uh I'll show some real-world examples here although am I actually am I supposed to be done now because my time says 1130 but I don't know what time that is here okay we'll keep going so uh here's the read me library the read me library is something that pops up this little banner at the top of the page um which is pretty cool and you can say like so it's like for announcing things right we want to just give you this little announcement so you can say how long it should be up how many times they should have to click it before it re-shows so we use it a lot to show to tell admins about new functionality we also use it to tell students about new functionality um and we we kept finding ourselves doing this over and over all over the code base so we just made a library for it right um so cool things is that if you just specify data read me close on anything inside the read me it'll prompt the read me to close you can add a close icon you can have a link that closes it so a lot of times in our libraries will kind of have these data attributes that you can add in things inside the DOM and they'll trigger something inside the library right and to reconstruct it we can just pass in the that DOM so you can actually browse the code I just did a snapshot of it right it's not like a fancy real open-source library but there's a little snapshot so you can browse through and see it um it's very similar to marquee modals I'm sure many of us have written like boxes at some time in our life so we of course have our modals so with our modals we'll um we'll have our div which has a modal on it and we also we often use the boot strap classes inside of it but it's not required right so that's one of the things that we often have the CSS optional so that if you do want to bring in the boot strap classes and have your modal look at bootstrap you can but then there's some places we don't like the main Coursera lecture viewer doesn't use the bootstrap classes looks completely different but it still uses this modal class because there's so much stuff about it that has nothing to do with what it looks inside right it has to do with how you get positioned on the page and then we have ways that we can get links on the page to actually open up right so the code maybe is a little more interesting because it enforces the singleton right so a lot of times you have these libraries you only want one of them to exist so I think the fancy name of that is singleton so we have this code that will actually check and make sure that there's only ever one modal that's open and will go and close previous modals right so sometimes you'll need those libraries this is kind of awkward to have two modals even if you're doing your tasks so we also have popups which are home tips or drop downs whatever you want to call them kind of like the bootstrap popovers so one thing is you need this is that you'll notice there's a lot of HTML this is because this is the amount of HTML you need to make a popup class accessible right so one of the things that Coursera has to do it has to be accessible I would get accessibility audits like every three months with the list of everything that was inaccessible about our website which is always really really fascinating and a lot of them would have to do with libraries right there's a lot of libraries out there that are not accessible like if any of you have used select two it's great not accessible at all if you've used any of the bootstrap plugins generally they're not accessible so one of the things that we end up building into a lot of our libraries is accessibility and if we can't build it into the library itself we usually document in the read me and say listen this is what HTML you need to add in order to make sure that you're using this library in an accessible way right and for doing something that pops up in something you have to have all this aria stuff to save the button and also to say that it expands something else on the page so accessibility is something that's pretty important to us and ideally you could work into a library but you can't just document how right and so we've got tons of other libraries too and you know you can imagine all the different ones we've had so you've seen there's lots of principles here and the general idea behind them is just to make it better for developers to use your library you want them to be happy you don't want them to hate you right they're like this person didn't document and I keep messing it up and it's really hard to use and then they're just going to be glaring at you from across the cubicle and you'll just kind of run away and cry in the bathroom which is what I do a lot but you might look at all this and think like oh couldn't I just do all this with jQuery plugins yeah yeah you totally could right you can do all that and bag chips but and you should right like these are all just principles that kind of things we discovered while trying to come up with these UI libraries from scratch but these are just things to think about when you're evaluating a jQuery plugin if you're writing your own if you're writing a UI library without using jQuery plugins I think these are just things that we encountered that you should think about in those situations so you know see where you can apply them or if you don't like them don't apply them to school just you know share next year what you've learned about doing UI libraries and that's the thing right I think the point of a lot of things today is we're just sharing things that we discovered ideas we've had about nice ways of doing things and it's really good to expose yourself to all these different ways of doing things but it doesn't mean you should run home and go do everything in your code right it means that you now have this idea of all the possible different ways of doing things and you can kind of evaluate them and keep them back in your head and figure out what works best for you or invent something completely new alright thank you hey just a question about all the data attributes and so I'm assuming that you have the potential there of having a lot of them on the page and having multiple libraries looking for their own selectors have you guys thought about that at all like overlap between the data attributes right just the efficiency more just the efficiency of doing data selector so every time I talk about using data selector somebody points out that they're not very efficient for doing stuff right which is true you can look at a js perf and selecting via data selector is not as performant as selecting via class or id but I feel like the performance different is negligible at least in terms of I think our performance concerns are at a much different level than at that level right because when you look at js purpose like there's a post on that as well it's like oh you can do 30,000 of these versus 10,000 of these in how many millisecond so I think that the performance my perception is that our performance issues are at a different level and so I would rather have the developer productivity gains of data attributes then and have that performance hit which I suspect is negligible for us if you're doing mobile or something like yeah you could definitely consider that