gulp

Add Aurelia to an ASP.NET Core Project

In this post I am going to add a new project to the my existing ASP.NET Core Basics solution which can be found in this repository. The new project will be MVC 6  to which I will add in Aurelia. With both ASP.NET and Aurelia now being at RTM I thought this would be a good time to cover getting a new project setup.

Over time the ASP.NET Core Basics repo used in this post is going to be replacing my ASP.NET Core SPAs repo based on some feedback that having Aurelia and Angular 2 in the same project made it harder to see how each individual framework is setup.

Part 1 – Add Aurelia to an ASP.NET Core Project (This Post)
Part 2 – Aurelia with an ASP.NET Core API
Part 3 – Aurelia with an ASP.NET Core API: Modeling and Displaying Data in Aurelia
Part 4 – Aurelia with ASP.NET Core: Host Aurelia from a Controller
Github repo with the code for all of the parts with a release to go with each post

 Adding a new project to an existing solution

To add a new project to the existing solution right click on the solution and then click Add > New Project.

AddProjectExistingSolution

On the Add New Project dialog select ASP.NET Core Web Application (.NET Core), enter a name and then click OK.

AddNewProjectDialog

On the New ASP.NET Core Web Application (.NET Core) dialog select Web Application. This application doesn’t need authentication so leave it set to No Authentication. Finally click OK.

NewASPNetCoreWebApplication

After a few seconds the project creation will complete and the solution will contain two projects. The existing Contacts project that contains both a razor/normal implementation of a contacts list as well as an API implementation. The second project is the newly created Aurelia project.

SolutionWithTwoProjects

Changing the startup project

Notice in the screenshot above that the Contacts project is in bold. This means that the Contacts project is set as the startup project and it will be the project that starts when the application is run (F5 or Cntrl + F5). In this post we will just be working with the Aurelia project so we need to make it the startup project. To do this right click the Aurelia project and select Set as StartUp Project.

SetAsStartupProject

Now if you hit F5 the Aurelia project will run. Visual Studio provides a lot of flexibility around which projects start up. You can select a single, have which ever project you have to have select, or even multiple projects.  In a later post we will need both projects to start up and I will cover that when we have the need.

Install the Aurelia CLI

Make sure you have a minimum of NodeJs 4.x or above installed. If you need the installer it can be found here. After the install is complete open a command prompt and run the following command to install the Aurelia CLI.

npm install aurelia-cli -g

Add Aurelia to existing ASP.NET Core Project

In a command prompt navigate to the folder that contains the xproj file for the ASP.NET Core project created above. Now the Aurelia CLI can be used to setup a new Aurelia project at the current location using the following command.

au new --here

There will be a series of prompts the first of which is the selection of which platform to use. Select the option for ASP.NET Core (option 2). I used the defaults for most of the remaining prompts. The exception was for unit testing which I selected no on just to keep the project simpler not because I think testing is a bad idea.

When the Aurelia CLI finishes its file creation and dependency restore your project will contain the highlighted new files and folders.

auaddedfiels

Notice that I have a warning on Dependencies that something is not installed. There is a quirky issue with Visual Studio that Scott Hanselman has blogged about here. He goes in to a good bit of detail about what is going on as well as suggesting a work around. It has to do with npm and not being about to restore an optional package that isn’t meant for Windows machines.

gulp

The Aurelia CLI creates a set of tasks to help with building, transpiling the Aurelia part of the applications. I wrote a couple of posts over the couple few weeks dealing with converting a project to use glup as well as how to get gulp working with ES 2015.

I am going to cover the abbreviated version of those two post here. Add a new file called gulpfile.babel.js in the root of the project, where your project.json is located. The Aurelia CLI added all the needed items in the devDependencies section of package.json.

gulp no go

At this point I attempted to include the tasks under aurelia_project/tasks using require(‘require-dir’)(‘aurelia_project/tasks’);. This failed completely. I couldn’t get any of the items in the tasks folder to show up. I am not sure why this didn’t work. My best guess is that the tasks in the tasks folder are exporting gulp.series and not gulp.task. I just don’t know enough about gulp at this point to now how to fix/work around this or if what I am trying to do is just not the right way it should be used.

The gulp work around

I spent more time that I would have like working on getting gulp to pick up the items in the tasks folder, but I don’t want to have to run a CLI command every time I do a build to make sure all the Aurelia related files are up to date. As a work around I decided to add a gulp task to invoke the CLI command for me.

