Advertisement

#1 Quick Start

In this article we will begin by creating a new project using the web application template provided in Visual Studio. Once the project is created we will remove the unnecessary parts that are included in the template, modify the existing shared layout and home pages and finally set our project up to use the hot module replacement capabilities of webpack.

Project Creation

This project begins as they all do using File -> New -> Project in Visual Studio. You are of course free to use any IDE/Text editor that you prefer but we will be using Visual Studio and Visual Studio Code throughout this series. Both are available for free at Visual Studio Community and Visual Studio Code. When starting a new project I more likely than not begin with creating a blank solution (a), which at the time of the writing of this article will be targeting version 4.6.1 of the .Net Framework which I will name AspNetCoreAngularWebpack. Next we need to add a new project in our blank solution again using File -> New -> Project but this time we are going to create an ASP.NET Core Web Application (b), which I have named WebUi. After clicking ok we are presented with another dialog which we use to select the specific template that we want to start with. After making sure that the selection box at the top of the dialog says 'ASP.NET Core 2.0' we will select the 'Web Application' option with no authentication (c) and click ok.

Visual Studio interface for creating a blank solution.
(a) Visual Studio interface for creating a blank solution.
Visual Studio interface for creating an Asp.Net Core Web Application.
(b) Visual Studio interface for creating an Asp.Net Core Web Application.
Visual Studio interface for creating an Asp.Net Core 2.0 without authentication.
(c) Visual Studio interface for creating an Asp.Net Core 2.0 without authentication.
  • WebUi
    • WebUi.csproj

If you are using Visual Studio we need to disable its built in behaviour for dealing with typescript files since we will be using webpack to transpile all of them. To do this we need to add an entry to our WebUi.csproj file by simply right clicking on the project in the solution explorer and selecting 'Edit WebUi.csproj' option which will open the file for us. Once it is open we need to add the property group (d) to it. This will prevent the transpiling of the typescript code when our solution is built.

WebUi.csproj (1)

<PropertyGroup>
    <TypeScriptCompileBlocked>True</TypeScriptCompileBlocked>
</PropertyGroup>
(d) Property group that we need to add to our WebUi.csproj file in order to disable the automatic compilation of our typescript files when building our project using Visual Studio.

Time to lighten the load

  • WebUi
    • wwwroot
      • css
        • site.css
        • site.min.css
      • images
        • banner1.svg
        • banner2.svg
        • banner3.svg
        • banner4.svg
      • js
        • site.js
        • site.min.js
      • lib
        • bootstrap
        • jquery
        • jquery-validation
        • jquery-validation-unobtrusive
    • Pages
      • _Layout.cshtml
      • Index.cshtml

Now it is time for us to remove some files that were included by the project creation template. As shown in the folder structure we want to remove all of the files contained in the various sub-folders of the wwwroot folder. Once that is completed we will modify the _Layout.cshtml (e) and Index.cshtml (f) files contained in our Pages folder. The _Layout.cshtml references both css and javascript files that we will define in the next section.

_Layout.cshtml (1)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"]</title>
    <environment include="Development">
        <link rel="stylesheet" href="~/css/main.bundle.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="~/css/main.bundle.min.css" asp-append-version="true" />
    </environment>
    @RenderSection("Styles", required: false)
</head>
<body>
    @RenderBody()
    <environment include="Development">
        <script src="~/js/common.bundle.js"></script>
        <script src="~/js/main.bundle.js"></script>
    </environment>
    <environment exclude="Development">
        <script src="~/js/common.bundle.min.js" asp-append-version="true"></script>
        <script src="~/js/main.bundle.min.js" asp-append-version="true"></script>
    </environment>
    @RenderSection("Scripts", required: false)
</body>
</html>
(e) Minimal _Layout.cshtml file using the bundles created with webpack.

Index.cshtml (1)

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<h1>Index</h1>
(f)

How about some scss and typescript

  • WebUi
    • Source
      • main.site.scss
      • main.site.ts

