Saturday, October 29, 2016

Microsoft's AspNet Javascript Services...now in Aurelia.

In today's complicated web application ecosystem, starting a system from scratch is some seriously hard work.  There's an incredible number of choices to make in terms of frameworks, JS language versions, build processes, back end integration, etc.  And once you choose these things, you have to piece them together.

Fortunately, there's a number of different starter "seed" projects out on GitHub that have some pre-packaged solutions that have most of this work already done.  You can generally find something that is built using the combination of things you're looking for, ready to go.  However, these are almost exclusively *client-side* solutions.  They provide everything you need for front end, but don't have any back end integration. For that you're on your own.  This typically means you're running a development web server with your client, and then have to separately start up a back end - or mock it completely.

But there are a couple end to end solutions out there. For example, ServiceStack has some Visual Studio templates that come in multiple flavors and integrate with ServiceStack APIs.  But I think there's a couple downsides to these.   First, they are using only JSPM.  Webpack is quickly becoming a standard and I would prefer to see them provide at least an option to use Webpack.  Also, more importantly, you need to pay for ServiceStack licenses to use the backend technologies used in the templates.  While ServiceStack is very powerful, it's also not cheap, and so it might not be an option for some teams.

That leaves the other full stack solution I've been able to find - the AspNET JavaScriptServices templates.  These are pretty new, and have a lot of really cool features.  They're using .NET Core, so they are a great opportunity to use latest Microsoft technologies.  They are well integrated with Webpack and take advantage of all its features, like HMR (hot module reloading).  And they all can be launched from single CLI "dotnet run".  The UI and the backend API launch simultaneously, from the same project.  You can have integrated debugging, from front to back and don't need to open up and work with multiple projects.  This is a really nice developer experience.

Until now, the JavaScriptServices templates have only come in Knockout, Angular, and React.  But as of this past Friday, with the merge of a new PR, there is also support for Aurelia.  And, in fact, I was the one who submitted it!  While it's not the most amazing work (and Steve Sanderson at MS deserves credit for the final Webpack configuration), it was work that needed to be done - and was definitely worth doing. 

This was the first time I've made an open source contribution, and it was a great experience.  It's personally rewarding to know that you've made a contribution that others can now use.  I actually wasn't looking for something to contribute to, but while I was reading about the JavaScriptServices templates, I looked through the Issues log and saw there was a request to add support for Aurelia, and that it was up for grabs.  Since I had just gone through some work converting some HTML dashboards to Aurelia and Angular2, and was interested in working with the templates, I figured I might as well try it.  I'm really glad that I did.

As I wrote previously, I think Aurelia is a really well designed framework, and also think that the JavaScriptServices templates provide a great way to develop SPA applications.  Hopefully others who are  interested in using Aurelia can find it useful as a starting point in projects of their own.  There's still work to be done for adding HMR support in Aurelia, so there's opportunity to improve the current implementation.  It looks like this might be available sometime at the end of this year, or start of next.

Finally, I have to comment on how much I like Microsoft's .NET Core environment and tooling.  Their CLI interface gives developers a first class command line experience, which is something quite different from the "Visual Studio does everything approach" we've seen from Microsoft until now.   That approach could result in some strange things, where the build in Visual Studio was very similar, but not quite the same as the MSBuild you'd run as part of an automated process. 

Now, you can easily work with the CLI build, run, and publish commands directly. For developers who are used to working with NPM at the command line for their JavaScript projects, this naturally becomes part of their development process.  I used VS Code (which I also like very much) to do all the editing for both front and back end code, and relied solely on the CLI for doing all the project related tasks.

So, what are you waiting for, go download the JavaScriptServices Aurelia template and try it out!

