[Laughter]
CHUCK:
AJ, I'm just DoneJS, just DoneJS. And I'm leaving because I CanJS.
[This episode is sponsored by Frontend Masters. They have a terrific lineup of live courses you can attend either online or in person. They also have a terrific backlog of courses you can watch including JavaScript the Good Parts, Build Web Applications with Node.js, AngularJS In-Depth, and Advanced JavaScript. You can go check them out at FrontEndMasters.com.]
[This episode is sponsored by Hired.com. Every week on Hired, they run an auction where over a thousand tech companies in San Francisco, New York, and L.A. bid on JavaScript developers, providing them with salary and equity upfront. The average JavaScript developer gets an average of 5 to 15 introductory offers and an average salary offer of $130,000 a year. Users can either accept an offer and go right into interviewing with the company or deny them without any continuing obligations. It’s totally free for users. And when you’re hired, they also give you a $2,000 bonus as a thank you for using them. But if you use the JavaScript Jabber link, you’ll get a $4,000 bonus instead. Finally, if you’re not looking for a job and know someone who is, you can refer them to Hired and get a $1,337 bonus if they accept a job. Go sign up at Hired.com/JavaScriptJabber.]
[This episode is sponsored by DigitalOcean. DigitalOcean is the provider I use to host all of my creations. All the shows are hosted there along with any other projects I come up with. Their user interface is simple and easy to use. Their support is excellent and their VPS’s are backed on Solid State Drives and are fast and responsive. Check them out at DigitalOcean.com. If you use the code JavaScriptJabber you’ll get a $10 credit.]
[Let's face it. Bookkeeping is hard and it's not really what you're good at anyway. Bench.co is the online bookkeeping service that pairs you with a team of dedicated bookkeepers who use simple, elegant software to do your bookkeeping for you. Check it out and get your free trial today at Bench.co. They help you focus on what matters most and that's why they're there. Once again that's Bench.co.]
CHUCK:
Hey everybody and welcome to episode 202 of the JavaScript Jabber Show. This week on our panel we have AJ O'Neal.
AJ:
Yo, yo, yo, coming at you live from the snowy sunshine of Pleasant Grove.
CHUCK:
Aimee Knight.
AIMEE:
Hello.
CHUCK:
Joe Eames.
JOE:
Hey, everybody.
CHUCK:
I'm Charles Max Wood from DevChat.tv. Quick shout-out for React Remote Conf coming up here in about three months. We also have a special guest this week and that is Justin Meyer.
JUSTIN:
Hey everybody. Very happy to be here.
CHUCK:
Do you want to introduce yourself?
JUSTIN:
Yeah. So, I'm the CEO of Bitovi, a JavaScript consulting company. We've been around for eight years. I'm the lead author of JavaScriptMVC which was a library of not, a framework of note maybe… it was built eight years ago. Probably peaked six years ago, and then I built CanJS. And now, released DoneJS and StealJS and a bunch of other libraries that you may or may not have heard of.
CHUCK:
So, do you want to give us a brief overview of what these are?
JUSTIN:
Yeah. So, the history of that would be I left Accenture eight years ago because I was disillusioned there with just how that kind of consulting operation worked. I felt that their business model didn't work very well and I wanted to do something where it was I would say more, people are actually developers who were most of the people working on a project. So, I started a JavaScript consulting company because I've done a little bit of JavaScript work with a friend of mine. And back then, this was eight years ago, there was really nothing. It was really easy, a perfect time to get started doing JavaScript consulting and building frameworks and tools and things like that. Because nothing existed.
Built the parts of JavaScriptMVC while working on this big T-Mobile application, and then just started doing consulting around that. So, JavaScriptMVC is basically what everybody I think, what everybody uses now. It was a dependency management, build systems. It was MVC which is, nobody does it anymore. But templates and models and views. And then, testing and stuff like that baked in, and a documentation engine. Anyway, so I built CanJS and that… So, we built JavaScriptMVC and then JavaScriptMVC wasn't taking off really, because Backbone had been released. And Backbone was really small and I think a lot of people wanted something smaller. It was too much to take on all of these, dependency management and all of these tools that you just wanted something simple that would work for a small application. Because, I don't think people were building a lot of big apps back then.
So, we extracted the MV* parts out of JavaScriptMVC and released M as kind of a standalone package which was CanJS. And then since that time we've been upgrading and maintaining CanJS. We also split out the dependency management parts and the testing parts and the documentation parts all into individual libraries and have been maintaining those for four years now.
And then about two years ago, we decided to get the gang back together again and rebuild what was JavaScriptMVC but JavaScriptMVC was built in Rhino because that was the only [chuckles] JavaScript interpreter at the time that would run on the server, or the most popular one. We rebuilt it all in Node and upgraded and added a bunch of new features. And then the result is now DoneJS which comprises of CanJS, StealJS, FuncUnit for testing and DocumentJS for documentation. And then it has a bunch of other little sub-libraries that's all different problems like server-side rendering.
AIMEE:
I guess my question was because I'm big on making comparisons since there are so many things out there right now and for people like me who are not as versed in all the different options, immediately it came to mind, how is this different than Meteor? So, maybe before we go too much further you could compare it to that.
JUSTIN:
So, I think it's similar to Meteor except that it runs off of any backend. As long as you're making RESTful services, and even if you're not, it really doesn't care too much what you're doing on the backend. But then feature-wise it's very similar. It uses… it still has real-time but uses a technique very dissimilar to what Meteor does. It doesn't have a database on the client. And it doesn't assume a certain database or backend. And so, it uses what we call set algebra to be able to do real-time updates of the list that the site knows it has loaded. So, Meteor is probably what it's closest to.
I would just say it's… I said this actually at the UtahJS meetup the other day, is that if I'm trying to be as intellectually honest as possible I think if your backend can be written in Node and you can want to build off what Meteor expects in the backend, Meteor is probably the more appropriate solution. But if you want to be writing Python or .NET on the backend, I think that DoneJS would make your life a little easier. Or I'm not even sure how possible it is to do that in Meteor. But it seems like it's not super easy.
AIMEE:
Cool. I love honestly. That's good. [Chuckles]
AJ:
So, to me that sounded like it's similar to React in being smart and similar to Angular in being a frontend. And I'm not really familiar with Meteor. I didn't like it when I tried it. [Laughter]
AJ:
So, I need a different comparison to make me feel better about this. So, aside from Meteor… [Laughter]
AJ:
What is it like?
JUSTIN:
Okay. So, I listened to the tools fatigue episode.
CHUCK:
Mmhmm.
JUSTIN:
And people were talking, you guys were all talking about the problems of how long it takes to set up a JavaScript application. What DoneJS does very well and I think Meteor helps with and Ember helps with is that it sets up server-side rendering, real-time behavior, dependency management with ES 6 and hot module swapping and high-performance builds and all of the stuff that you really want and should be doing, testing built in, documentation built it, it has all of those things ready to go right away when you initialize an application. So, in that way it's similar to Meteor.
But when you say React is smart, I'm not sure what you mean by smart. If you mean it only updates… React's real thing is the virtual DOM diffing and things that derive from that as a technology. It doesn't use virtual DOM diffing but it uses observables. And I can go all into the difference between where I think observables are more applicable or the benefits and disadvantages of observables versus diffing in terms of technology. But I guess I need to know what you mean by 'React is smart'.
AJ:
That's what I meant, well as far as I know. People talk about React like it's a framework but it's really just a view.
JUSTIN:
Yeah.
AJ:
So, it's the real-time-y-ness that it enables is the diffing and the being intelligent about not wasting…
JUSTIN:
Ah.
AJ:
Like something can happen and it can update the page and the page can update, rather than… like with Angular if you do it in a very naive way instead of doing it the Angular way then you can end up actually waiting for a list to load.
JUSTIN:
Yeah. So, those things are all solved in CanJS. But to be specific here, when I talk about real-time React really doesn't help you with, when I talk about real-time behavior. When you want to say, “Hey, if this person makes changes on this page, how are you going to communicate those changes to another page so it updates correctly?” you have to set up all of that plumbing yourself in something like React. Where CanJS, it's more baked in for you. It's baked in and I think this is actually one of the coolest parts of it, is it's, when I was talking about it's set algebra, if you request…
AJ:
That sounds cool. I want to hear more about that in a minute.
JUSTIN:
The set algebra, it is a cool sounding word. So, you know sets like Venn diagrams?
CHUCK:
Mmhmm.
AJ:
I love those.
JUSTIN:
Yeah, those are great. When you request your data from a service layer, let's say of course a list of to-do's. You want to list of to-do's that are let's say, due today. Well, you're requesting a subset of to-do's. Your parameters are the request might look like 'slash to-do's question mark do equals today'. But that represents a subset. And what we can do is say that, oh, by knowing that the person requested to-do's due today, as long as we're getting messages when to-do's are being created, we know if the to-do being created belongs in that set of to-do's or if to-do's are being updated, if they're moving in and out of that subset of to-do's that are due today. And we can basically update the list that the client has loaded.
So, the client's loaded the list of to-do's. They're due today. And we can basically add or remove things to that list using set logic. And you could create your own set logic that handle things like sorting and ranges and that kind of thing. So, you don't have to have a database in the client and you don't have to have special, what is it called, live query or something. You don't have to have any of that. You just have the basic RESTful services. Just somehow your server just has to send these updated, created, destroyed messages to DoneJS and it takes care of updating everything for you.
AJ:
I like that.
JUSTIN:
Hopefully that makes sense. Yeah. [Chuckles]
AJ:
That makes sense. I appreciate the explanation. And just so you know, while I'm on the show you can go as computer science-y as you want, because I'll make the listeners enjoy it. [Laughter]
AJ:
With my mind.
JUSTIN:
Awesome. I can go very computer… good, I like that. I love to go computer science-y.
AJ:
You just have to stop and answer Aimee's questions.
AIMEE:
Yes, I'd enjoy it too. But yeah, you might have to answer questions along the way. I'm googling as you talk.
CHUCK:
Here's the thing, is we've gone a little bit deep into the weeds as far as how DoneJS does its thing. But what I'm really curious about is let's say that I am Joe programmer. I'm reasonably new to the whole frontend, frontend framework kind of area…
JOE:
Hey, I'm Joe programmer.
CHUCK:
Oh, sorry.
AIMEE:
[Laughs]
CHUCK:
I'm going to be Joe programmer for a minute anyway. But I guess the question is how do I get started with DoneJS? I look at it, I see the benefits and I'm like, “You know what? This really looks like what I want.” So, how do you get started with an application? And how do you build your app from there? How do you architect it so that it winds up with the DoneJS way?
JUSTIN:
Great question. So, on the DoneJS website there are two guides. We have a very basic guide that's building the real-time chat app, the hello world, and it's built with all the performance flashy features that DoneJS provides. And you can export it to a native desktop app through NW.js and you can export it through an iOS app through Cordova. That's really a fun one. But we also have a restaurant ordering guide called Place My Order and that's a much more comprehensive guide that walks you through how it's built architecturally, how to set up routing.
And then what I really like about it is it shows you how to set up tests with continuous integration, continuous deployment through Travis and through Heroku, and sets up things like content, uses a CDN. So, that shows you how to more or less architect it and how to make it work in a development ecosystem. Yes, NW.js is Node-Webkit. And then I would say to follow that up it's really about once you're set up with the… DoneJS is mostly a super framework but most of the meat of what you're building is CanJS. And then CanJS has a lot more docs and guides and things like that.
Architecturally it's, MVVM is the architecture. And this is what I really like about it, is how, well I would say that there are two things to care about. One is what we call modlets. This is something that I've been big on for eight years. And every time I give a talk which isn't very, very often, it's one thing to learn I think from how Bitovi develops… it's the modlet folder organization where if you're writing, working on a module, all of its tests, styles, documentation, and a demo page, and all code for it are in one folder.
I really disagree with the approach where sometimes people have a test folder separated from where their actual code that's being tested is. We like to make it so that everything works in one folder. You can write that module, test it, see it working, and a demo page separated out from the rest of the application. So, that's how everything is organized in a DoneJS application. And then it's MVVM, so everything is, you're building custom elements that are controlled by a view model. An observable is the view model. And when it changes, the template automatically updates itself to reflect those changes. So yeah, Charles…
CHUCK:
Yeah, I put in the chat I just have this distaste for certain terms like webinar. Like it's a horrible word. And then I recently heard 'micronar', and modlet is right up there. I'm sorry.
JUSTIN:
Oh no.
CHUCK:
The name just kind of makes me go 'Ugh'.
AJ:
I loved it, Justin. I loved it. I got your back, bro.
JUSTIN:
Thank you, AJ. [Chuckles]
JUSTIN:
Well, if you don't like the term, hopefully I can convince you on the practice.
CHUCK:
Yeah.
JUSTIN:
Because for us we build a lot of big systems. And if you have a lot of developers cranking out code, you don't want to have to load the entire application to see your widget. And I actually think it helps people design better modules if they're building it so that that module can, they can actually make a demo page for it, a test, separated from the rest of the app.
CHUCK:
Yeah. It reminds me a little bit of components in React or in Angular 2. And it makes sense. You have an encapsulated section of functionality that you then manage through whatever other means you're using to pass messages around on your frontend. So, I like the concept. I just hate the word. [Chuckles]
JUSTIN:
I think the difference is when I'm talking about modlets, it isn't necessarily how you build stuff. It's actually how you organize your files.
CHUCK:
Okay.
JUSTIN:
You have a folder and then the test for that same… the module's in that folder and the test for that module is in that same folder.
AJ:
So, couldn't we just call it an npm module and be done with it?
JUSTIN:
You could break out your entire application into all of its own npm modules if you wanted to maintain all of that and have individual tests and things like that and set up the continuous integration on each one of those. That's just…
AJ:
Well, that would be a modlet, right?
JUSTIN:
Yeah.
AJ:
By the definition that we're talking about, that's a modlet.
JUSTIN:
No, that's…
AJ:
Because that's what npm does, or well it's what the GitHub plus npm pop culture push is.
JUSTIN:
I can agree. That's actually the highest form of modlet, actually, where if you were building your entire application where every single module was published to npm or your local npm and have its own tests and its own CI, that would be… I've never done it that way. [Chuckles] That's intense because you'd just have a lot of boilerplate to be setting up. It's actually something that DoneJS can help with is even if you were working on a non-CanJS based app and you were, “Hey, I want to make a React plugin,” but you wanted to make sure Travis was set up easily and the tests would run automatically and it would be exported to every single format, AMD, CommonJS, so that people could share it really easy and publish it to npm, DoneJS has a plugin generator that helps with that kind of stuff. But I know of no project that has… you'd be talking about, if you have hundreds of files you'd be talking about hundreds of different projects all published to npm. I just think it's unlikely that someone would actually go to that extreme.
CHUCK:
So, I guess my other question is then where does Can end or Done begin or vice versa? So, is Can this modular system or is that a different piece altogether?
JUSTIN:
So yeah, let me break it down a little bit. CanJS is the MVVM parts.
CHUCK:
Okay.
JUSTIN:
So, it's closest to… you would compare CanJS to something like Angular or React.
CHUCK:
Okay.
AJ:
Can we just clarify MVVM real quick?
JUSTIN:
Absolutely. It's model, view, view model. And what I mean by that is it has models that help you get data from the server typically connecting to a RESTful interface.
AJ:
So, REST JSON, one part.
JUSTIN:
Yes. And then there are two parts to a model really. There's getting your data and then actually the modeling part where you convert it to some type of type where I don't want just raw to-do's coming back from the server because it's nice if I have methods on them, can put helper functions. It's kind of like Backbone's model. And CanJS models are very similar. It has the view part which is, it's actually got two main, two different real-time… or I think when AJ was saying real-time, live updating views. So, if you change an observable the template changes automatically, or what's rendered into the DOM is changed automatically.
JOE:
Hey, now when you say observable, do you mean like the RxJS observables or are you talking about a more classic definition observable?
JUSTIN:
We're talking about a classic form of observable than the event stream type observable. CanJS has this thing called computes which you might have seen in something like Ember or Knockout, something very similar. CanJS I think does a really good job of straddling with its observables the functional reactive programming world of event streams and what React is big on and things like Elm where you have your state or source state and then everything is derived from that through functional programming or through event streams. That's one kind of model. And then there's the object-oriented model where it's, “Hey, it's nice. I can create a pagination object with methods on it that has state with it.” And you can call methods like, can you go to the next page, or go to the next page, or what would the offset and limit be derived from which page you're on?
CanJS's observables I think are a good middle ground between those approaches because it allows you to, if I have to split… take paginate for example. If I have a limited offset as the state of where my pagination is, I can easily derive values from that to say, “Oh, can I go to the next page given my limit offsetting counts? Can I go backwards? Am I at the end of the full set? What is the next page number?” Things derived from your source values, you can take those and drive other values. But you're building those… you can build your own custom observables. So, it bridges both worlds because you can derive those custom values but you're deriving them within the context of an object-oriented object. [Chuckles] So, that's something that is understandable by a user or by other people who want to use whatever your module is producing.
Think of it as like, I think sometimes when people are in the RxJS and event streams world is the API of those things end up producing those other streams. They're not easily consumable because people like objects. They can reason about them easily. But it's great because of how it manages state. Everything is derived from your source state. What I'm trying to say about CanJS is it kind of bridges those worlds as you can derive observable properties and make your methods reach in and change state. So, you can have nice APIs and derive values at the same time.
AJ:
So, just quick, concrete example. You were talking about pagination.
JUSTIN:
Mmhmm.
AJ:
And just give me the two-sentence version of how a blog with pagination type model goes into what you were just saying. I just need to hear it in a short version one more time to fully grasp.
JUSTIN:
Okay. If there was pagination on a blog, I'm going to create a pagination observable. And the only values that really matter in your pagination observable, really the state of your pagination, is a limit and offset, if you will, and maybe the count of total number of blog posts.
AJ:
So, what's the derivative value in this case?
JUSTIN:
Derivative values might be like, what is the page number? Which would be your offset divided by your limit. So, if your offset was like 60 but your limit was 20, well then you're on page 3.
AJ:
Okay.
JUSTIN:
Or, can you go to the next page? Or, can you go to the previous page?
AJ:
And so, you can observe the derivative values as well as the values of what you were saying.
JUSTIN:
Yes.
AJ:
Okay.
JUSTIN:
And you can also change the derivative values and that will go and flow into the source values. So, I could say change the page to five and you can wire it so it will update the source values.
AJ:
Okay.
JUSTIN:
And the other thing which I think it does really well is it handles memory leaks really nicely. If you've used event streams you know you've got to kill them if a person goes from one page to another page, stop the whole chain of observability. DoneJS is able to infer, compose computes with other computes and know, “Hey, this compute cares about this other…” You can think of it as like an event stream caring about another event stream, and it can flow that whole chain. So, once there are no listeners on the end of the derivation, all of the listeners will be torn down all the way back up until to the source state. So, all the memory is cleared.
AJ:
So, at the risk of going down the rabbit hole, how do you prevent loop issues where a thing depends on itself, depends on itself. Because when I first started with Angular I would hit into that problem day one, because I didn't understand well enough the nature of observable. Is that something that happens here, too?
JUSTIN:
So, yes. That can definitely happen. We have a batching thing that happens internally. So, you could still… other than letting you know because we can detect if something is observed on itself but we don't do it… we only do it for very direct cases. We can't do it for huge cycles. We maybe could but we only warn in the small case where it's very… you can think of it as when it's very clear that you're binding to yourself we can identify that and let the user know. But for the most part, it's not something that, at least on the 2000 issues that we've seen, that hasn't been something where people experience too much in CanJS. Maybe also because events are synchronous in CanJS. And it's not dirty-checking based. It isn't Angular. The observables produce their own events immediately on a change. So, maybe spotting and identifying and resolving those issues is a little bit easier with CanJS. Because you can walk back and see, “Oh, what produced this change? Oh, I could synchronously in the call stack…”
AJ:
Oh, okay.
JUSTIN:
“Walk up and see, oh it's the same thing that's listening, same property is changing itself.” That's maybe easier to identify because everything is synchronous.
AJ:
Okay, that makes sense.
JOE:
So, JavaScriptMVC right? That was your sort of first version. And now this CanJS, DoneJS is sort of version two, right?
JUSTIN:
Mmhmm.
JOE:
And you said that you were doing MVC with number, what version was the JavaScriptMVC? And now you've been talking about using MVVM. Why the change? And well, that's kind of it. Why the change?
JUSTIN:
Because MVC isn't… even though I wrote JavaScriptMVC, how to practically apply MVC in all cases still isn't even clear to me. I think there's just a ton of ambiguity on what is really a view in MVC can often be not clear. Where in MVVM I think it's kind of this observable track you take where you're writing all of your business rules and logic in this unit testable observable that is independent of the DOM completely. That's just so much a better method. I can create a paginate view model if you will, call those method on it that derive the source data or [inaudible] source data totally independently of the DOM. And so, I think just view models encourage that behavior a lot more. It's more clear what belongs where as well.
JOE:
I gotcha. I kind of feel like that MVC was one of those things much like the theory of relativity when Einstein was asked… the reporter, he says, “I understand only two people in the world really understand the theory of relativity,” and Einstein says, “Well, I can't think of who the other person is.”
[Laughter]
JOE:
[Inaudible] that anecdote.
JUSTIN:
Yeah, I can agree with that.
JOE:
But yeah, MVC was one of those things that everybody talked about but every implementation was significantly different.
AJ:
And that's why I asked the question about the MVVM, because I feel like it's the same story. All these acronyms, they don't mean anything [chuckles]. You have to understand what the person interpreted it as.
CHUCK:
Yeah. But at the same time, I think MVVM and model view presenter, MVP, and a lot of these others were initially called MVC. And then it became apparent that what you had there, the model was pretty clear cut what its job was. The view was pretty clear-cut what its job was. But whatever the other thing was functioned differently enough to where it didn't make sense to call it a controller. And so, we came up with other terms like a view model which is tightly tied to the behavior and performance of your view, or the presenter which isn't as tightly tied and just provides information to the entire view or things like that. But yeah, the definitions are still fuzzy, I think. I think you're right.
AIMEE:
My question is, I feel like more and more people are going towards Flux. So, why do you think that MVVM is still a good option as opposed to just using Flux?
JUSTIN:
So, I think Flux trades reasonability for composability a little bit. In my experience, and we're building a React app, React and Flux, well I shouldn't say… it's really Flux. Because everything has to go through that main highest level component where a lot of things going through that, it makes that a central linchpin of pretty much all application behavior, which make that file, it can grow really, really big. Where when you have observables… so React is kind of forced into this because of how it works and I think just frameworks in general, they're all trying to solve the observability or state change and then how do you reflect the state change in different ways. They all have different ways of doing it.
But React's way with diffing and no observables and things like that, it ends up forcing that main component to grow really big. Where something like MVVM with observables, you get what people… one way of calling it, if we're bringing up the physics, is kind of like spooky action at a distance [chuckles] where oh, the same instance of a to-do is in these two different components. And once can change and then the other one would just know about it without having to propagate that event all the way up to some main component and then have the component reset the state all the way down. They can find side channels to set up communication with the state up.
Now, that makes it so… this is one of the big things I think that I like about DoneJS and the way they build things, is it's all based around that modlet idea whether you like the name or not, is that everything should be self-contained and built to work on its own. And that in my opinion is much easier when you have observables and you're expecting the same instance. And one thing can change in one component and it'll just change the same instances somewhere else without having to have a parent component orchestrate that. It's kind of like Flux and stuff like that could sometimes be a leaky abstraction I think where to prevent a React from updating itself, you have to export some ID to let React know what's the key so it doesn't re-update, so it doesn't recreate that same component in the view model.
There are issues like that, that Flux creates. No, I shouldn't say… the idea, and that's why I say, I think the idea of what Flux and Elm and all of those things are doing where you have functional reactive programming where you have your state and your application is in some ways just a mathematical reflection of your state, it's a really, really solid, strong idea. I think DoneJS does a good job of being a hybrid of those approaches. But that's kind of the problem I see with Flux. I
don't know if any of that makes sense. Hopefully it did.
AIMEE:
No, that did.
JUSTIN:
It's like a big meatball in what I would say is not spaghetti but it's like a meatball in the middle of straight uncooked spaghetti that you can easily…
AIMEE:
[Chuckles]
JUSTIN:
Easily see the lines coming out of that meatball in React, or Flux I should say. It's a trade-off. I've seen what people have to do with those state stores when they want to start combining and crosscommunicating state across different parts of the application. It can get a little strange.
So, let's assume for a moment that I want to convince you to use DoneJS and CanJS. Ask the questions that would help me convince you.
CHUCK:
Well, that's kind of what I've been doing anyway.
JUSTIN:
Oh, okay. [Chuckles]
JOE:
Not me. [Chuckles]
JOE:
I haven't been asking those questions at all. My question is, does it look really good in a to-do app because that's all it convinces me and anybody to use… [Laughter]
JOE:
A framework, is how good it looks in a to-do app.
AIMEE:
Who else is using it?
JOE:
Right. No, I think if you want to ask that question, I think there's a good question related to that. One of the things that I think we hear a lot from the React community, the Elm community, the Redux community, and we've been hearing the same thing from the functional reactive programming community for a long time, is it's a ton easier to maintain these applications as they get months, years down the line in the maintenance mode where we're not building it anymore. And it's not the same guys who've written 95% of the code that are still writing. New people come on and new people have to just maintain the existing app. That those apps are very easy to maintain and easier than your typical OO app. So, can you talk maybe a little bit about that? About CanJS and how that relates?
JUSTIN:
Yeah. I would love to see how that really looks in practice, because all of these things are so new. I think that the hardest thing is really when you transition someone new on a project, how quickly they can understand it. I don't know. It's hard for me and really this is a hard thing because I don't know how they're… I know this is something that people… in my opinion, it's one of these things that people, they're just saying and people are taking for granted because I guess I haven't been exposed to the real evidence of this.
The famous Flux or React video where they're like, “Oh, the count. We're keeping track of the count,” that's something that totally works very similar in a CanJS application, is that your count is derived or number of… what is it, like count of unread messages, is derived from these other source state values. And in the case of CanJS you have observables that derive that value and then whenever the source changes, the values update themselves automatically. So, I don't know. I
guess I haven't been presented by the evidence where it actually deviates that much.
The only place that I can see it is maybe with two-way bindings where you're getting that spooky action at a distance where, “Well this has its own value and the parent can have a different value.” But in CanJS you can very easily set one-directional bindings and events going up. So, you can switch to that. I guess it doesn't enforce it. But two-way, I guess two-way bindings like I said, that spooky action at a distance can be very nice I think for composability where I can say, “Here's a paginate model. And this can use that paginate model and this other type of widget can all use that exact same paginate instance and cross-communicate with it.” And they don't have to all build their own version of…
I guess an example with React and Flux I've seen is like if you have something like paginate and [inaudible] derived values, you derive them and then add them to the object and then pass that all around everywhere. If you know what I'm talking about, like can you go to the next page? That's a property that gets added to your paginate object and then passed to all of these different widgets. It kind of feels, I don't know. You do very similar stuff with CanJS. So, I don't know. Maybe you guys can illuminate me with more of the rationale behind this.
JOE:
Well, I think one of the reasons that people say those sorts of things has to do with the way that actions work in the single-direction, one-way data flow, is you have these actions, this nice list of actions. So, everything runs through one place so the state can't mutate itself while it's trying to render out. And also, I think another reason probably is because you also tend to get this nice list of, “Oh, here are all the valid states in your app.”
JUSTIN:
Yes.
JOE:
Or valid actions I guess is really what I'm talking about. They're not the valid states, but here are all the valid actions in your app. And so, for somebody new that comes on, it's very easy to go through and see, “Oh, this is everything that the app does.” And for maintenance when it's time to, “Oh, I want to make a change in how some functionality works,” I know exactly how this functionality flows because it all comes through here. So, there's no… It’s a lot easier to avoid the problem where I
touched something over here but in this far corner of the app it breaks.
JUSTIN:
Yeah, I think…
JOE:
Something that I didn't realize.
JUSTIN:
Yeah, that's… I would say that you could still do that stuff with CanJS because it has one-way bindings and you can propagate events back up to the parent that it can listen for and update itself as it's the only source of truth. And I guess if enforcement of that is what you need, then CanJS won't provide that. But I guess in the big apps I just don't see the parent knowing and being the end all, be all of everything. And having to have exporting events really to connect to the parent as a way that… I kind of want to build, in multi-page apps, think about like a… you've got a singlepage application that represents multiple pages. Each of those pages should really in general, should have its own state and doesn't really need to communicate that ever up to the parent. That's really more connected to the state that's implied by the URL.
I know you can have substates in components. And then you wouldn't propagate the state for just that page up to the parent. I guess I just don't see it as, I don't know. You could do those things with CanJS if you want or you can just use two-way routing and then the value, or two-way binding and then the value. You don't have to set [inaudible]. You just change your value and then you know that the parent's value is going to change.
JOE:
Okay. So, your opinion is more along the lines of, you not necessarily thematically agree with all of that, that you could still write your app to be maintainable. CanJS and DoneJS, they enable that sort of thing. But the restriction of it isn't necessarily a required thing.
JUSTIN:
Yeah, I guess it's a lot of boilerplate to have to dispatch an event and then really a lot of times all that event is doing is calling an action that updates the root state. Where instead you could just change your state because it's connected to the root state. I just change that value and then it's done.
JOE:
That's a very common complaint among Flux and Redux users.
JUSTIN:
Yeah. So, that's what two-way binding provides, is just like, “Well, I can just change it.” So, I guess I would just say with, I don't know. This is such a [chuckles]… it would depend on the situation. In a
lot of apps, you get more transparency probably by always going up to the source state. But at some point the app might get big enough where that becomes, like I said, that big meatball. That thing grows and grows and grows with methods and just to listen to the bindings and then call a state where all of the children could effectively be doing that themselves. Very good question.
JOE:
So, what about app size with CanJS? How big have apps gotten with this so far?
JUSTIN:
So, I guess one thing to talk about is when you talk about DoneJS, DoneJS is built with CanJS as the big part. So, if you talk about apps built with DoneJS, there probably aren't too many yet because it's only been out since November. But really if you're talking about things built with CanJS and StealJS, the dependency management part, we've built some enormous 500 megabyte gzipped and minified apps. We obviously don't make that the production JS. We have… one really cool thing. All the Webpack folks who might be checking this out and love Webpack or jspm, check out StealJS for dependency management. It's very similar to those but two benefits. The first is it has a really nice high-performance bundler that adds an additional step compared to the Webpack bundler. And it doesn't have to run on the file system to load an application. It's kind of like RequireJS you can do everything in the client which makes building demo pages or individual test pages much easier, because you don't have to set up a build for those pages.
But so yeah, huge, 500 megabytes gzipped. I don't know. Hundreds of files. We've been building stuff on this technology for eight years. Unfortunately the most high-profile website that's been built with it I can't… actually I can talk about. Store.Apple is built with CanJS because reddit, someone posted that on reddit. So, I'm allowed to talk about it. Hooray.
AIMEE:
I did kind of have a question about this. So, if I'm a newer person deciding what I want to learn, I'm trying to pick something where I have to learn as little about the specific API as possible and I can just rely on as much of just plain JavaScript as possible. So, how does this fit into that? Would I be able to rely on just knowing a lot about JavaScript or am I going to have to learn a lot of things about Can and Done?
JUSTIN:
So, it depends. That is a concern for us right now. That's one of the best things I think React got right was making templates feel like JavaScript as much as possible. And it's actually something we have in CanJS but it's kind of deprecated. It's old embedded JS templates which were kind of, you would write out JavaScript. The biggest thing, hurdle that you would have to learn I think it Handlebars which is what its template engine is right now. We're actually making or right now we're working on Levis.com. It's using CanJS observables which are really its best part, with React's templating engine. And we're going to have that as a plugin to DoneJS.
And we're also planning on making a version of our templates that use, go back to using JavaScript instead of Handlebars type templating. But if you understand Handlebars you should be fine.
CHUCK:
Alright. Well, if people want to go check out CanJS or DoneJS and find out a little bit more about what they're about, where should they go?
JUSTIN:
They should go to DoneJS.com, check out the features page, and then… or a local meetup in your area. I've been going to a lot of meetups lately so I might hit your town pretty soon. So, just look out for it.
CHUCK:
Alright. Sounds good. Well, let's go ahead and get to the picks. AJ, do you want to start us off with picks?
AJ:
Yes. So, I've got a couple of good picks this week. In case you were not aware, Taylor Swift albums are like Pokémon. You got to catch them all. And my sister pointed out to me that there as a limited edition album that very few people have that you might not be aware of. I really can't pick it because I haven't listened to it. But it's called 'Beautiful Eyes'. And I don't think there's… it just alternate versions of songs that are on other albums. I don't know if there are any songs that are specific only to that album. But I'm going to pick that because I didn't know about it. And now I do.
And now you do. And if you're a Swifty then you can feel more complete.
JOE:
AJ, Taylor Swift, she's one of those weird artists that doesn't stream her music, right? You actually have to go somewhere and pay money for just one album? Is that how it works?
AJ:
God bless her. God bless her for standing up for owning something and actually having it in your hand. So, I am actually…
JOE:
God bless her with [none] of my money. [Laughter]
AJ:
Well, he wasn't blessing her with any of your money before, was he? So…
JOE:
When she was streaming, he was. She was getting some of it. Now she's getting none of it. Zilch.
AJ:
Oh, I hate streaming. I hate this whole… just one day…
CHUCK:
Just find it and get a digital copy, right?
AJ:
Yeah, digital copy is great. Digital copy is absolutely awesome. But oh, I'll post an article. I got to go find a link. But it's an article about what happens when Amazon Videos die. And we've already seen this kind of stuff happen before, like when they took all the Disney movies off. And inevitably it's going to happen. Somebody's going to change the policy and all those thousands of dollars that you've spent on things that you think you own, you're going to find out that you really don't have. And they're just going to be unavailable and you're going to get a, “Oh, sorry. We changed our policy,” one day. So, I'm all about if you have it in your hands, you own it.
JOE:
I'm just renting the music. And I love it. I get to rent every music. [Laughter]
JOE:
I'm renting it all. I don't want it.
AJ:
And that's what YouTube is for. Or Spotify or Pandora. Get it all for free and never have it and only have it available when you have internet connectivity. And that is great for people that are super techy.
And anyway, but leaving that rant I'm also going to pick PROTODOME. That is a band. They have stuff available on Bandcamp. And you can choose to pay nothing and get it. Or you can choose to pay something. The song that I really like is called 'This Heart Has Too Many Broken Pieces' and I can't remember which album it's on right now. But it's chip-tune music or video game music. So, if you love that stuff, you'll love it.
I'm also going to pick city libraries because they all have websites. And they have an event calendar on them. And you'll find out that there's cool stuff like adult coloring book classes and adult story time with professional storytellers. And [inaudible].
CHUCK:
AJ, that explains a lot.
AIMEE:
[Laughs]
AJ:
Oh, I'm going to start going to the library more. Well, I… so, this is what happened. Last year for my Facebook friend year in review, Facebook was like, “Here's you,” and it showed some pictures of me. And then it's like, “Here's you with your friends,” and it showed my mom and my sister. And then it was like, “Here are things you've done,” and it was like me standing still. And I have a cool life, okay? I have fun. And I don't care what Facebook says. I do too have friends.
AIMEE:
We're programmers. There should just be a picture of the computer. That's my friends.
CHUCK:
[Laughs]
AJ:
But, so I've decided this year I'm actually going to try to go do things. Well, more things, because I did things last year. I did. But I'm going to try to do more things and take pictures and stuff. And so, I've been looking at city event calendars and free stuff and paid stuff and whatever. And I found the city library calendars to be very helpful.
And then lastly, I will pick 'The Crucible of Doubt' which is a book that has been mind-blowing in my personal rediscovery of faith that I'm going through right now. And it's by the same authors of the book that I picked last time, 'The God Who Weeps'.
CHUCK:
Alright. Aimee, do you have some picks for us?
AIMEE:
I do. I have a fun one and a serious one. I'm going to start with the serious one. So, serious one, somebody sent me over a link in the Elm Slack channel. But it is a site called LearnXinYMinutes.com. And it has a ton of different programming languages on there and it just runs through the syntax and stuff. So, for things like Elm where this is something that's very, very different than any language I've ever learned before, I actually found this to be really, really helpful, especially for Elm. So, if you are interested in Elm, check that out. You could also check it out for other languages, although I can't say anything about those because I haven't looked at them yet.
My fund pick is something called 'Which cat is your JavaScript framework?'. Unfortunately I don't see Can and Done on here but it's still pretty fun. They have all the regular players in here. So, if you are in for a little joke or something, you can check that out. That's it for me this week.
CHUCK:
Alright Joe, what are your picks?
JOE:
Okay. Well, I want to start off with a tweet that John Papa tweeted recently. And it was basically about having manners on social media and not treating social media differently than you would treat a real-life interaction. I'll post the tweet itself, the link to it. But basically the point was, and actually he tweeted this after he and I had a conversation about somebody who had criticized one of my courses on social media over Twitter I think. And the criticism was completely valid. There are… everybody's work is subject to imperfection. And what I had done wasn't necessarily perfect and by his opinion, he didn't like it, which is fine. But the way that he made the comment was really kind of like in poor taste and something you would never say to a person's face unless maybe you were a sociopath. But because it was on social media, it's something more common, a type of thing that we see. And so, that's going to be my pick is just being a good citizen over social media and treating social media the same way that you would treat real-life interactions. So, that's going to be my only pick this week.
AIMEE:
Joe…
CHUCK:
Yeah, I want to plus one that one on email as well. I got an email when I sent around an email saying, “Hey, I'm going to be in Amsterdam so if you're from there or going to be there, I'd like to meet up and hang out.” I got an email and it was, “Why the F are you emailing this to me?” And I emailed him back and said, “I don't know who's in Amsterdam so I let everybody know and figured the people who didn't care, it wouldn't bother them.” Yeah, and I got an email back just saying, “Yeah, I was drunk that night and I'm really sorry.” [Laughter]
CHUCK:
And you know, a lot of times we just don't think about it. We're kind of in some head space either assisted by some drug or not, or lack of sleep. And so, yeah, plus one on that. And think doubly as hard if you're emotionally compromised.
JOE:
Right. Well, you never know. It's just not a good way to treat life. There are far too many interactions. It's hard enough when you're talking about these in personal interactions to just give the wrong impression anyway.
CHUCK:
Yeah.
JOE:
To say something that you don't necessarily mean. But add onto that the anonymity and the temptation to just say what you feel without thinking it through and say, “Would I say this to a real person that's sitting in front of me?” and not filtering it out. And it just becomes a big habit. You never know who you're talking to and how your comments may affect both your life and their life, right? So, I think it's just always better to act on social media the way you would act in person.
CHUCK:
Yeah. Aimee, were you trying to say something?
JOE:
I know tons of people…
CHUCK:
Oh, go ahead.
AIMEE:
Oh, I was just going to say to Joe, [inaudible] everyone that I talk to absolutely loves your courses [inaudible].
JOE:
[Laughs] Thank you, Aimee.
AIMEE:
[Chuckles]
CHUCK:
You got to stop talking to his mom. [Laughter]
AIMEE:
Well no, these aren't his mom. [Chuckles]
JOE:
Yeah, when Aimee had her Facebook year in review, here are your friends, it was my mom.
AIMEE:
[Laughs]
JOE:
Here are things you've done, and she was chatting with my mom. [Laughs]
CHUCK:
Yeah, yeah.
JOE:
That's it.
CHUCK:
Alright. I've got a couple of picks. These are more along the marketing line of picks. I've recently set up a set of emails. It is the top 10 episodes of JavaScript Jabber ever at least to date, as of the beginning of this year. Anyway, it was kind of fun to compile. But I'm using a few tools to get it out there so people can use it, or to get to emails. So, the first one is SumoMe at SumoMe.com. And it's a tool that allows you to put marketing tools on your website. So, if you go to JavaScriptJabber.com it'll actually slide down with a full screen place where you can put your email address to get it. It only does it once. I figured that's not too awfully intrusive. But then if people want it, they can get it, and it's really easy to find.
The other tool I'm using there is Drip. That's at GetDrip.com and it's a terrific email marketing tool that I've probably picked on the show before and I'm super, super happy about.
I also went to a game night earlier this month and played a couple of new games that were fun. The first one was called 7 Wonders. And it's kind of hard to explain what it is. It's a rather involved game. But it was a ton of fun. And it's one of those games where you can kind of see what everybody's doing and you can see how they're trying to win the game. But you don't really know who won until the end. And sometimes you're a little surprised, oh you stacked that up, but effectively you build certain resources and use those resources to get other resources that count toward victory points.
The other game we played was called Shadow Hunters. It's kind of Werewolf with life points. And it also has different cards that are like weapons or give you some special ability this way or that. And that's also just a ton of fun so I'm going to pick both of those.
And finally, I'm just picking a ton today, two of my book series that I've been listening to on Audible came out with new books. The first one is The Reckoners by Brandon Sanderson. The third book 'Calamity' just came out and I'm really itching to read that one.
JOE:
You haven't started it yet?
CHUCK:
Not yet. I want to go back and listen to the other books again.
JOE:
I went down to the pre-release and got a signed copy.
CHUCK:
Oh.
JOE:
I'm such a geek.
CHUCK:
I didn't know he was doing that.
JOE:
Yeah.
CHUCK:
That would have been fun.
The other one is the Iron Druid Chronicles by Kevin Hearne. And the book 'Staked' came out last week. So, I picked that up on Audible as well. I just finally finished listening to all the books that lead up to it. I didn't listen to the, there are like a couple of hour and a half long short story form parts of the story that I didn't go back and listen to again. But yeah, I'm in the middle of 'Staked' right now because that's the one that I ran across first. So, I'm super excited for that. That came out last month. And yeah, so I'm really enjoying those so I'm going to pick those as well.
Justin, what are your picks?
JUSTIN:
So, my first pick is the BB-8 Sphero which is like a little remote-controlled BB-8 that is amazing for keeping, lazily keeping crawling babies entertained.
CHUCK:
Mmhmm.
JUSTIN:
Which, I have one of those.
JOE:
[Chuckles]
JUSTIN:
And then the next pick is something that I recommend to everybody who likes science fiction which is the Hyperion Cantos. It's a series of four books written by Dan Simmons. If you like crazy, science fiction fantasy and in some ways just being exposed to things that I wasn't exposed to, the writing of John Keats before, I highly encourage you to pick up the audio book or the real book. I'm reading it now for maybe the 10th time. I highly encourage people to check that out.
CHUCK:
Alright. Well, we'll go ahead and wrap up the show. Thank you again for coming Justin, and giving people an opportunity to mentally explore this particular topic and those libraries.
JUSTIN:
Thanks for having me.
CHUCK:
Alright. Well, we'll wrap this up and we'll catch you all next week.
[Hosting and bandwidth provided by the Blue Box Group. Check them out at BlueBox.net.]
[Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]
[Do you wish you could be part of the discussion on JavaScript Jabber? Do you have a burning question for one of our guests? Now you can join the action at our membership forum. You can sign up at
JavaScriptJabber.com and there you can join discussions with the regular panelists and our guests.]