To start open package.json  and add the following to the devDependencies section which allows shell commands to be run from gulp.

"gulp-shell" :  "0.3.0"

Next in gulpfile.babel.js added the proper imports and created tasks for the CLI commands I wanted to run. In the case I am just showing the build command.

import gulp from 'gulp';
import shell from 'gulp-shell';

gulp.task('bulid', shell.task(['au build']));

Using the Task Runner Explorer this task can now be set to run after a build of the MVC project.

treafterbuild

This accomplishes what I wanted, but it feels like a hack. If anyone knows a better way please let me know.

It’s Alive!

At this point if you run the application it will go to the normal default home page that gets created by the Visual Studio template. For me that address is http://localhost:37472/. From there if you add index.html, the full address is http://localhost:37472/index.html, you will be invoking the Aurelia application.

At this point all you will see is “Hello World!”. Not that impressive I know, but it is a starting point that we will build on in future posts.

The associated code can be found here.

Add Aurelia to an ASP.NET Core Project Read More »

Unexpected token import with gulp

I have started to play with the release version of Aurelia. My current goal is to see what it takes to get going with Aurelia and ASP.NET Core now that both are RTM. I have hit a couple of road blocks that have ended up being new post of their own. For example this post that covers converting a new ASP.NET Core application to use gulp is one example. Today’s post is going to cover another issue I hit trying to use the gulp tasks created by the Aurelia CLI. There will not be anything Aurelia related in this post that will another post at a later date.

gulp setup

My gulpfile.js is nothing but a reference a directory of tasks. The full file looks like the following.

require('require-dir')('tasks');

Then I have a single task in tasks/exampleTask.js that consists of the following.

import gulp from 'gulp';

gulp.task('helloGulp', function(done){
 console.log('Hello Gulp!');
 done();
});

The error

With the above in place if you look at the task runner explorer you will see that Gulpfile.js shows a failed to load error instead of the helloGulp task.

gulpfailedtoload

As suggested by task runner explorer open the output window. There are many different things that use the output window so be sure and change show output from option to Task Runner Explorer. With that done you will be able to see why the task failed to load. The following is the error I am getting.

Failed to run "C:\ProjectDirectory\Gulpfile.js"...
cmd.exe /c gulp --tasks-simple
C:\ProjectDirectory\tasks\exampleTask.js:3
import gulp from 'gulp';
^^^^^^
SyntaxError: Unexpected token import
    at Object.exports.runInThisContext (vm.js:76:16)
    at Module._compile (module.js:528:28)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at requireDir (C:\ProjectDirectory\node_modules\require-dir\index.js:116:33)
    at Object.<anonymous> (C:\ProjectDirectory\gulpfile.js:1:85)

The fix

I did some googling and I found this post by Mark Goodyear on using ES6 (or ES 2015) with gulp. It turns out the tasks generated by the Aurelia CLI are using ES 2015 and in order to use ES 2015 with gulp there are a few steps that must be taken first. Mark does a great job explaining those steps, but I am going to include a summary from the Visual Studio perspective.

Verify the devDependencies section in package.json contains the following. require-dir is only required if your gulpfile or tasks are using it.

"devDependencies": {
  "gulp": "3.9.1",
  "babel-preset-es2015": "^6.9.0",
  "require-dir":  "^0.3.0" 
}

Next create a .babelrc file at the same level as the package.json file with the following contents.

{
  "presets": [ "es2015"]
}

Then rename gulpfile.js to gulpfile.babel.js.

Back in the Task Runner Explorer hit the refresh button in the top left of the window which should now load your list of tasks under Gulpfile.babel.js with no errors.

taskrunnerrefersh

 

Unexpected token import with gulp Read More »

Change from Bundle & Minifier to Gulp in Visual Studio

When ASP.NET Core 1.0 was released Microsoft switched gulp for Mads Kristensen‘s Bundler & Minifier. This post is going to cover taking a project that is using Bundler & Minifier and change it to use gulp instead. Don’t take this as problem with Bundler & Minifier I am just more familiar with gulp and didn’t mix in another new tool.

The extension

There is a Bundler & Minifier extension available that make the change to gulp super simple. You could do all this yourself, but the extension seems to be the fastest way to convert without having to worry about htting. Click the Tools > Extensions and Updates menu. Then in the Extensions and Update dialog on the left select Online. Next on the top right enter “bundler & minifier” in the search box. Then click the download button next to Bundler & Minifier and follow the prompt to install and then restart Visual Studio.

ExtensionBundlerMinifier

