Advertisement

#1 Creation and Basic Setup

In this article we will perform the creation and basic setup for our project.

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, we will add authentication ourselves later, and click ok.

(a) Visual Studio blank solution
(b) ASP.NET Core Web Application
(c) ASP.NET Core 2.0 without authentication

Folder Structure

  • WebUi
    • wwwroot
      • css
        • site.css
      • images
        • banner1.svg
        • banner2.svg
        • banner3.svg
        • banner4.svg
      • lib
      • js
        • site.js
    • Source
      • sass
        • 0-bourbon
        • 1-neat
        • 2-base
          • _media-queries.scss
        • _bourbon-neat.scss
    • .bowerrc
    • bower.json

Now that our project is created we will add and remove a few files and folders. All the files and folders that are shown in red can be deleted. Once that is done our next step is to create a 'Source' folder in the root of the project which will hold all of the files that we need to create the front-end of the application. Inside of this folder we need to create a 'sass' folder, which as you have guessed will contain our styles outside of those pertaining to a particular component. After creating a the Sass forlder we need to open a terminal inside of it execute the following commands: bourbon install, which will create a bourbon folder, neat install, which will create a neat folder and finally bitters install which will create a base folder. What I like to do next is rename these folders to keep them in a particular order so I rename them bourbon -> 0-bourbon, neat -> 1-neat, and base -> 2-base. I picked this convention up by watching YouTube videos from DevTips. He has some very good we design tutorial videos and I highly encourage you to check them out if you are interested. All three of the preceding install commands come from ruby gems which of course requires you to have ruby installed on your machine which you can find at https://rubyinstaller.org/. The packages themselves were created by thoughtbot and the documentation for each can be found at bourbon, neat, and bitters. At the time of the writing of this article the versions that we are using are bourbon: 5.0.0-beta.8, neat: 2.1.0, and bitters: 1.7.0. In order to make it easy for us to import the files from both the 0-bourbon and 1-neat folders we will create a file called '_bourbon-neat.scss' (d) in the sass folder which will import the file from both folders that exports all of their contents.

Note: This project will make use of the console for running our front-end build process and as such I very quickly became unhappy with the console available on Windows so I have installed a console emulator name ConEmu.
Note: All code blocks that appear, not including inline code, will have a copy button where if you press it the contents of the block will be copied to your clipboard allowing you to then paste it to your IDE/text editor.

There will already be several files inside of the 2-base folder but we need to create one more named '_media-queries.scss' (e). This file just contains a few mixins that I like to use to make writing media queries a little bit easier and we will be writing a ton of them as the project progresses. This will allow us to write our media queries like @include media-lt(768px) which will be active when the screen is less than 768px wide and @include media-gt(768px) which will be active when the screen is greater than 768px wide. We also have the equivalent mixins for less than or equal to, greater than or equal to and between a min and max value.

_bourbon-neat.scss

@import "0-bourbon/_bourbon.scss";
@import "1-neat/_neat.scss";
(d) File that imports all the contents of 0-bourbon and 1-neat folders.

_media-queries.scss

@import "../_bourbon-neat.scss";

@mixin media-lt($max-width) {
    @media screen and (max-width: $max-width - 1) {
        @content;
    }
}

@mixin media-lt-or-eq($max-width) {
    @media screen and (max-width: $max-width) {
        @content;
    }
}

@mixin media-gt($max-width) {
    @media screen and (min-width: $max-width + 1) {
        @content;
    }
}

@mixin media-gt-or-eq($min-width) {
    @media screen and (min-width: $min-width) {
        @content;
    }
}

@mixin media-between($min-width, $max-width) {
    @media screen and (min-width: $min-width) and (max-width: $max-width) {
        @content;
    }
}
(e) Mixins that will make writing media queries much simpler.
Advertisement

Node Setup

Next we turn to setting up our Node.js environment by navigating our console to the root of the project and typing npm init -y which will create a default package.json file for us. I have changed the value of the name property from 'WebUi' to 'web-ui' the specification for the package.json file should not contain capital letters and added to the scripts and dependencies. You can either install the packages yourself (f) or you can copy and paste the package.json file (g) from here and run npm i. One last thing we need is to either install TypeScript locally using npm or as I have it globally and then create a link to it. To do that we need to run npm link typescript at the root of our project.

npm install