As mentioned in the previous section we need to add the site wide scss and typescript files for our project. We do this by creating a Source folder at the root of our project. Inside the source folder we will create a main.site.scss (g) file and a main.site.ts (h) file. The contents of the files are of course just temporary and are being used to make sure that our project is set up correctly. Now that we have scss and typescript files included in our project we need to be able to convert them to css and javascript respectively. Luckily there exists another quick start article for webpack quick start article for webpack.

main.site.scss (1)

body {
    font-size: 96px;
}
(g) Site wide scss file with temporary content.

main.site.ts (1)

document.body
    .appendChild(document
        .createElement("div")
        .appendChild(document
            .createTextNode("Hello World!")));
(h) Site wide typescript with temporary content.

If all has gone well with the setup of webpack once we run the npm run build command, at the root of our project, and start the server by using the Debug -> Start Without Debugging command located in the toolbar of Visual Studio we should be greeted with the home page shown in (i).

Output of our home page showing the bundles are being compiled successfully.
(i) Output of our home page showing the bundles are being compiled successfully.
Advertisement

That's nice but you promised I wouldn't need to use the refresh button

  • WebUi
    • Startup.cs

The first thing we need to do start the process of enabling the hot module replacement capability of webpack is to install the Microsoft.AspNetCore.SpaServices package using NuGet. Simply right-click on the dependencies node in our project explorer and select Manage NuGet Packages.... Once that package is installed we need to modify our Startup.cs file to enable the hot module replacement (j).

Startup.cs (1)

...
using Microsoft.AspNetCore.SpaServices.Webpack;
...
namespace WebUi
{
    public class Startup
    {
        ...
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                ...
                app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
                {
                    HotModuleReplacement = true
                });
            }
            ...
        }
    }
}
(j) Code to enable webpack's hot module replacement on the server side.

Returning to the browser and pressing refresh, for we are sure the last time, we are presented with an error which tells us that we a missing a couple of npm packages (k).

Error indicating we are missing a couple of npm packages.
(k) Error indicating we are missing a couple of npm packages.

To fix this error we just need to install the packages shown in (l). Once the packages are added you will probably need to rebuild the project in order to make it work.

npm install (1)

npm install --save-dev
aspnet-webpack
webpack-hot-middleware
(l) The code to install the two required npm packages.

Does it work?

  • WebUi
    • Source
      • main.site.ts

After rebuilding the project and refreshing the browser if we make a change to our main.site.ts file (m) and save it we are presented with the output in our browser console shown in (n). This output is telling us that the update that we were just attempting to make have been ignored. This is due to the fact the updates are an opt in and we have not opted in for our module.

main.site.ts (2)

document.body
    .appendChild(document
        .createElement("div")
        .appendChild(document
            .createTextNode("Hello World! Does this work?")));
(m) Making a change to our main.site.ts file to see if the changes are shown automatically in the browser.
Console output telling us we need to make one more update before our changes are picked up
            automatically.
(n) Console output telling us we need to make one more update before our changes are picked up automatically.

Opting in to HMR

  • WebUi
    • Source
      • main.site.ts

Before we make the last change to our main typescript file we need to include the node types if we have not already done it previously as well as the types for the webpack module API (o). With that done we will return to our main.site.ts file and update it (p). As you can see in (p) we have modified the appending to add a css class to the div so that we can first remove it and then reappened it when a change is made.

npm install (2)

npm install --save-dev
@types/node
@types/webpack-env
(o) We need to install the type definitions for node and the webpack module API.

main.site.ts (4)

if (process.env.NODE_ENV === "development" && module.hot) {
    module.hot.accept();

    const oldApp = document.getElementsByClassName("app")[0];
    if (typeof oldApp !== "undefined" && oldApp !== null) {
        oldApp.remove();
    }
}

const app = document.createElement("div");
app.classList.add("app");
const child = document.createTextNode("Now it works");
app.appendChild(child);
document.body.appendChild(app);
(p) Final update to our main typescript file so that hot module reloading happens the way we expect it to.

With that done, and refreshing the browser one last time, changes that we make are now picked up automatically without the need for us to precess the refresh button.

Any update that we make to our message is automatically picked up and displayed in
            the browser.
(q) Any update that we make to our message is automatically picked up and displayed in the browser.
Exciton Interactive LLC
Advertisement