The conversion to gulp

Right click on your project’s bundleconfig.json (this is the file that is used to configure the default bundling and minification stuff) and select Bundler & Minifier > Convet To Gulp.

converttogulpmenu

This will show a warning dialog saying that the process will take a few minutes due to npm restores, etc. When the process is done you will now have a gulpfile.js file. The gulpfile.js file that is created will require bundleconfig.js in order to expose your existing tasks.

Required edit to bundleconfig.js

Since the generated gulpfile.js is using the existing tasks in bundleconfig.js all the comments must be removed from bundleconfig.js before gulp will work properly. This is due to comments not being valid json and the parser that gulp uses sees the json as being invalid. The following line exists in the generated gulpfile.js, but it is easy to miss so I wanted to call it out.

bundleconfig = require("./bundleconfig.json"); // make sure bundleconfig.json doesn't contain any comments

Wrapping up

package.json is the other file that got created during this process. If you are doing this manually don’t forget this file. I had tried this conversion manually once before and I am pretty sure this file is the reason I was not successful.

As I stated above I went the route of the extension so I wouldn’t miss anything and it worked out well. Now knowing what needs to be changed I could do it manually, but the extension works so well I recommend using it.

Thanks to Jon Galloway as I first saw this process at one of his talk at Code on the Beach.

Change from Bundle & Minifier to Gulp in Visual Studio Read More »

Angular 2 Quickstart with ASP.NET Core

Updated version of this post can be found here.

After working with Aurelia over last couple of months it seemed prudent to try out Angular 2. This post is going to cover the installation of Angular 2 and launching a basic Angular 2 application from an ASP.NET Core (the new name for ASP.NET 5) controller. Make sure to check out the official quickstart guide here.

Installation

Open the package.json file and add the following dependencies and devDependencies. This project is using gulp and is using the typescript based version of the quickstart guide which is why the gulp and typescript references are there.

  "dependencies": {
    "angular2":"2.0.0-beta.1",
    "systemjs": "0.19.16",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.33.3",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.0",
    "zone.js": "0.5.10"
  },
  "devDependencies": {
    "gulp": "3.9.0",
    "gulp-concat": "2.6.0",
    "gulp-cssmin": "0.1.7",
    "gulp-uglify": "1.5.1",
    "gulp-typescript": "2.10.0",
    "rimraf": "2.5.0",
    "typescript": "1.7.5"
  }

If inside Visual Studio 2015 the proper packages will be restored when package.js is saved, but outside of Visual Studio open a command prompt to the same directory as the package.js file and run npm install  which will download the required packages.

Typescript Configuration

Next add a tsconfig.json file to the project. This file marks the root of a typescript project and contains configuration setting for that project. Details on configuration options can be found here.

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "system",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules"
  ]
}

Angular 2 Bootstrap and Basic App

Create an Angular folder in the project’s root folder. Next add a app.component.ts file which is used to manage a view. This component is super simple and was pulled from the official quickstart guide.

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }

Next add boot.ts which is used to bootstrap Angular 2.

import {bootstrap}    from 'angular2/platform/browser'
import {AppComponent} from './app.component'

bootstrap(AppComponent);

Gulp Tasks

This is the project that was the inspiration for the gulpjs introduction post. The first task is to move the Angular 2 dependencies from the node_modules folder to an Angular folder in wwwroot  so they will be available to be served.

gulp.task("angular2:moveLibs", function () {
    return gulp.src([
            "node_modules/angular2/bundles/angular2-polyfills.js",
            "node_modules/systemjs/dist/system.src.js",
            "node_modules/systemjs/dist/system-polyfills.js",
            "node_modules/rxjs/bundles/Rx.js",
            "node_modules/angular2/bundles/angular2.dev.js"
        ])
        .pipe(gulp.dest(paths.webroot + "Angular"));

});

The next task move the js files created by the typescript compiler when a ts file is saved from the Angular folder in the root of the project to wwwroot/Angular.

gulp.task("angular2:moveJs", function () {
    return gulp.src(["Angular/**/*.js"])
        .pipe(gulp.dest(paths.webroot + "Angular/app/"));

});

The last task just runs both of the previous tasks.

gulp.task("angular2", ["angular2:moveLibs", "angular2:moveJs"])

ASP.NET Controller

The Angular application is going to be run from the ASP.NET’s HomeController. Here is the new action that will load the yet to be created view.

public IActionResult Angular2()
{
    return View();
}

ASP.NET View

