

ASP.NET + Node.js = JavaScript Services

Sandeep Singh speaking at dotnetsheff in May, 2017
Great talks, fired to your inbox 👌

About this talk

JavaScript Services: what they are and how they can benefit you.


- Hi everyone, my name's Sandeep and today I'm gonna talk about something that's new in the ASP.NET Core ecosystem, which is called JavaScript Services, has anyone heard of JavaScript Services, or... Anyone know anything about it? That's pretty good. Alright, so before we get into what JavaScript Services actually is and how it can benefit you, what I wanna look at is a little bit of a history lesson. So if we just have a look at what web development was actually like in 2009, essentially it was fairly simple. If you want to create like a front end website you generally have a script tag with some reference to, probably, jQuery or one of the tools that's here and programmed some CSS and that was about really it. And it was great. And it's nice and easy and you could deploy that, fantastic. Modern web development is a little bit different, so anything from 2011 onwards we now have an array of tools. So we have package managers, things like MPM, Yarn, Bower. We have transpilers 'cause no one writes JavaScript anymore, everyone likes TOPscript 'cause TOPscript's pretty awesome. Then we've got a lot of frameworks such as Aurelia, Angular, Few JS, React, the list goes on. Got some pre-processes so for instance in CSS, compiling CSS from lass, sorry from Less and Sass into CSS. So got some testing tools, we've got Jest, got Karma, Protractor, depends on which ones you want to use. We've got module bundlers, so there's like Webpack, Gratify, Brunch, Roll up. And we've got syntax checkers and you can see where I'm going with this. This is quite a long list, so we've got linters such as ESLint and then you've got JSLint as well. Then we've got task runners which is the final one. Which is like your Gulp and your Grunt. So looking at this list we have a really long range of, like technology that we use to create modern front end applications And this is...half of this stuff that I've mentioned we don't... I haven't gone into architecture, if you're using like, things like flux, so there's React for that. Haven't looked at cross platform stuff like React Native. Which you can do mobile application development with as well as client side. And there's Electron if you want to do desktop with React. So it's quite a complex task nowadays to create a front end website. Especially single page application. But ultimately, if we have a look at all the technology we use we have some frameworks and we have a bunch of tools which allow us to transpile or compile our code and our js into html and CSS and JavaScript. 'Cause that's essentially all the browsers really care about. Don't really care about anything on the left hand side, that's something that we're interested in and all the cool stuff happens. So what we just had a look at is, back in 2009 it was straight forward to create a website, very easy. No such real concept as single page applications. 2017, big difference. Everyone wants a single page application. But as we've seen from the list of technology and some of the stuff I didn't mention, it's not that straight forward to create. There's a lot of boilerplate they need set up. There's a lot of other things that you need to know about technology wise. And you might not know about what all the latest and greatest stuff is because the grounds kinda moving underneath you. As you're kinda looking at all the different tech. Like Grunt was one of the greatest things since sliced bread for task runners but then Webpack came along and it's like, okay everyone likes Webpack and Webpack's great. But how can ASP.NET Core help you with this? Basically, there's something called JavaScript Services, it's been around for about a year. It's 1.0 release at the moment. And it's a set of technologies which allow you to build single page applications and run node on the server. While you can invoke it via ASP.NET. You probably want to ask me why would you want to do that, I'll go into that a little bit later. So, if we just have a look at what it's actually made up of, JavaScript Services there's three main NuGet packages. There's SpaTemplates, SpaServices, and NodeServices. So I just want to run through these and have a look at what they do individually and how they can benefit you. So if we just have a look at SpaTemplates, basically SpaTemplates is what it says in the name. It's a bunch of templates for the following frameworks. And you're probably thinking, I can just put this in myself. The cool think about SpaTemplates is they put a lot of the boilerplate code in for you that you need for a single page application in terms of if you want to do self-side rendering, if you want to use a build pipeline, which is Webpack, it's already configured and same with your tag script configuration. There's a lot of stuff under the hood that's already done for you. So you don't have to sit there for hours and plumbing away and trying to think, why doesn't my modules work and so on and so forth. So there's two ways to use SpaTemplates. They either can use Yeoman which is, was the first way that it was created with. And the second way, which I prefer, is using the NuGet package. And using .NET New because that is kind of like, it's a more of better user experience in terms of the .NET CLI. You can kind of stay all in one, which is great. So, next thing, which is... I want to talk about is SpaServices. Which essentially is a lot of the features that you want to build into your single page application. So the template has all this boilerplate and has all its magic done for you. But it's all powered by SpaServices which is another NuGet package. So inside of SpaServices there's four main, real, areas of interest. There's a few more of those, if you have a look at documentation. But these are the core ones that people talk about mostly. So, the templates that we have, are all built in line with... they have the build pipeline of Webpack already configured into it. Which is great 'cause Webpack allows you to do all your transpilation And LSD and Less to CSS. Basically, handles all your module bundling. So it's pretty good as an all around tool. You can use it as a task one as well. But one of the other things that Webpack has is that it has middleware which is basically a dev server. So if you're making code changes, and you want to reflect them in the browser it actually compiles them in memory in the background and all you have to do is refresh your page and there's now commands to run after Webpack to claim a line aid after a watch of a grunt task or anything like that. It automatically does that, it give you that outbox. And the next step is hot module replacement which is another feature inside of Webpack. Which takes that...extends that a little bit further in the sense that, instead of actually just refreshing the page yourself, could it automatically do it for you? And yes it can. It's very clever in the way it does. It kind of looks at your file system changes and does a dev and incrementally updates what's in the browser without a full page reload. So, I've got an example of this, of a simple application that I created. So I've got a Counter and it goes up. You can count in threes. But if you look, and I actually change that to a minus number and go back you won't see a full page refresh. 'Cause the state is still there in the page but my actual compilation has been updated and that's seamless. So the React template supports it very very well. The Angular template doesn't hold state unless you're using NGI or X because it doesn't hold... React, sorry... Angular as a whole doesn't hold component level values in it's state whereas React does. So, the next thing is server-side pre-rendering. So has anyone heard of terms like isomorphic or universal apps? That's essentially being able to run your JavaScript on a client as well as on a server. So, the whole point of this is to allow you to basically give a better user experience for people who don't have the best internet connexions and who want the application to come down straight away. Because if you look at a lot of the single page application frameworks that we have, they are big in size. Angular, I think minified is 1.9 meg which is a lot to transfer over the wire. Server-side pre-rendering what you can do is with it, it will render the actual page and the mock up and all the JavaScript that you really need to boot with on the server and then you can, basically, you can pull it down over the wire and there's a preboot js that it's got in there that once it's downloaded on the client it will update any of the events that you need to get on with it. So that's really cool and it's really good for SCO as well because even though Crawlers are getting really smart now about crawling over JavaScript, it makes it a lot easier for 'em. So the last thing I want to talk about is routing helpers and that's fairly straightforward. It's basically a way to sync your client-side routes with your service-side routes. So if everyone's familiar with NVC, you have route and you have route attributes. What this does is it allows you to check basically, static files first when a request is made. Then it checks the routes and if it doesn't match any of those, it will pass it down to the single page application. Which is pretty cool. You can use it for handling 404s and so on and so forth. Right, so, the last thing I want to talk about out of all these packages is something called NodeServices. And NodeServices is what's used in all of the other packages. It's basically the core of it. It's essentially running Node in as ASP.NET Core environment. It basically runs in the background and is the process that spins up when you... When I wanna show you a little bit of a demo and you'll see how it runs. So, if we just get into the demo, what we want to have a quick look at is, I've got a very simple NVC up here. Just enough to have co NVC up. But what we want to do if I get it running, so this should start a watch, it should run in a second. Hopefully that'll come to life. Right, so basically this is very simple. This is a simple page, that we have a ticket for... to see a film called "Logan". And what we want to do is, we want to render some new functionality with the print button. So currently the print button does... Nothing, really, there's nothing here. It's just a call to an end-point. So imagine you've got a BA sat by you and say, okay that print button we want to generate a pdf. And you say, okay so what pdf libraries do I have in ASP.NET Core currently? And the probable answer to that question is not very many. So this is where the power of NodeServices come in, 'cause you can invoke Node on the server so you can use any of the MPM packages in the ecosystem that's available. So what we can do, if we go back to our solution, I've already added the relevant Node package into the csproj. Show you, just the NodeServices, just NuGet Package. But what we can do is we can add into our DI, tether, services... And that should recompile on the fly. Which is great. Let's just see we haven't broken anything. Alright, that's fantastic. So what we want to do next is we actually want to implement the functionality that the BA actually asked for. So, we have a look at the end-point that says generate pdf which says nothing here. What we want to do is, we want to basically invoke some JavaScript to create our pdf for us. So, if we get rid of this. And this is a snippet I made early. So essentially, the most important part of this is there's two methods. Basically we get some html from a file on disc and we replace some values which you have seen on screen. Which are basically just the type of ticket, the cost, and the title. And then the most important bit is we have injected into our method a NodeSevices or an I NodeServices class. So on that the most important methods, there's quite a few, but the most important ones, invoke, which basically allows you to invoke some JavaScript. What's generate pdf JS in a node process and you can pass in an arbitrary number of arguments. So, and what what we're going to do is return to screen from this. So if we have a look what's in this, generate pdf, actually, it's blank so, what we can do is just write a normal node. So I've got a snippet here. And this is using a package called html to pdf. And all it essentially does is convert html to pdf. So what we're passing in, if we go back and have a look, Oops. Go back to our controller, we're just passing in the options of the format that you want and then the data which is the html. If we go have a look, and generate pdf, then if we just save this, it should have recompiled and if we go back here, This all works. We should see a pdf. It's probably not very pretty but.. Yeah, Wahoo! And that's essentially, I can run an MPM package or access to an MPM package or any JavaScript that you really want on server via ASP.NET. So this is really useful. So a lot of the server's features that we see for Webpack and the SpaServices all use NodeServices under the hood, 'cause all it does is generate you a new node instance which you can make RPC style calls to and then away you go. So the possibilities are endless. Right, so, it's got a few resources that you might want to look at if you want to check this out a little bit further. So, JavaScript Services GitHub page is pretty good. They're quite responsive in terms of the issues and the releases and what they're doing is quite up to date. The Webpack, if you're interested in some of the stuff around Webpack documentation's really good. My demos up here as well. And this is a really good example of what you can do with JavaScript Services if you're building an Angular Two application. Because it implements a lot of the new features which I haven't really talked about. Which is ahead of time compilation. Which allows you to basically compile stuff into smaller chunks. So you basically, when you're requesting a page or a route you don't actually have to download the whole initial app to start with. You can just request it and lazy load it. Which is pretty cool. And that's it. Any questions? - [Audience Member] Does it paly nicely with Azure web apps? - I haven't really deployed it to Azure web apps. I've run it in IS and various other platforms and it seems okay. But I would guess so, because it runs it's own private instance. It's fairly robust in the way it's done. I know a few people who do run it in production so I wouldn't see any issues with it. Yes John? - [John] Sorry, So I may have missed the point but why would I want Node in the background? Why not just run NetCore throughout the whole stack? - Yeah, that's an interesting question, so for... to support a lot of the features that you have, that I talked about in terms of the Webpack Middleware, it uses NodeServices under the hood. Now, NodeServices is a package that you might not want to use. You don't have to use it, but the whole point of it is, if you have something like an audio or an image processing library which is not available in ASP.NET Core, it allows you to expand that and use that elsewhere and basically get access to it and continue use, still continue, kind of your development until there's an API in ASP okay? Not ASP.NET Core. Like a NuGet package. So it's up to you where you want to use it. But generally most people will probably stick to SpaServices and the templates because it wraps it up for you and you don't really have to do anything about it. But if you really wanted a low-level library to invoke a no js environment inside of ASP.NET Core, NodeServices is what you want to do it with. - [Audience] What's the debugging experience like? Can you debug with JavaScript? - Yes, so I didn't actually, I can show you, if you want, if we have enough time. So essentially, inside of our... when we register on NodeService, you can actually set a debugger, this says "launch debugging equals true". So essentially it uses, it's like a Chrome debugger. It's called NodeInspector, so once it starts and we make a request I can show you exactly what it does. So now that it's started if we was to request... this, if we go back to application you can see that it says to debug run NodeInspector debug port 0. So if we was to take... That. Yeah, that's not gonna work because... No, this is not working at all. What is the port number? Alright, but that's how you set it up. It usually does work. But ultimately what you get is the, if you ever have debugged in Chrome you get the development tools basically, that's all we can...that's all we give you. Which is pretty cool in a way 'cause you can debug in line if you really wanted to.