 So I have been doing web development since I was a tiny little nugget. I'm an engineer at Sony I founded angular UI which might get some hisses and booze, but Angular UI is to angular what jQuery UI is to jQuery. We were like the unofficial partnership Thank you. I was I was feeling a little weird for some second there And I learned a lot about open-source organizations and library maintenance and how much I hate people with bugs who don't read documentation I used to do cake php in jQuery when I really got into web development And now I work at PlayStation Where we do view which is a competitor to cable and I also maintain my mustache Which is something that should go on my professional profile for some reason So I'm gonna lay on some general knowledge just because I felt you guys really wanted to hear about it And this is not specific to anything. It's just practices I've kind of learned from being a library developer and maintainer and It's just kind of important to me. So first of all, I actually view API design as a form of user experience I'm sure everybody in tech kind of wants to get into user experience and graphic design one way or another but One of the things I view is every single time you write code If you're thinking about how other people look at your code, which only tends to come about from digging really heavily into the open-source community You really start thinking about API design What are your method names and variable names and you spend hours wasting time on that stuff? But it actually comes in really handy if you can really kind of focus on certain things and the one thing I think is generally the most important. It's not conciseness or efficiency or performance or any of that other crap It's how quickly can I refactor this code? And if you can always focus on that or keep that in the back of your mind Then all the other problems will usually be addressed really well if it's not perform it now, but it's refactorable It's perform it later if it doesn't look really good now But it's refactorable it can look good later and the main thing is the one inevitable Thing in life is death taxes and the fact that you're going to have to refactor your code or it's gonna go in the crapper One of the things I find personally is a little more relevant and this might get some Complaints is I don't do convention too much over configuration And that's actually something that is a strength in a framework like ember and in cake PHP and Ruby on rails but it's not a strength for a library because learning conventions takes a while and it's you look at code and you see oh I need to use these keys these properties and Only somebody who's been working in it for a while says oh it's totally easy You just put this here and put that there But you have to go learn that and the old most of the time I bet you 75% of the knowledge You guys have now was word of mouth after slamming your head on the desk for a while and going bald like me So pretty much as a library developer if you've not heard about composition or composable code Look into it. I won't dig into it too much But the main thing is usually you have code and you kind of write the lines that kind of build an object and form it Until it's something like what you finally want as a result But it just makes your code clearer to somebody who's digging in and he doesn't have to know Conventions because how you set up your code is right there in front of you now You can always use conventions and doing that, but Try checking that stuff out I don't like obfuscation because if you're just wrapping everything in a function because it's slightly more convenient to call a method of Get projects instead of calling a URL with the core library that is literally Slash project slash get or something like that. You're a moron Because you're just making more layers in the stack trace for me to debug through and you're making everything more confusing for everybody else last thing is You know JavaScript doesn't have a whole lot of privacy And a lot of people complain to me about that and they underscore prefix everything and I don't actually view that as a Really bad thing if you view your internal code your private variables your private methods as public if you just pretend that Eventually someone's going to use this no matter how obscure or ridiculous or insane it is Expect someone to use this code then when they're debugging it They will be inspecting your objects and looking at all the properties when they're looking through your code because you didn't Document it very well. They will be finding these things and if you build small modular simple Nuggets of functions even in your internal API, it will be easier for you to understand what the hell you were thinking when you come back later will be easier for other people to come in and help you and just Stop worrying about making everything private. Just let go be Zen No one likes your code in the first place Cool 30 wasted five minutes I Apologize if I go too fast feel free to tell me to slow down and speed up or get with the program So I'm due note and I've been working on a node library in view for PlayStation view And it's a core architecture library. It's essentially a bunch of business logic, and we have a bunch of consumers We have a I got to make sure I don't legally break any rules Chromecast We have an iOS device an Android device We have obviously the PlayStation console we have Roku and we have some more devices coming out soon And the main thing is we don't want to do all the convoluted business rules such as does Time Warner cable or does Disney or does Showtime actually allow us to show this episode at this time to this consumer in this region in this neighborhood during this hour of the day on holidays And it's convoluted is all hell So let's put that in one place and let all the consumers use it And it's a little bit weird having iOS hit JavaScript for some business logic But it makes everybody's life easier in the long run. So that's kind of what I've been doing and The reason why we went with node is the main thing is when I picked up the library There were a lot of bad practices, and I think I might have gotten Jaded towards node of the ember community because of the bad practices in this library And I think I might have been misguided in that assumption But the main thing I've done is I went back to the code which was written very heavily parallel to our ember applications and I took out all concept of ember and I just said this library this core architecture is node first Everybody else is a second-class citizen and the main reason is node can be used anywhere But an ember add-on cannot so if you want to have code that's reusable across clients and consumers and architectures and platforms I decided let's go with vanilla JavaScript, which has no browser has no framework As much as possible no libraries, and it's just kind of made things a lot saner for us See here Everybody loves ES6 you guys are using ember so you see it all the time for me It's a little bit newer because there's no standards and practices, but God as it make life wonderful I actually found out that if you you put a use strict at the top of all your javascript files Certain versions of node will actually out of the box support ES6 Now which versions of nodes support ES6 and which ES6 rules are supported is a little here or there But the bottom line is if you're really really close-minded and don't care about any of your consumers or environments You can make your life way easier just by developing an ES6 and running in native Node because your stack traces are not going through source maps They're not going through compiles and watches and builds. It's literally I'm just running ES6 in my browser and debugging it and it's awesome You want to learn more about what features are supported check out node.green, which is a website It was weird I'm like I needed like a triple w to confirm that that's actually a website And for everybody since that's a naive world I do actually need to make my code which is again node first accessible to node consumers and by doing the best way I did that was compile a node tree a source tree, which is a one-to-one copy of my vanilla So I have an ES6 tree and an ES5 tree and the key is it's a tree It is not a bundled browser-ified minified distribution file that I'm distributing over the node package network And I say that because I've had teams think that we're compiling ES6 into ES5 Let's just package it like we're used to doing in a browser and give out everybody this one tiny file And you're insane for doing that. You're working on the local file system. So there is no extra overhead and The problem I'm probably going into things you guys don't need to know about is I've had people who will bundle node libraries and they'll build distribution files and it's a nightmare and This is a pitfall most of you probably already know but some of you may not and I highly recommend paying attention right now I'm developing a library and I use dependency A and B and I decide to bundle that Using browser if I roll up something like that and I distribute that just because I I wanted to use ES6 and node Consumers externally or any other consumer can't use ES6 They I cannot assume they have an ES6 compiler transpiler or something like that So I bundle and browser if I and all that jazz and when you do browser if I roll up You get all your sub dependencies packaged into one file and then another guy comes along He's an app and he wants to use my library, but he's also using the dependency number letter B And what happens when you bundle it again? You get two copies of dependency B You may think that browser if I and roll up is going to be smart enough to catch all that, but it's not so one of the solutions I've had is Don't do superfluous Compiling don't do superfluous bundling if you're bundling in multiple times throughout your process And now for me, I'm lucky I'm of the library developer and the apps are also my co-workers in the wild that might not be as plausible But if you're at least developing a library try to keep the amount of time you're compiling or bundling to an absolute minimum in the entire process lifespan But as you can see this is obviously going to bloat my file size. It's going to bloat memory It's going to have multiple versions. I'm going to have a lot of breakages and I'm just going to go more bold So Essentially for me, I told you I wanted an ES6 tree and an ES5 tree and I kept the tree So this is a simple way of me setting up compiling for my ES6 This is for node library maintainers my package.json has got actually to my main points to my compiled tree So when a node library depends on my library, they won't use my source tree They will use my compile tree and this is simple configuration But the key one of the things is I don't put the configuration inside of my package.json Because when it comes to distributing for browserify Well, I'll get more to that later, but So files are local They're smaller and the building is faster if you go from a source tree to a build to a build tree and incremental changes are faster If you went to one giant build file, even though one small file changed you'd actually have to regenerate a one megabyte distribution file So getting to the actual point. How do we bring node and ember together? For me the answer was ember browserify which I've been instructed is currently under some Heavy rework and will have certain functionality Polished such as bringing in node packages multiple times and some other pitfalls I actually never ran into so I've just found it to be awesome salvation to my sanity But it generally seemed to be the recommended solution for ember moving forwards If you want to use node in ember telling you right now check out ember browserify It does some awesome stuff all the node all the packages you import via ember browserify get prefixed with npm colon It looks just like a normal import Except you can tell what came from node and what didn't and I highly recommend Dropping the bower versions of the packages and dropping the ember add-on thin Rappers for packages because if you can get as close to the original core library as possible You're getting closer to the guy who actually developed it You're having less opportunities for breakage down the life cycle, and it's just you know, it's easier to upgrade It's easier to maintain just all that shit comes easier and the best thing is browser if I can actually compile and Again, I mentioned you don't want to do redundant compiling transpiling bundling you might think okay I'm going to bring in this node package, which was an ES6 tree compiled into an ES5 tree into my ember package So I would point it to the ES5 Compiled tree and that's bad juju Because what happens is you have two sets of watchers the ES6 watchers, and then the ES5 watchers then you have two sets of waiting you have to wait for it to compile from ES6 to ES5 And this is if you're developing the node library alongside your ember application and Then you also have two different build approaches you have one way of built compiling from ES6 to ES5 and then you have the ember approach to compiling from ES5 into a bundled server and Source maps will probably break if they didn't break you've probably lost months of your life Instead figure out how to get browser fi to do all the magic for you, and it's really cool Just by adding this configuration to your package.json you can actually get browser fi to Automatically transpile your library without the guy who's browser Refying you having to know how the hell to do that in other words. I'm building an ember app, and I want to use Library a library the library is written in ES6 And I don't want to use their compiled code because I want to develop on that library I don't want to have to had any idea if he used ES6 type script coffee script I don't want to have to know how to get his grunt or gulp or any of that other stuff working I don't want to have to know about his ES lint I just want it to freaking compile when I compile the rest of my code And I want it to work and the great thing is if you put a browser fi section into your package.json Specifically if you are a node library developer and you have this in there Then this is how you will tell browser fi This is how to transpile my package and the cool thing is the developer doesn't have to know this and it will recursively down the entire node dependency tree All you need if I want to use the babelify transform, which will go from ES6 to 5 I Bring in some dependencies, and I actually make them production dependencies not development because when you think of what Dependencies people are going to download when they install your package You got to think of if I'm downloading you as a library inside another package That's production if I'm downloading packages while I'm sitting right in that library. I'm working directly on the library That's development, so I cannot make these dev dependencies even though they're pretty much for developing on the package Because I'm actually using this node library inside another package so there's the babelify plugin and the presets and Again, I'm using the RC file That's the advantage of not putting it in the package.json because I don't have to put it in there I don't have to put it in a grunt or a gulp file or a bunch of other places Every single thing that runs it through babel will use this file and So moving on So back to the library figuring out how I can develop a library and How I can make it work with ember really well and not have to shoot myself What can I do without ember in other words? What can I do in my library that ember will not bulk at? I can use classes. I can do perform queries to the server I can perform I can provide read business logic such as get Person dot get age get name things like that and I can provide static utilities What can I not do well the key to my library is actually I'm building a essentially an alternative to a data server a back end which in addition to querying the data will actually turn the data response into objects and provide business logic on the objects such as like Get the as I mentioned is get age and things like that But what I can't do is once these objects have been placed onto the view and you can place Pojos onto the view that took me a long while to figure out I don't have to turn everything and its mother into an ember object I repeat you do not have to turn every single object into an ember object to render it out It works perfectly fine with pojos, which means I can actually develop a node library and it will work for ember I need to do certain things to make sure the rendering works fine and that's usually rights I can read all the data. I can provide a get methods in vanilla. J s or in my case ES6 JS, but I cannot perform rights because once a property once person age is placed onto the view The as soon as I go and say person age equals 12 And I do that inside the library for instance. I say grow I have a function called grow I do person grow inside of that library It says this dot age plus plus that will throw an error and even though I wrote all that code in ES6 without the concept of ember Simply because it was a right it will throw an error and the ember templates won't update and all that jazz and it took us a long Well, we actually copied the entire class definition our ES6 vanilla class definitions and pasted them and created ember class definitions which had nearly a one-to-one copy except we did ember dot set instead of this dot age or something like that and the bottom line was once we realized we don't have to copy everything over and Most of the time I don't even have to write stuff if you're really working with data retrieved from the server At least for us. This is kind of we get to be naive We don't we're rendering like a TV guide and those things don't change that that much because users don't write to the data Most of the time they log in and then they pull shows and episodes and things like that from the server um, but What we were able to do was say all rights will be isolated to ember and all reads and everything else queries will be isolated to vanilla JS and That was actually really great. So this is my vanilla library. This is a Super simplified of pseudo coded version of it I've got a class which pretty much just takes when you construct an instance of it It takes a data and copies it on to itself. I've got another class which extends it It's got a static method so I can do project dot get three and it will pull out the Project record number three it will iterate over the response convert it into an instance of itself which again calls the Parent and then I can do things like once I'm done mapping the data on I can go through its children properties And I've got this really clear concrete contract and API and code and this is really refactorable I have to say but the main thing is This is all reads and this is data retrieval and I've actually had some people ask me Why aren't you using ember data in the bottom line is I want to be able to use this outside of ember I'm not even going to dig into this too much because I'm already behind So this is actually a little broken. So I apologize Yeah, you're not missing too much This is the ember wrapper So we had a vanilla node package Which we called view services and then we have an ember wrapper which we called view ember services and it literally was a helper to Bring in all the vanilla logic business logic into the ember world and kind of do some small poly filling The main thing I wanted to point out is if you're building a companion library Do not make it an alias for the core library You want people to access your what you would normally hold close to your heart as private internal code I want people to call the vanilla library using the npm colon prefix and then additionally in their app Call my ember add-on and I want them to see a clear distinction between what came from the original code and what came from the add-on But one of the things I can do is I can actually you know monkey patch This goes into the pulls in the base class and adds ember like functionality So now even though I'm not using ember objects. I can kind of do person dot set person dot get again The node library will not internally call these functions, but as long as I only have reads That's not a big deal You can use ember dot get everywhere or this duck yet, but it's not absolutely necessary. It helps with caching But for us we were not using performant Concerned queer reads from the object. So it wasn't and as long and ember dot set Correct me if I'm wrong does actually write to the original object So using a ember dot set and a vanilla object dot get object of property should work perfectly fine And then we so going back I take my in my ember add-on I configure the core library, which is a node package and I can even let this is let's say a static Singleton of fat implementation of the library. You can only tell by the lowercase c in the capital C the Singleton let's I mean approach to this API is you configure it globally. I can give it a promise implementation We did this because we don't want 40 different copies of a promise library floating around your bundled file Because this is just one package, but imagine all the other packages that kept yanked in here And then I can configure it or I can my add-on the one thing I would say this is kind of like an alias, but not really I'm actually creating one instance of it and I know upfront how to configure it for ember If you need more configuration information, you know what? I'd probably just pass it through to the app and do the configuration at the app level So to pull this off is a little tricky The main key for me was how do I develop a node package? Alongside an ember add-on for ember apps and we had to kind of build this tree So this is my app. This is an ember application. This is the file system. I need to eventually reach I need my ember browser if I and I wanted to use it at the top level because I actually Wanted to say if you're gonna use my node package you got to use browser fi And if you're gonna do it in ember you should use ember browser fi And it might seem like a hindrance that I'm putting this expectation on you But trust me once you can start npm colon importing anything your life will just be a hundred times easier You'll open up in a whole new ecosystem to yourself now in the add-on which is a companion for my library I've got you know your add-on code This I'll explain in a minute, and then I've got a blueprint and then in my core library I've got My package which will hold the browser fi configuration, and I've actually got the things that Assist this package in being browser-ified essentially the babelify and it's preset now This might get redundant, but I really don't care because that's just during the build process This is what the configuration looks like so the thing is I mentioned This is the tree I want to achieve This is one two three dependencies if somebody wants to consume this application. He has to do three installs But if you do this he does one install If I'm in a node world that I want to create a kind of contract to say if you want to use this ember add-on You should be using this package and this package alongside it. That's a peer dependency And I know peer dependencies are going away, but you should still look into them Peer dependencies for those who don't know means the package sits next to you not underneath you Which means your parent can use the library? So if I have a dependency on underscore and the app has a dependency on underscore I can say I want it to be a peer and we'll both share the same copy. I won't have my own copy But the new version in NPM is kind of making that optimized This is the real magic if you do an ember install of the add-on It will automatically install the browser fi library at the top level and the other vanilla node library at the top level so now I've taken what was essentially a a one line I Gotta go back to that a three line install into a one line install and then this is my add-on so I can use the NPM colon import anywhere in the library in the add-on and As long as you know, here's the tricky part Because of how ember browser fi works. It won't detect NPM Colon prefixed imports in your add-on tree. It will detect it in the app tree So throw a file together that you never run and all it does is import the library I don't even need it to be from I can literally just make this import and once you do that This import starts working. You never have to execute this code. It just has to exist so that Ember CLI can see it and it will automatically add this package to its dependencies When it's bundling and now my install is one line and my usage is pretty much This is the app. I can use both the core library in the add-on. I can just directly Statically access a core library and perform methods on it Or if I wanted to use the instance version which the add-on humbly provided for me all pre-configured I can do that too and That's my presentation There you go. In spite of the fact that Dean's watch is broken. He ended precisely on time It's not actually broken. It's just a style statement right now And out of energy because charging our watches and all that other fun stuff So that means we have an opportunity for questions anybody have questions for this wonderful person Is it because I said I worked on angular because Wax mustache wax Yes, I made it myself and I have business cards with that on there if you'd like I also have like five or ten PlayStation assorted PlayStation stickers if anybody'd like Hit me up afterwards Yes, this library is being used on a variety of platforms the the way JavaScript is consumed on an iOS environment is iOS actually has a virtualized runtime JavaScript environment and the it kind of uses like a send message Syntax I believe I could be wrong, but it has a virtualized in a runtime Sitting inside the iOS runtime that is JavaScript and we it communicates with it through that Same thing happens through Android and we tried to use essentially a socket type syntax to Streamline communication and standardize it so we can bring in other platforms because PlayStation Actually communicates with this and they've got a few different ways of how the PlayStation source code works But yeah, hopefully that answers the question Cool. Thank you