This is the view that when loaded kicks off the Angular 2 application. Add a new file called Angular2.cshtml in the Views/Home folder.  In the following first Angular related scripts are loaded. Then system.js is configured and the boot module is imported and the app is rendered inside of the my-app tag.

<html>
<head>
    <title>Angular 2 QuickStart</title>

    <script src="~/Angular/angular2-polyfills.js"></script>
    <script src="~/Angular/system.src.js"></script>
    <script src="~/Angular/Rx.js"></script>
    <script src="~/Angular/angular2.dev.js"></script>

    <script>
        System.config({
            packages: {
                '../Angular': {
                    format: 'register',
                    defaultExtension: 'js'
                }
            }
        });
        System.import('../Angular/app/boot')
              .then(null, console.error.bind(console));
    </script>

</head>

<body>
    <my-app>Loading...</my-app>
</body>

</html>

This is where the trouble started for me. It took a bit of searching, but the problem turned out to be with the system.js configuration. Since the view is in the HomeController it gets rendered out of as Home/Angular2.html and this project’s Angular files are up a directory so in order for system.js to find the Angular files the package configuration needed to be set to look up one folder.

This issue took longer to find than I would like to admit, but that is the danger is using libraries one is not familiar with. System.js was not my first thought since it was used in my Aurelia without issue. If you run into an issue check out the docs for system.js configuration.

Finally add the new view to main application’s nav bar. In Views/Shared/_Layout.cshtml add a link to Angular 2 on using the Home controller.

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li><a asp-controller="Home" asp-action="Index">Home</a></li>
        <li><a asp-controller="Home" asp-action="Angular2">Angular 2</a></li>
        <li><a asp-controller="Home" asp-action="About">About</a></li>
        <li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
    </ul>
    @await Html.PartialAsync("_LoginPartial")
</div>

Follow Up

This is a very basic Angular 2 application. Expect a follow up post in the new few weeks with this application build out more to utilize the same contacts web API as my Aurelia posts.

Update

If you are having issues upgrading beta 7 check out this post for a solution.

Angular 2 Quickstart with ASP.NET Core Read More »

Introduction to gulpjs

Working on a future blog post I hit some problems involving files that needed to be moved around as part of build process. This is one of the problems that gulp solves.

What is gulp?

Gulp is a task runner that utilizes node. The core idea behind task runners is automation. Have less that needs compiled into css, minified and output into the proper directory? That is a great use case for a task runner.

Gulp is not the only task runner out there. Grunt is another option and has actually been around longer. I am using gulp because it is the default in Visual Studio 2015. Google gulp vs grunt and decide which is right for you.

Installation

  1. Install node if needed from this site.
  2. From the console install gulp using npm install gulp -g

Project setup

Next add a gulpfile.js the root of the project where gulp is to be used. If using ASP.NET 5 this file will already exist and will include a few prebuilt tasks. If you are not using ASP.NET 5 the following is a mimimum gulpfile from the official getting started guide.

var gulp = require('gulp');

gulp.task('default', function() {
  // place code for your default task here
});

Also add gulp to the devDependencies section of the project’s package.json file. Since Visual Studio handles edits to package.json so nicely (intellisense and automatic package restore) I tend to edit the file manually instead of using npm.

 "devDependencies": {
    "gulp": "3.9.0"
  }

Plugins

The base gulp API only contains 4 functions (src, dest, task and watch) and doesn’t do a whole lot on its own. This is where plugins come in. Gulp has a ton of plugins that do all sorts of useful things. For example, the default gulpfile.js provided by Visual Studio has a min:js task that used gulp-concat and gulp-uglify to combine javascript files and then minify the result.

Example gulpfile for minification of javascript

The following is a full gulpfile based on the default file generated by Visual Studio stripped down to just the bits needed for the min:js task.

"use strict";

var gulp = require("gulp"),
    concat = require("gulp-concat"),
    uglify = require("gulp-uglify");

var paths = {
    webroot: "./wwwroot/"
};

paths.js = paths.webroot + "js/**/*.js";
paths.minJs = paths.webroot + "js/**/*.min.js";
paths.concatJsDest = paths.webroot + "js/site.min.js";

gulp.task("min:js", function () {
    return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
        .pipe(concat(paths.concatJsDest))
        .pipe(uglify())
        .pipe(gulp.dest("."));
});

The above will pull all the javascript files from wwwroot/js and its subfolders and combine them and output the results to site.min.js in the wwwroot/js folder.

Introduction to gulpjs Read More »