npm install --save
@angular/common
@angular/compiler
@angular/core
@angular/forms
@angular/http
@angular/platform-browser
@angular/platform-browser-dynamic
@angular/router
@types/node
@types/web-animations-js
autoprefixer
classlist-polyfill
core-js
css-loader
extract-text-webpack-plugin
html-loader
lodash
node-sass
normalize.css
postcss-loader
pug-html-loader
raw-loader
rxjs
sass-loader
style-loader
ts-loader
uglifyjs-webpack-plugin
web-animations-js
webpack
webpack-bundle-analyzer
zone.js
(f) Code that can be used to install individual npm packages.
{
  "name": "web-ui",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "@angular/common": "^4.4.4",
    "@angular/compiler": "^4.4.4",
    "@angular/core": "^4.4.4",
    "@angular/forms": "^4.4.4",
    "@angular/http": "^4.4.4",
    "@angular/platform-browser": "^4.4.4",
    "@angular/platform-browser-dynamic": "^4.4.4",
    "@angular/router": "^4.4.4",
    "@types/lodash": "^4.14.77",
    "@types/node": "^8.0.33",
    "@types/web-animations-js": "^2.2.5",
    "autoprefixer": "^7.1.5",
    "classlist-polyfill": "^1.2.0",
    "core-js": "^2.5.1",
    "css-loader": "^0.28.7",
    "extract-text-webpack-plugin": "^3.0.1",
    "html-loader": "^0.5.1",
    "lodash": "^4.17.4",
    "node-sass": "^4.5.3",
    "normalize.css": "^7.0.0",
    "postcss-loader": "^2.0.6",
    "pug-html-loader": "^1.1.5",
    "raw-loader": "^0.5.1",
    "rxjs": "^5.4.3",
    "sass-loader": "^6.0.6",
    "style-loader": "^0.19.0",
    "ts-loader": "^2.3.7",
    "uglifyjs-webpack-plugin": "^1.0.0-beta.3",
    "web-animations-js": "^2.3.1",
    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "zone.js": "^0.8.18"
  }
  "scripts": {
    "build": "set NODE_ENV=development&&webpack --progress",
    "build:production": "set NODE_ENV=production&&webpack --progress -p",
    "test": "echo \"Error: no test specified\" && exit 1",
    "watch": "set NODE_ENV=development&&webpack --progress --watch"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
(g) The package.json at the start of our project.

Typescript Setup

  • WebUi
    • tsconfig.json
    • tslint.json
    • WebUi.csproj

Speaking of TypeScript we need to add a couple of configuration files for the TypeScript compiler both of which will be created at the root of our project. The first file that we need to create is the 'tsconfig.json' file (h). This file will be used by the typescript loader when calling the typescript compiler to pass in the configuration options. A detailed explanation of the contents can be found at https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. Next create a file called 'tslint.json' (i) in the root of the project. This file will be used to configure the rules that should be followed in our typescript files. A detailed explanation of the contents can be found at https://palantir.github.io/tslint/usage/tslint-json.

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 (j) to it. This will prevent the transpiling of the typescript code when our solution is built.

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "outDir": "wwwroot/js",
    "lib": [ "es2017", "dom" ]
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}
(h) The tsconfig.json is used to configure the options for the typescript compiler.

tslint.json

{
  "extends": "tslint:latest",
  "rules": {
    "no-constructor-vars": true,
    "no-string-literal": false
  },
  "rulesDirectory": [
  ]
}
(i) The tslint.json file configures the rules to be used for the formatting of our typescript files.

WebUi.csproj

<PropertyGroup>
    <TypeScriptCompileBlocked>True</TypeScriptCompileBlocked>
</PropertyGroup>
(j) Property group that needs to be added to our WebUi.csproj file if you are using Visual Studio to prevent the transpiling of our typescript files when the project is built.

Odds and Ends

  • WebUi
    • Pages
      • _Layout.cshtml
      • Index.cshtml
    • Source
      • app
        • vendor.ts

In our project we have plenty of third-party code that we do not want to include in each javascript bundle so we will create a separate file that we can call when we setup webpack to create a separate bundle. Start by creating a folder named 'app' under the Source folder and inside it create a file named 'vendor.ts' (k).

And we will reduce our _Layout.cshtml file to the code in block (l) and we will delete the contents of the Index.cshtml, In the next article we will setup webpack to process all of our scss and typescript files.

vendor.ts

import "core-js/es6";
import "core-js/es7/reflect";
import "zone.js/dist/zone";

if (process.env.ENV !== "production") {
    Error["stackTraceLimit"] = Infinity;
    require("zone.js/dist/long-stack-trace-zone");
}

import "@angular/platform-browser";
import "@angular/platform-browser-dynamic";
import "@angular/core";
import "@angular/common";
import "@angular/http";
import "@angular/router";
import "@angular/forms";

import "classlist-polyfill";
import "lodash";
import "rxjs";
import "web-animations-js";
(k) File used to create a bundle for all of our third-party javascript code.

_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebUi</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>
</head>
<body>
    <div class="container body-content">
    @RenderBody()
    <hr />
        <footer>
            <p>© 2017 - WebUi</p>
        </footer>
    </div>
    <environment include="Development">
        <script src="~/js/vendor.bundle.js"></script>
        <script src="~/js/main.bundle.js"></script>
    </environment>
    <environment exclude="Development">
        <script src="~/js/vendor.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>
(l) The content of our _Layout.cshtml file after we have removed all the information that was added by the starting template that we do not need.
Exciton Interactive LLC
Advertisement