50 comments:

  1. Hi Keith

    I found this article via Rob's blog he published today. He should have mentioned to you that our Aurelia Community team assembled under the name of Aurelia Tools is working on the tool (code name Monterey - see http://blog.aureliatools.com/2016/09/19/introducing-monterey/) would greatly benefit by having some direct conversations with you. Please contact me at https://github.com/monterey-framework/monterey

    ReplyDelete
    Replies
    1. Adriatic - I put up a note over at Monterey, with some unsolicited thoughts on what my dream tool for UI project management would do =)

      Delete
  2. Nice Job! I just heard about the JavaScriptServices repo on https://www.dotnetrocks.com/?show=1374 just a few days ago, and was wondering if someone from the Aurelia community was going to make a request to get it up there.

    ReplyDelete
  3. installs cleanly following the prereq's found on:
    http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/
    1. HMR needs to be commented out to Run: in Startup.cs
    2. Browser only displays : Loading...

    nothing beyond that is shown. Exact same whether executed with dotnet run or F5.

    ReplyDelete
    Replies
    1. Do you see anything in F12 console? Something seems to be keeping Aurelia from bootstrapping

      Delete
  4. /dist/vendor.css HTTP GET 404
    /dist/app.js HTTP GET 404
    /dist/vendor.js HTTP GET 404

    ReplyDelete
    Replies
    1. Ah, I know what this is. Need to run command line:
      webpack --config webpack.vendor.config.js.

      And then this can command line:
      webpack

      This builds the vendor, and app packages. The webpack vendor build only needs to happen one time, ever. The webpack app build should get triggered subsequent changes, but without HMR have to reload page after webpack finished builds.

      Delete
  5. errors follow executing the first command:
    webpack --config webpack.config.vendor.js
    Error: Module 'C:\Source\Repos\coreSpa\node_modules\css\index.js' is not a loade
    r (must have normal or pitch function)
    at loadLoader (C:\Source\Repos\coreSpa\node_modules\loader-runner\lib\loadLo
    ader.js:35:10)
    at iteratePitchingLoaders (C:\Source\Repos\coreSpa\node_modules\loader-runne
    r\lib\LoaderRunner.js:164:2)...

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. I had this same error when I used yo generator to create the aurelia spa project. After some searching I found that fixing the webpack version at 2.1.0-beta.25 fixed it. 2.1.0-beta.27 had been installed during the scaffolding and was causing an issue.

      Remove the ^ from the beginning of the webpack version number in package.json to fix the version at 2.1.0-beta.25.
      Then in command prompt (or bash etc) from the project root run
      npm install to pull down the right webpack version
      webpack --config webpack.config.vendor.js
      webpack
      dotnet run (then go to localhost:5000)

      Delete
    3. Thanks, Steven, for finding root cause of this issue! An unfortunate danger of living on the edge of the package.json "^". Since the Aurelia template is using Webpack 2.0 beta, this was/is an area likely to cause potential issues. Since you found issue and resolution, would you want to post to GitHub issues for the repo?

      Delete
    4. Actually, just checked and looks like Steve Sanderson already fixed this issue in the project.json - it's locked to beta.25 now

      Delete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Keith,

    Thanks for your work on this, it's just what I've been searching for.
    I like the integration with Visual Studio making the development process more fluid. And I agree, the dotnet CLI is pretty neat though it has thrown a few unhandled exceptions if I happen to have passed an incorrect flag or such as when I mistakenly typed in dotnet run --watch. I wonder if you've noticed the same. No biggie though, looking forward to tinkering with it more.

    ReplyDelete
    Replies
    1. Glad to hear! I also found some funkiness to the dotnet CLI. One of those was issue with the publish not working on subsequent runs. And now already .NET core is onto 1.1, and changing things up again!

      Delete
  8. Thanks for this! Are there any plans to make an esnext flavor? There's also an experimental webpack skeleton rewrite in the works that drops the dependencies on aurelia-boostrapper-webpack and aurelia-loader-webpack.

    It seems like this could be fairly easily updated if it stays an NPM package and uses yo. If they integrate it with VS and use VS templates, it'd be harder to keep updated.

    ReplyDelete
    Replies
    1. Chris, I think since it's a MS project, it will stay exclusively typescript. Someone could fork it and swap it out, but then have the extra overhead of keeping *that* up to date. Like you say, keeping stuff up to date is a huge challenge in front end dev world!

      Delete
  9. Did as instructed and all seem to work but once you hit dotnet run or F5 gives the following error in the console:
    SCRIPT5009: 'Promise' is undefined
    File: app.js, Line: 1170, Column: 3

    ReplyDelete
    Replies
    1. Sid, looks like from Anthony's comment below there must be a polyfill needed for promise on IE (I'm assuming using IE?). I develop exclusively in Chrome so never saw this issue. If you can add promise (and probably fetch) polyfill from NPM, should resolve issues.

      Delete
  10. I ran this and it initially ran great on all browser once I added support for fetch and Promise for internet explorer.. My problem came when I made a change to the code in one of the ts files to see how to get the project to refresh. I know that HMR is currently unsupported, but I am puzzled as to how to get a refresh to happen.. I shut down dotnet run and reran dotnet run and it said that it had already been compiled. I removed the bin and the obj folders and reran it and it rebuilt the dlls, but did not republish to the dist folder. I removed the dist folder and the bin and obj folders and it rebuilt the bin and obj folders, but did not repopulate the dist folder. How would I get this to rerun a transformation of my ts files so that it repopulates the dist folder?
    This is unclear to me. Thanks for your input

    ReplyDelete
    Replies
    1. Anthony - the webpack server that is running in background by the javascriptservices middleware should have a watch on the ts files, and recompile. However, when the HMR is not on, I wasn't able to consistently see the webpack output in the console window. But you should see the dist output get updated after a slight delay, and can refresh browser to see latest.

      If HMR is on, then you will see the webpack console output, so can tell exactly when webpack is done. I found it was easier to work with with HMR on, but then you get errors in browser F12 output (just refresh browser works fine). Hopefully when webpack HMR is supported, the project can be updated and will have a smoother experience.

      Delete
  11. Aurelia has just released aurelia-hot-module-reload (https://github.com/aurelia/hot-module-reload). Do you think that will address HMR needs?

    I wonder how that will work. I haven't seen any docs on it yet. Maybe it just works when present.

    ReplyDelete
    Replies
    1. Doug - I saw a note that you tried this out and it was working. I will try it out and if it works will submit a PR for it to the main repo. Thanks!

      Delete
    2. Hi Keith, I deleted that note because, if HMR was ever truly working at all, it stopped, and I couldn't get it to work after that. I may have been dreaming that it was working in the first place. :-S

      It would be great if you were able to figure it out!

      Here is the full set of steps I used:

      1. install JavaScriptServices template per instructions
      2. npm install aurelia-hot-module-reload --save
      3. npm install aurelia-loader-webpack@2.00 --save
      4. in Startup.cs set HotModuleReplacement = true
      5. in webpack.config.vendor.js, under entry.vendor, add 'aurelia-hot-module-reload',
      6. webpack --config webpack.config.vendor.js
      7. webpack
      8. dotnet run --environment "development"
      9 .Browse to http://localhost:5000

      Running in Chrome: What happens is that, watching the Chrome debugger console output, I can see HRM connecting ("[HMR] connected"), but when I update some HTML or JavaScript, nothing happens in the GUI and I see a error in the console: "TypeError: Cannot read property 'status' of undefined". This appears to be due to "module.hot" being undefined in aurelia-loader-webpack.

      Let me know if I can help with this! Thanks!

      Delete
    3. Could be this is the problem: https://github.com/aurelia/loader-webpack/pull/25

      Delete
    4. Doug - I'm getting exact same problem you are. Searching found someone else on StackOverflow, with your comment as well =)

      I'm thinking that there may be some additional as yet uncommitted dependencies in aurelia webpack loader, based on some comments here: https://github.com/aurelia/skeleton-navigation/pull/714

      It's a long discussion, and my take is that there's some in progress changes in aurelia webpack support that the HMR stuff might be layered upon. It looks like when those are pulled in, there's going to be some other nice stuff coming in with it though.

      Bottom line, I think until that new version of the skeleton is integrated into mainline with its updated Webpack functionality (and raw webpack configuration) it could be tricky to figure this one out.

      Delete
    5. Yes, I've seen that conversation too and came to the same conclusion as you. Things seem to be moving a lot regarding webpack and support for module loaders in general, the question is just how soon we'll see something released. Could be breaking-enough to be part of a major 2.0 release.

      Thanks for looking into this and validating my reality. :-)

      Delete
  12. The only way the typescript compiler ever runs is if I run it manually using tsc.exe.

    ReplyDelete
    Replies
    1. app.js is being updated, but without the changes that it would contain had the ts changes been recompiled.

      Delete
    2. I note that the ts-loader version included with AureliaSpa is quite old (0.8.2 versus the current 1.3.2).

      I am using TypeScript v2.1, if that is relevant. Also using Asp.Net Core 1.1.

      Delete
    3. Upgraded ts-loader to the latest. No change, still no typescript compile within `dotnet run`. None within `webpack`. Only if I manually run `tsc`.

      Delete
    4. Doug,

      I pulled down latest again today, just to make sure nothing going on. I believe issue is that the ASPNET_ENVIRONMENT has to be set to Development for webpack to be started up (otherwise, assumes it is in prod mode and being hosted).

      There's a couple ways to set this variable, but easy one is just to pass in on command line:

      dotnet run --environment "Development"

      Try that out, thanks!

      Delete
    5. Thanks so much for checking, Keith! I had already tried your suggestion. When I modify a .ts file, the app.js is updated, but the modified .ts file has not been recompiled so the changes are not included inthe new app.js file.

      Delete
    6. I'm afraid I don't understand enough of what is going on under the hood to understand why this is happening.

      Delete
    7. Just a note here: I noted the solution in an ensuing thread, below

      Delete
  13. Not sure why it would not be picking up the latest .ts file changes. I just tested the current JavaScript services code (basically did a new clone, dotnet restore at root of repo, and then npm install in the Aurelia template folder), then did "dotnet run" in development mode. App comes up fine (using Chrome, need a promise polyfill for IE)

    I then updated the counter.ts to do an increment of 2 instead of 1. The app.js gets recompiled, and after refreshing browser it correctly incremented by 2 for me.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. I just started cleanly from scratch. It does indeed work with counter.ts. But if I add a new .ts module, it doesn't work with the new module.

      Delete
    3. OK, it seems that the fact that when I drag/dropped the new .ts file into the folder, I included the .js and .map files, and that confused the heck out of some component or another. After I deleted the .js and .map files and restarted `dotnet run`, it works fine.

      Delete
  14. This comment has been removed by the author.

    ReplyDelete
  15. I am receiving all notifications about this discussion - and wanted to register my interest for it (too busy at the moment to do more than just say this)

    ReplyDelete
  16. Keith, have you tried publishing to IIS an app created with this template? It seems to require that the `node_modules` folder be published. That seems like too much to ask, and figuring out which specific modules are required is a pain.

    Maybe I'm missing something...

    ReplyDelete
  17. This implies not exclusively will you get Outlook Support on the official Support for Microsoft page, yet bolster for other Microsoft items and administrations also.
    microsoft technical support toll free number

    ReplyDelete
  18. Not only that, but a function can accept another function as a parameter and can also return a function. You can have functions with no names as well.
    best web design tutorials

    ReplyDelete
  19. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from Javascript Training in Chennai . or learn thru JavaScript Online Training in India. Nowadays JavaScript has tons of job opportunities on various vertical industry. JavaScript Training in Chennai

    ReplyDelete
  20. Terrific is the most suitable word to depict this blog.
    software development company in delhi

    ReplyDelete
  21. They have been our #1 general choose for his or her top-tier gaming library, their generous welcome bonuses 우리카지노 connected to low playthroughs, and their fee-free cashouts. We should clarify that in many of} nations Bitstarz is a crypto-only on line casino, so if you’re trying to deposit with bank cards or an e-wallet you might be out of luck. There’s additionally no minimum deposit required to say your daily free spins here; although their most allowable guess restrict is capped at 100,000 coins ($100).

    ReplyDelete
  22. FDM technology constructs from the underside up, while CNC machining works by slicing and drilling pieces away from a block of material into its form. Generally talking, 3D printing is used to supply prototypes and has comparatively low pace compared to with} CNC machining. Because of this, it's not environment friendly for producing giant portions. While CNC machining has created super new alternatives for all types of companies, it has also led to much less standard Direct CNC machining and in the end, some unemployment. However, most specialists do not agree that handbook expertise will turn into out of date. In truth, some assume standard machining will thrive through small and specialty projects.

    ReplyDelete