├── AngularBasic ├── ClientApp │ ├── test │ │ ├── .gitignore │ │ ├── karma.conf.js │ │ └── boot-tests.ts │ ├── .gitignore │ ├── app │ │ ├── app.template.html │ │ ├── home │ │ │ ├── home.style.scss │ │ │ ├── home.template.html │ │ │ ├── home.component.ts │ │ │ └── home.component.spec.ts │ │ ├── test │ │ │ ├── test.template.html │ │ │ ├── test.component.ts │ │ │ └── test.module.ts │ │ ├── app.component.ts │ │ ├── errors │ │ │ └── not-found.component.ts │ │ ├── app.service.ts │ │ └── app.module.ts │ ├── styles │ │ ├── main.scss │ │ └── _theme.scss │ ├── polyfills.ts │ └── main.ts ├── typings │ ├── index.d.ts │ └── globals.d.ts ├── Views │ ├── _ViewStart.cshtml │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ └── _Layout.cshtml │ └── _ViewImports.cshtml ├── .vscode │ ├── extensions.json │ ├── settings.json │ ├── launch.json │ └── tasks.json ├── .gitignore ├── appsettings.json ├── Controllers │ ├── HomeController.cs │ └── ValuesController.cs ├── Web.config ├── webpack.config.test.ts ├── Properties │ └── launchSettings.json ├── Program.cs ├── wwwroot │ └── loading.css ├── tslint.json ├── webpack.config.ts ├── tsconfig.json ├── AngularBasic.csproj ├── webpack.config.vendor.ts ├── Startup.cs ├── package.json ├── gulpfile.js └── webpack.config.common.ts ├── .gitignore ├── LICENSE ├── appveyor.yml ├── AngularBasic.sln ├── README.md └── .gitattributes /AngularBasic/ClientApp/test/.gitignore: -------------------------------------------------------------------------------- 1 | !karma.conf.js -------------------------------------------------------------------------------- /AngularBasic/ClientApp/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.js 2 | **/*.js.map -------------------------------------------------------------------------------- /AngularBasic/typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/app.template.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/home/home.style.scss: -------------------------------------------------------------------------------- 1 | h1{ 2 | color:green; 3 | } -------------------------------------------------------------------------------- /AngularBasic/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | \.vs 2 | node_modules 3 | *.tgz 4 | generators 5 | *.log 6 | *.csproj.user -------------------------------------------------------------------------------- /AngularBasic/ClientApp/styles/main.scss: -------------------------------------------------------------------------------- 1 | // Global styles 2 | 3 | @import '_theme.scss'; -------------------------------------------------------------------------------- /AngularBasic/typings/globals.d.ts: -------------------------------------------------------------------------------- 1 | // Globals 2 | 3 | declare module "pace-progress"; 4 | -------------------------------------------------------------------------------- /AngularBasic/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 |

Loading...

-------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/test/test.template.html: -------------------------------------------------------------------------------- 1 |

{{test}}

2 | 3 | Home Page -------------------------------------------------------------------------------- /AngularBasic/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Angular.ng-template", 4 | "ms-vscode.csharp" 5 | ] 6 | } -------------------------------------------------------------------------------- /AngularBasic/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

Error.

2 |

An error occurred while processing your request.

3 | -------------------------------------------------------------------------------- /AngularBasic/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bin 3 | obj 4 | wwwroot/dist 5 | webpack.config.js 6 | webpack.config.js.map 7 | webpack.config.vendor.js 8 | webpack.config.vendor.js.map -------------------------------------------------------------------------------- /AngularBasic/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using AngularBasic 2 | @addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers" 3 | @addTagHelper "*, Microsoft.AspNetCore.SpaServices" 4 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app", 5 | templateUrl: "./app.template.html", 6 | }) 7 | export class AppComponent { } 8 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/errors/not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from "@angular/core"; 2 | 3 | @Component({ 4 | template: "

Page not found

", 5 | }) 6 | export class PageNotFoundComponent { } 7 | -------------------------------------------------------------------------------- /AngularBasic/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/test/test.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from "@angular/core"; 2 | 3 | @Component({ 4 | templateUrl: "./test.template.html", 5 | }) 6 | export class TestComponent { 7 | public test: string = "Test Page"; 8 | } 9 | -------------------------------------------------------------------------------- /AngularBasic/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/*.js": {"when": "$(basename).ts"}, 4 | "**/*.js.map": true, 5 | "node_modules": true, 6 | "obj": true, 7 | "bin": true 8 | }, 9 | "typescript.tsdk": "node_modules\\typescript\\lib" 10 | } 11 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/app.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from "@angular/common/http"; 2 | import { Injectable } from "@angular/core"; 3 | 4 | @Injectable() 5 | export class AppService { 6 | constructor(private httpClient: HttpClient) { } 7 | public async getValues() { 8 | return this.httpClient.get("/api/values").toPromise(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/polyfills.ts: -------------------------------------------------------------------------------- 1 | import "core-js/es6/array"; 2 | import "core-js/es6/object"; 3 | import "core-js/es6/string"; 4 | 5 | import "core-js/es7/reflect"; 6 | import "zone.js/dist/zone"; 7 | 8 | declare var module: any; 9 | 10 | if (module.hot) { 11 | Error.stackTraceLimit = Infinity; 12 | 13 | // tslint:disable-next-line 14 | require("zone.js/dist/long-stack-trace-zone"); 15 | } 16 | -------------------------------------------------------------------------------- /AngularBasic/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace AngularBasic.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public IActionResult Index() 12 | { 13 | return View(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/test/test.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from "@angular/core"; 2 | import { RouterModule } from "@angular/router"; 3 | 4 | import { TestComponent } from "./test.component"; 5 | 6 | @NgModule({ 7 | imports: [ 8 | RouterModule.forChild([ 9 | { path: "", component: TestComponent }, 10 | ]), 11 | ], 12 | declarations: [ 13 | TestComponent, 14 | ], 15 | }) 16 | export class TestModule { } 17 | -------------------------------------------------------------------------------- /AngularBasic/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/styles/_theme.scss: -------------------------------------------------------------------------------- 1 | @import '~@angular/material/theming'; 2 | @import '~@covalent/core/theming/all-theme'; 3 | 4 | @include mat-core(); 5 | @include covalent-core(); 6 | 7 | $primary: mat-palette($mat-blue, 800); 8 | $accent: mat-palette($mat-light-blue, 600, A100, A400); 9 | 10 | $warn: mat-palette($mat-red, 600); 11 | 12 | $theme: mat-light-theme($primary, $accent, $warn); 13 | 14 | @include angular-material-theme($theme); 15 | @include covalent-theme($theme); 16 | -------------------------------------------------------------------------------- /AngularBasic/webpack.config.test.ts: -------------------------------------------------------------------------------- 1 | import { Configuration } from "webpack"; 2 | import * as webpackMerge from "webpack-merge"; 3 | 4 | import { WebpackCommonConfig } from "./webpack.config.common"; 5 | 6 | module.exports = (env: any) => { 7 | const bundleConfig: Configuration = webpackMerge(WebpackCommonConfig(env, "main"), { 8 | entry: { 9 | tests: [ 10 | "./ClientApp/test/boot-tests.ts", 11 | ], 12 | }, 13 | }); 14 | 15 | return bundleConfig; 16 | }; 17 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/test/karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function (config) { 2 | config.set({ 3 | basePath: '.', 4 | frameworks: ['jasmine'], 5 | files: [ 6 | '../../wwwroot/dist/tests.js' 7 | ], 8 | reporters: ['progress'], 9 | port: 9876, 10 | colors: true, 11 | logLevel: config.LOG_INFO, 12 | autoWatch: true, 13 | browsers: ['Chrome'], 14 | mime: { 'application/javascript': ['ts','tsx'] }, 15 | singleRun: true, 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /AngularBasic/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:51114/", 7 | "sslPort": 44314 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "AngularBasic": { 19 | "commandName": "Project" 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /AngularBasic/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | 9 | namespace AngularBasic 10 | { 11 | public class Program 12 | { 13 | public static void Main(string[] args) 14 | { 15 | CreateWebHostBuilder(args).Build().Run(); 16 | } 17 | 18 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 19 | WebHost.CreateDefaultBuilder(args) 20 | .UseStartup(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/home/home.template.html: -------------------------------------------------------------------------------- 1 |

{{appName}}

2 | Test Page 3 |
4 |
5 | 6 | 7 | 8 | 9 | 10 |

Count:

11 |

{{count}}

12 |

Values:

13 |
{{values | json}}
-------------------------------------------------------------------------------- /AngularBasic/wwwroot/loading.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | background-color: #f5f5f5 !important; 3 | font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; 4 | } 5 | 6 | .loading { 7 | font-size: 40px; 8 | text-align: center; 9 | } 10 | 11 | .loading span { 12 | font-size: 50px; 13 | animation-name: blink; 14 | animation-duration: 1.4s; 15 | animation-iteration-count: infinite; 16 | animation-fill-mode: both; 17 | } 18 | 19 | .loading span:nth-child(2) { 20 | animation-delay: .2s; 21 | } 22 | 23 | .loading span:nth-child(3) { 24 | animation-delay: .4s; 25 | } 26 | 27 | @keyframes blink { 28 | 0% { 29 | opacity: .2; 30 | } 31 | 32 | 20% { 33 | opacity: 1; 34 | } 35 | 36 | 100% { 37 | opacity: .2; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /AngularBasic/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tslint", 3 | "extends": "tslint:recommended", 4 | "rules": { 5 | "object-literal-sort-keys": false, 6 | "no-console": [ 7 | false 8 | ], 9 | "max-line-length": [ 10 | true, 11 | 250 12 | ], 13 | "arrow-parens": false, 14 | "radix": false, 15 | "no-angle-bracket-type-assertion": false, 16 | "indent": [ 17 | false 18 | ], 19 | "whitespace": [ 20 | false 21 | ], 22 | "no-unused-expression": [ 23 | true, 24 | "allow-new" 25 | ], 26 | "max-classes-per-file": [ 27 | false 28 | ], 29 | "no-shadowed-variable": false, 30 | "comment-format": [ 31 | false 32 | ], 33 | "no-namespace": false, 34 | "no-internal-module": false 35 | } 36 | } -------------------------------------------------------------------------------- /AngularBasic/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | AngularBasic 7 | 8 | 9 | 10 | 11 | @RenderBody() 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { TdDialogService } from "@covalent/core"; 3 | import { AppService } from "../app.service"; 4 | 5 | @Component({ 6 | templateUrl: "./home.template.html", 7 | styleUrls: ["./home.style.scss"], 8 | }) 9 | export class HomeComponent implements OnInit { 10 | public appName: string = "My App"; 11 | public count: number = 0; 12 | public values: string[] = []; 13 | constructor(private dialogService: TdDialogService, private appService: AppService) { } 14 | public async ngOnInit() { 15 | await this.updateValues(); 16 | } 17 | public counter(amount: number) { 18 | this.count += amount; 19 | } 20 | public openDialog() { 21 | const message = `Hello from ${this.appName}`; 22 | this.dialogService.openAlert({ message }); 23 | } 24 | public async updateValues() { 25 | this.values = ["Loading"]; 26 | this.values = await this.appService.getValues(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /AngularBasic/webpack.config.ts: -------------------------------------------------------------------------------- 1 | import * as path from "path"; 2 | import { Configuration, DllReferencePlugin } from "webpack"; 3 | import * as webpackMerge from "webpack-merge"; 4 | 5 | import { isAOT, isProd, outputDir, WebpackCommonConfig } from "./webpack.config.common"; 6 | 7 | module.exports = (env: any) => { 8 | const prod = isProd(env); 9 | const aot = isAOT(env); 10 | if (!prod && aot) { console.warn("Vendor dll bundle will not be used as AOT is enabled"); } 11 | const bundleConfig: Configuration = webpackMerge(WebpackCommonConfig(env, "main"), { 12 | entry: { 13 | app: "./ClientApp/main.ts", 14 | }, 15 | devtool: prod ? undefined : "eval-source-map", 16 | plugins: prod || aot ? [] : [ 17 | // AOT chunk splitting does not work while this is active https://github.com/angular/angular-cli/issues/4565 18 | new DllReferencePlugin({ 19 | context: __dirname, 20 | manifest: require(path.join(__dirname, outputDir, "vendor-manifest.json")), 21 | }), 22 | ], 23 | }); 24 | 25 | return bundleConfig; 26 | }; 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Matt Jeanes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /AngularBasic/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace AngularBasic.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | public class ValuesController : Controller 11 | { 12 | // GET api/values 13 | [HttpGet] 14 | public IEnumerable Get() 15 | { 16 | return new string[] { "value1", "value2" }; 17 | } 18 | 19 | // GET api/values/5 20 | [HttpGet("{id}")] 21 | public string Get(int id) 22 | { 23 | return "value"; 24 | } 25 | 26 | // POST api/values 27 | [HttpPost] 28 | public void Post([FromBody]string value) 29 | { 30 | } 31 | 32 | // PUT api/values/5 33 | [HttpPut("{id}")] 34 | public void Put(int id, [FromBody]string value) 35 | { 36 | } 37 | 38 | // DELETE api/values/5 39 | [HttpDelete("{id}")] 40 | public void Delete(int id) 41 | { 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /AngularBasic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "es2017", 6 | "dom" 7 | ], 8 | "moduleResolution": "node", 9 | "sourceMap": true, 10 | "strictNullChecks": true, 11 | "noUnusedLocals": true, 12 | "noImplicitThis": true, 13 | "noImplicitReturns": true, 14 | "noImplicitAny": true, 15 | "suppressImplicitAnyIndexErrors": true, 16 | "alwaysStrict": true, 17 | "emitDecoratorMetadata": true, 18 | "experimentalDecorators": true, 19 | "skipLibCheck": true, 20 | "noEmit": true, 21 | "plugins": [ 22 | { 23 | "name": "tslint-language-service", 24 | "alwaysShowRuleFailuresAsWarnings": false, 25 | "ignoreDefinitionFiles": true, 26 | "disableNoUnusedVariableRule": true 27 | } 28 | ] 29 | }, 30 | "include": [ 31 | "ClientApp/**/*", 32 | "typings/**/*", 33 | "webpack.config.*" 34 | ], 35 | "angularCompilerOptions": { 36 | "preserveWhitespaces": false, 37 | "genDir": "./ClientApp/app/ngfactory", 38 | "entryModule": "ClientApp/app/app.module#AppModule" 39 | }, 40 | "compileOnSave": false 41 | } 42 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/main.ts: -------------------------------------------------------------------------------- 1 | // Main 2 | 3 | import * as Pace from "pace-progress"; 4 | 5 | Pace.start(); 6 | 7 | import "./styles/main.scss"; 8 | 9 | import "./polyfills"; 10 | 11 | import "hammerjs"; 12 | 13 | import { enableProdMode } from "@angular/core"; 14 | import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; 15 | import { AppModule } from "./app/app.module"; 16 | 17 | declare var module: any; 18 | 19 | if (module.hot) { 20 | module.hot.accept(); 21 | module.hot.dispose(() => { 22 | // Before restarting the app, we create a new root element and dispose the old one 23 | const oldRootElem = document.querySelector("app"); 24 | const newRootElem = document.createElement("app"); 25 | if (oldRootElem && oldRootElem.parentNode) { 26 | oldRootElem.parentNode.insertBefore(newRootElem, oldRootElem); 27 | oldRootElem.parentNode.removeChild(oldRootElem); 28 | } 29 | if (modulePromise) { 30 | modulePromise.then(appModule => appModule.destroy()); 31 | } 32 | }); 33 | } else { 34 | enableProdMode(); 35 | } 36 | 37 | const modulePromise = platformBrowserDynamic().bootstrapModule(AppModule); 38 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/home/home.component.spec.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { async, ComponentFixture, TestBed } from "@angular/core/testing"; 4 | import { MatButtonModule } from "@angular/material"; 5 | import { HomeComponent } from "./home.component"; 6 | 7 | let fixture: ComponentFixture; 8 | 9 | describe("Counter component", () => { 10 | beforeEach(() => { 11 | TestBed.configureTestingModule({ imports: [MatButtonModule], declarations: [HomeComponent] }); 12 | fixture = TestBed.createComponent(HomeComponent); 13 | fixture.detectChanges(); 14 | }); 15 | 16 | it("should display a title", async(() => { 17 | const titleText = fixture.nativeElement.querySelector("h1").textContent; 18 | expect(titleText).toEqual("My App"); 19 | })); 20 | 21 | it("should start with count 0, then increments by 1 when clicked", async(() => { 22 | const countElement = fixture.nativeElement.querySelector("h3"); 23 | expect(countElement.textContent).toEqual("0"); 24 | 25 | const incrementButton = fixture.nativeElement.querySelector("button"); 26 | incrementButton.click(); 27 | fixture.detectChanges(); 28 | expect(countElement.textContent).toEqual("1"); 29 | })); 30 | }); 31 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/test/boot-tests.ts: -------------------------------------------------------------------------------- 1 | // Load required polyfills and testing libraries 2 | 3 | import "reflect-metadata"; 4 | 5 | import "zone.js"; 6 | 7 | import "zone.js/dist/long-stack-trace-zone"; 8 | 9 | import "zone.js/dist/async-test"; 10 | 11 | import "zone.js/dist/fake-async-test"; 12 | 13 | import "zone.js/dist/sync-test"; 14 | 15 | import "zone.js/dist/proxy"; 16 | 17 | import "zone.js/dist/jasmine-patch"; 18 | 19 | import * as testing from "@angular/core/testing"; 20 | import * as testingBrowser from "@angular/platform-browser-dynamic/testing"; 21 | 22 | // There's no typing for the `__karma__` variable. Just declare it as any 23 | declare var __karma__: any; 24 | declare var require: any; 25 | 26 | // Prevent Karma from running prematurely 27 | // tslint:disable-next-line:no-empty 28 | __karma__.loaded = () => {}; 29 | 30 | // First, initialize the Angular testing environment 31 | testing.getTestBed().initTestEnvironment( 32 | testingBrowser.BrowserDynamicTestingModule, 33 | testingBrowser.platformBrowserDynamicTesting(), 34 | ); 35 | 36 | // Then we find all the tests 37 | const context = require.context("../", true, /\.spec\.ts$/); 38 | 39 | // And load the modules 40 | context.keys().map(context); 41 | 42 | // Finally, start Karma to run the tests 43 | __karma__.start(); 44 | -------------------------------------------------------------------------------- /AngularBasic/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": ".NET Core Launch", 6 | "type": "coreclr", 7 | "request": "launch", 8 | "preLaunchTask": "build", 9 | "program": "${workspaceRoot}/bin/Debug/netcoreapp2.1/AngularBasic.dll", 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "stopAtEntry": false, 13 | "launchBrowser": { 14 | "enabled": true, 15 | "args": "${auto-detect-url}", 16 | "windows": { 17 | "command": "cmd.exe", 18 | "args": "/C start ${auto-detect-url}" 19 | }, 20 | "osx": { 21 | "command": "open" 22 | }, 23 | "linux": { 24 | "command": "xdg-open" 25 | } 26 | }, 27 | "env": { 28 | "ASPNETCORE_ENVIRONMENT": "Development" 29 | }, 30 | "sourceFileMap": { 31 | "/Views": "${workspaceRoot}/Views" 32 | } 33 | }, 34 | { 35 | "name": ".NET Core Attach", 36 | "type": "coreclr", 37 | "request": "attach", 38 | "processId": "${command:pickProcess}" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /AngularBasic/AngularBasic.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netcoreapp2.1 4 | false 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | %(DistFiles.Identity) 31 | PreserveNewest 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | pull_requests: 3 | do_not_increment_build_number: true 4 | branches: 5 | except: 6 | - /.*yeoman.*/ 7 | skip_branch_with_pr: true 8 | image: Visual Studio 2017 9 | environment: 10 | OCTOPUS_API_KEY: 11 | secure: NdYQQ5h892q9r/GVUs/6eum4RKtWiH9b0TgFv51ksX8= 12 | OCTOPUS_SERVER: 13 | secure: UHnMTTS3+01ToVMjEW9+jxJuf400Of7LwIezsgw1Ks0= 14 | OCTOPUS_PROJECT_NAME: AngularBasic 15 | OCTOPUS_DEPLOY_TO: Production 16 | install: 17 | - ps: choco install octopustools 18 | cache: '%LOCALAPPDATA%\Yarn' 19 | build_script: 20 | - ps: >- 21 | Set-Location "AngularBasic" 22 | 23 | dotnet restore AngularBasic.csproj 24 | 25 | yarn 26 | 27 | dotnet publish AngularBasic.csproj --configuration "Release" --output "publish" 28 | test: off 29 | artifacts: 30 | - path: AngularBasic/publish 31 | name: AngularBasic 32 | deploy_script: 33 | - ps: >- 34 | if ($env:APPVEYOR_REPO_BRANCH -eq "master") { 35 | $Version = (Get-Content -Raw -Path package.json | ConvertFrom-Json).version + ".$env:APPVEYOR_BUILD_ID" 36 | Write-Output "Using version $Version" 37 | octo pack --id "AngularBasic" --version "$Version" --basePath "publish" 38 | nuget push "AngularBasic.$Version.nupkg" -ApiKey "$env:OCTOPUS_API_KEY" -Source "$env:OCTOPUS_SERVER/nuget/packages" 39 | octo create-release --packageversion $Version --version $Version --project "$env:OCTOPUS_PROJECT_NAME" --progress --deployto "$env:OCTOPUS_DEPLOY_TO" --server "$env:OCTOPUS_SERVER" --apiKey "$env:OCTOPUS_API_KEY" 40 | } 41 | -------------------------------------------------------------------------------- /AngularBasic.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.7 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4371F927-BFB3-4B91-98B0-B6657AEB20D0}" 7 | ProjectSection(SolutionItems) = preProject 8 | .gitattributes = .gitattributes 9 | .gitignore = .gitignore 10 | appveyor.yml = appveyor.yml 11 | LICENSE = LICENSE 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AngularBasic", "AngularBasic\AngularBasic.csproj", "{C18A0BB8-6D17-43B9-B22D-EB647F95269E}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Release|Any CPU = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {C18A0BB8-6D17-43B9-B22D-EB647F95269E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {C18A0BB8-6D17-43B9-B22D-EB647F95269E}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {C18A0BB8-6D17-43B9-B22D-EB647F95269E}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {C18A0BB8-6D17-43B9-B22D-EB647F95269E}.Release|Any CPU.Build.0 = Release|Any CPU 27 | EndGlobalSection 28 | GlobalSection(SolutionProperties) = preSolution 29 | HideSolutionNode = FALSE 30 | EndGlobalSection 31 | GlobalSection(ExtensibilityGlobals) = postSolution 32 | SolutionGuid = {F9C74C48-299F-41A4-B3AF-62C68C9A2376} 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /AngularBasic/ClientApp/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { HttpClientModule } from "@angular/common/http"; 2 | import { NgModule } from "@angular/core"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { BrowserModule } from "@angular/platform-browser"; 5 | import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; 6 | import { RouterModule, Routes } from "@angular/router"; 7 | 8 | import { AppComponent } from "./app.component"; 9 | import { AppService } from "./app.service"; 10 | import { PageNotFoundComponent } from "./errors/not-found.component"; 11 | import { HomeComponent } from "./home/home.component"; 12 | 13 | import { MatButtonModule, MatSliderModule } from "@angular/material"; 14 | 15 | import { ButtonModule } from "primeng/primeng"; 16 | 17 | import { CovalentDialogsModule } from "@covalent/core"; 18 | 19 | export const ROUTES: Routes = [ 20 | { path: "", component: HomeComponent }, 21 | { path: "test", loadChildren: "./test/test.module#TestModule" }, 22 | { path: "**", component: PageNotFoundComponent }, 23 | ]; 24 | 25 | @NgModule({ 26 | imports: [ 27 | RouterModule.forRoot(ROUTES), 28 | BrowserModule, 29 | BrowserAnimationsModule, 30 | FormsModule, 31 | HttpClientModule, 32 | ButtonModule, 33 | MatButtonModule, 34 | MatSliderModule, 35 | CovalentDialogsModule, 36 | ], 37 | declarations: [ 38 | AppComponent, 39 | HomeComponent, 40 | PageNotFoundComponent, 41 | ], 42 | bootstrap: [AppComponent], 43 | providers: [ 44 | AppService, 45 | ], 46 | }) 47 | export class AppModule { } 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED: Newer versions of Angular are much easier to setup and maintain, use Angular CLI instead of this 2 | 3 | # AngularBasic 4 | Basic Angular TypeScript app for VS2017/VSCode, uses aspnet core, webpack, gulp, sass and yarn (optional) 5 | 6 | [![Build status](https://ci.appveyor.com/api/projects/status/f8pheooffn5a9vrb/branch/master?svg=true)](https://ci.appveyor.com/project/MattJeanes/angularbasic/branch/master) 7 | 8 | ##       *Now available as a [project template](https://marketplace.visualstudio.com/items?itemName=GregTrevellick.AngularBasicVsix) within Visual Studio.* 9 | 10 | ## Demo site 11 | http://angularbasic.mattjeanes.com/ 12 | 13 | ## Why did you switch from SystemJS to webpack? 14 | I feel that webpack has reached a point where it's ease of use and power have overcome my old SystemJS-based setup. 15 | 16 | That said, it still has it's uses, particularly anywhere webpack-dev-middleware cannot be used, such as in older asp.net 4 applications. 17 | 18 | If you wish to use the old SystemJS-based version, it's available on npm under 1.x or on the systemjs branches on this repository. 19 | ## Installation 20 | You can download the master branch and use directly or (recommended) use the yeoman generator for this 21 | - `npm install -g yo generator-angular-basic` 22 | - `yo angular-basic` 23 | 24 | This will ask a few questions such as project name and scaffold out your application ready for use 25 | 26 | # 27 | [![BrowserStack](https://user-images.githubusercontent.com/2363642/32060856-eac21ffa-ba67-11e7-94ad-0bf1ebe10e87.png)](https://www.browserstack.com) 28 | 29 | Special thanks to BrowserStack for allowing me to use their platform to test this project 30 | -------------------------------------------------------------------------------- /AngularBasic/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "restore", 8 | "command": "npm", 9 | "type": "shell", 10 | "args": [ 11 | "run-script", 12 | "restore" 13 | ], 14 | "problemMatcher": [] 15 | }, 16 | { 17 | "label": "clean", 18 | "command": "dotnet", 19 | "type": "shell", 20 | "args": [ 21 | "clean" 22 | ], 23 | "problemMatcher": "$msCompile" 24 | }, 25 | { 26 | "label": "build", 27 | "command": "dotnet", 28 | "type": "shell", 29 | "args": [ 30 | "build" 31 | ], 32 | "group": { 33 | "isDefault": true, 34 | "kind": "build" 35 | }, 36 | "problemMatcher": "$msCompile" 37 | }, 38 | { 39 | "label": "lint", 40 | "type": "shell", 41 | "command": "npm", 42 | "args": [ 43 | "run", 44 | "lint", 45 | "--", 46 | "--format", 47 | "msbuild" 48 | ], 49 | "problemMatcher": "$msCompile" 50 | }, 51 | { 52 | "label": "lint_fix", 53 | "type": "shell", 54 | "command": "npm", 55 | "args": [ 56 | "run", 57 | "lint", 58 | "--", 59 | "--fix", 60 | "--format", 61 | "msbuild" 62 | ], 63 | "problemMatcher": "$msCompile" 64 | }, 65 | { 66 | "label": "test", 67 | "command": "npm", 68 | "type": "shell", 69 | "args": [ 70 | "run-script", 71 | "test" 72 | ], 73 | "problemMatcher": "$tsc" 74 | } 75 | ] 76 | } -------------------------------------------------------------------------------- /AngularBasic/webpack.config.vendor.ts: -------------------------------------------------------------------------------- 1 | import * as path from "path"; 2 | import * as webpack from "webpack"; 3 | import * as webpackMerge from "webpack-merge"; 4 | import { isProd, outputDir, WebpackCommonConfig } from "./webpack.config.common"; 5 | 6 | module.exports = (env: any) => { 7 | const prod = isProd(env); 8 | const bundleConfig = webpackMerge(WebpackCommonConfig(env, "vendor"), { 9 | output: { 10 | library: "[name]_[hash]", 11 | }, 12 | entry: { 13 | vendor: [ // add any vendor styles here e.g. bootstrap/dist/css/bootstrap.min.css 14 | "pace-progress/themes/black/pace-theme-center-simple.css", 15 | "primeng/resources/primeng.min.css", 16 | "primeng/resources/themes/cruze/theme.css", 17 | "primeicons/primeicons.css", 18 | ].concat(prod ? [] : [ // used to speed up dev launch time 19 | "@angular/animations", 20 | "@angular/common", 21 | "@angular/common/http", 22 | "@angular/compiler", 23 | "@angular/core", 24 | "@angular/forms", 25 | "@angular/http", 26 | "@angular/platform-browser", 27 | "@angular/platform-browser/animations", 28 | "@angular/platform-browser-dynamic", 29 | "@angular/router", 30 | "@angular/material", 31 | "@angular/cdk", 32 | "@covalent/core", 33 | "pace-progress", 34 | "jquery", 35 | "zone.js", 36 | "primeng/primeng", 37 | "reflect-metadata", 38 | "core-js", 39 | "rxjs", 40 | "css-loader/lib/css-base", 41 | "core-js/es6/string", 42 | "core-js/es6/array", 43 | "core-js/es6/object", 44 | "core-js/es7/reflect", 45 | "hammerjs", 46 | ]), 47 | }, 48 | plugins: prod ? [] : [ 49 | new webpack.DllPlugin({ 50 | path: path.join(__dirname, outputDir, "[name]-manifest.json"), 51 | name: "[name]_[hash]", 52 | }), 53 | ], 54 | }); 55 | return bundleConfig; 56 | }; 57 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /AngularBasic/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.Http; 8 | using Microsoft.AspNetCore.SpaServices.Webpack; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace AngularBasic 14 | { 15 | public class Startup 16 | { 17 | public Startup(IHostingEnvironment env) 18 | { 19 | var builder = new ConfigurationBuilder() 20 | .SetBasePath(env.ContentRootPath) 21 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 22 | .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 23 | .AddEnvironmentVariables(); 24 | Configuration = builder.Build(); 25 | } 26 | 27 | public IConfigurationRoot Configuration { get; } 28 | 29 | public void ConfigureServices(IServiceCollection services) 30 | { 31 | services.AddMvc(); 32 | services.AddHttpsRedirection(options => 33 | { 34 | options.RedirectStatusCode = StatusCodes.Status301MovedPermanently; 35 | }); 36 | } 37 | 38 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 39 | { 40 | loggerFactory.AddConsole(Configuration.GetSection("Logging")); 41 | loggerFactory.AddDebug(); 42 | 43 | app.UseHttpsRedirection(); 44 | 45 | if (env.IsDevelopment()) 46 | { 47 | app.UseDeveloperExceptionPage(); 48 | app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions 49 | { 50 | HotModuleReplacement = true, 51 | ConfigFile = "webpack.config.ts", 52 | EnvParam = new 53 | { 54 | aot = false // can't use AOT with HMR currently https://github.com/angular/angular-cli/issues/6347 55 | } 56 | }); 57 | } 58 | else 59 | { 60 | app.UseExceptionHandler("/Home/Error"); 61 | //app.UseHsts(); 62 | } 63 | 64 | app.UseStaticFiles(); 65 | 66 | app.UseMvc(routes => 67 | { 68 | routes.MapRoute( 69 | name: "default", 70 | template: "{controller=Home}/{action=Index}/{id?}"); 71 | 72 | routes.MapSpaFallbackRoute( 73 | name: "spa-fallback", 74 | defaults: new { controller = "Home", action = "Index" }); 75 | }); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /AngularBasic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angularbasic", 3 | "version": "6.0.0", 4 | "private": true, 5 | "scripts": { 6 | "vendor": "gulp vendor", 7 | "test": "gulp test", 8 | "lint": "tslint -p .", 9 | "publish": "gulp publish", 10 | "restore": "dotnet restore && yarn install", 11 | "clean": "gulp clean" 12 | }, 13 | "dependencies": { 14 | "@angular/animations": "^6.1.0", 15 | "@angular/cdk": "^6.4.1", 16 | "@angular/common": "^6.1.0", 17 | "@angular/compiler": "^6.1.0", 18 | "@angular/compiler-cli": "^6.1.0", 19 | "@angular/core": "^6.1.0", 20 | "@angular/forms": "^6.1.0", 21 | "@angular/http": "^6.1.0", 22 | "@angular/material": "^6.4.1", 23 | "@angular/platform-browser": "^6.1.0", 24 | "@angular/platform-browser-dynamic": "^6.1.0", 25 | "@angular/platform-server": "^6.1.0", 26 | "@angular/router": "^6.1.0", 27 | "@covalent/core": "^2.0.0-beta.2", 28 | "@ngtools/webpack": "^6.1.1", 29 | "@types/core-js": "^2.5.0", 30 | "@types/mini-css-extract-plugin": "^0.2.0", 31 | "@types/node": "^10.5.4", 32 | "@types/webpack": "^4.4.8", 33 | "@types/webpack-bundle-analyzer": "^2.9.2", 34 | "@types/webpack-merge": "^4.1.3", 35 | "angular-router-loader": "^0.8.5", 36 | "angular2-template-loader": "^0.6.2", 37 | "aspnet-webpack": "^3.0.0", 38 | "awesome-typescript-loader": "^5.2.0", 39 | "copy-webpack-plugin": "^4.5.2", 40 | "core-js": "^2.5.7", 41 | "css": "^2.2.3", 42 | "css-loader": "^1.0.0", 43 | "del": "^3.0.0", 44 | "event-source-polyfill": "^0.0.12", 45 | "expose-loader": "^0.7.5", 46 | "file-loader": "^1.1.11", 47 | "gulp": "^3.9.1", 48 | "gulp-run": "^1.7.1", 49 | "hammerjs": "^2.0.8", 50 | "html-loader": "^0.5.5", 51 | "jquery": "^3.3.1", 52 | "mini-css-extract-plugin": "^0.4.1", 53 | "node-sass": "^4.9.2", 54 | "pace-progress": "^1.0.2", 55 | "primeicons": "^1.0.0-beta.10", 56 | "primeng": "^6.0.2", 57 | "raw-loader": "^0.5.1", 58 | "reflect-metadata": "^0.1.12", 59 | "run-sequence": "^2.2.1", 60 | "rxjs": "^6.2.2", 61 | "sass-loader": "^7.0.3", 62 | "style-loader": "^0.21.0", 63 | "to-string-loader": "^1.1.5", 64 | "ts-node": "^7.0.0", 65 | "tslint": "^5.11.0", 66 | "tslint-language-service": "^0.9.9", 67 | "typescript": "^2.9.2", 68 | "uglify-es": "^3.3.9", 69 | "uglifyjs-webpack-plugin": "^1.2.7", 70 | "url-loader": "^1.0.1", 71 | "webpack": "^4.16.3", 72 | "webpack-bundle-analyzer": "^2.13.1", 73 | "webpack-cli": "^3.1.0", 74 | "webpack-dev-middleware": "^3.1.3", 75 | "webpack-hot-middleware": "^2.22.3", 76 | "webpack-merge": "^4.1.3", 77 | "zone.js": "^0.8.26" 78 | }, 79 | "devDependencies": { 80 | "@types/chai": "^4.1.4", 81 | "@types/jasmine": "^2.8.8", 82 | "chai": "^4.1.2", 83 | "jasmine-core": "^3.1.0", 84 | "karma": "^2.0.5", 85 | "karma-chai": "^0.1.0", 86 | "karma-chrome-launcher": "^2.2.0", 87 | "karma-cli": "^1.0.1", 88 | "karma-jasmine": "^1.1.2", 89 | "karma-webpack": "^3.0.0" 90 | }, 91 | "resolutions": { 92 | "@types/tapable": "1.0.0", 93 | "@types/webpack": "^4.4.8" 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /AngularBasic/gulpfile.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const gulp = require("gulp"); 4 | const run = require("gulp-run"); 5 | const runSequence = require("run-sequence"); 6 | const del = require("del"); 7 | const path = require("path"); 8 | const fs = require("fs"); 9 | require("ts-node/register"); 10 | 11 | const outputDir = "./wwwroot/dist"; 12 | global.aot = true; 13 | 14 | function getEnvOptions() { 15 | var env = []; 16 | if (global.prod) { 17 | env.push("prod"); 18 | } 19 | if (global.analyse) { 20 | env.push("analyse"); 21 | } 22 | if (global.aot) { 23 | env.push("aot"); 24 | } 25 | return env; 26 | } 27 | 28 | function getOptions() { 29 | var envOptions = getEnvOptions(); 30 | const options = []; 31 | for (const option of envOptions) { 32 | options.push(`--env.${option}`); 33 | } 34 | if (options.length > 0) { 35 | return " " + options.join(" "); 36 | } else { 37 | return ""; 38 | } 39 | } 40 | 41 | function webpack(type) { 42 | return run(`webpack --config webpack.config${type ? `.${type}` : ""}.ts${getOptions()}`).exec(); 43 | } 44 | 45 | gulp.task("vendor", () => { 46 | let build = false; 47 | const vendorPath = path.join(outputDir, "vendor.js"); 48 | const vendorExists = fs.existsSync(vendorPath); 49 | if (vendorExists) { 50 | const vendorStat = fs.statSync(vendorPath); 51 | const packageStat = fs.statSync("package.json"); 52 | const vendorConfigStat = fs.statSync("webpack.config.vendor.ts"); 53 | const commonConfigStat = fs.statSync("webpack.config.common.ts"); 54 | if (packageStat.mtime > vendorStat.mtime) { 55 | build = true; 56 | } 57 | if (vendorConfigStat.mtime > vendorStat.mtime) { 58 | build = true; 59 | } 60 | if (commonConfigStat.mtime > vendorStat.mtime) { 61 | build = true; 62 | } 63 | } else { 64 | build = true; 65 | } 66 | if (build) { 67 | var envOptions = getEnvOptions(); 68 | var env = {}; 69 | for (const option of envOptions) { 70 | env[option] = true; 71 | } 72 | var config = require("./webpack.config.vendor.ts")(env); 73 | if (config.entry.vendor.length) { // webpack will crash if given an empty entry list 74 | return webpack("vendor"); 75 | } 76 | } 77 | }); 78 | 79 | gulp.task("vendor_force", () => { 80 | return webpack("vendor"); 81 | }) 82 | 83 | gulp.task("main", () => { 84 | return webpack() 85 | }); 86 | 87 | gulp.task("prod_var", () => { 88 | global.prod = true; 89 | }) 90 | 91 | gulp.task("analyse_var", () => { 92 | global.analyse = true; 93 | }) 94 | 95 | gulp.task("clean", () => { 96 | del.sync(outputDir, { force: true }); 97 | }); 98 | 99 | gulp.task("test_compile", function () { 100 | return webpack("test"); 101 | }); 102 | 103 | gulp.task("test_run", function () { 104 | return run("karma start ClientApp/test/karma.conf.js").exec(); 105 | }); 106 | 107 | gulp.task("test", callback => runSequence("test_compile", "test_run", callback)); 108 | gulp.task("lint", () => run("npm run lint").exec()); 109 | gulp.task("lint_fix", () => run("npm run lint -- --fix").exec()); 110 | gulp.task("build", callback => runSequence("vendor", "main", callback)); 111 | gulp.task("analyse", callback => runSequence("analyse_var", "clean", "build", callback)); 112 | gulp.task("full", callback => runSequence("clean", "build", callback)); 113 | gulp.task("publish", callback => runSequence("prod_var", "full", callback)); -------------------------------------------------------------------------------- /AngularBasic/webpack.config.common.ts: -------------------------------------------------------------------------------- 1 | import { AngularCompilerPlugin } from "@ngtools/webpack"; 2 | import * as MiniCssExtractPlugin from "mini-css-extract-plugin"; 3 | import * as path from "path"; 4 | import { Configuration, ContextReplacementPlugin, ProvidePlugin } from "webpack"; 5 | import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer"; 6 | 7 | export const outputDir = "./wwwroot/dist"; 8 | 9 | export function isProd(env: any) { 10 | return env && env.prod as boolean; 11 | } 12 | 13 | export function isAOT(env: any) { 14 | return env && env.aot as boolean; 15 | } 16 | 17 | export const WebpackCommonConfig = (env: any, type: string) => { 18 | const prod = isProd(env); 19 | const aot = isAOT(env); 20 | const vendor = type === "vendor"; 21 | console.log(`${prod ? "Production" : "Dev"} ${type} build`); 22 | console.log(`Output directory: ${outputDir}`); 23 | console.log(`${aot ? "Using" : "Not using"} AOT compiler`); 24 | const analyse = env && env.analyse as boolean; 25 | if (analyse) { console.log("Analysing build"); } 26 | const cssLoader = prod ? "css-loader?minimize" : "css-loader"; 27 | const bundleConfig: Configuration = { 28 | mode: prod ? "production" : "development", 29 | resolve: { 30 | extensions: [".ts", ".js"], 31 | alias: { 32 | pace: "pace-progress", 33 | }, 34 | }, 35 | output: { 36 | path: path.resolve(outputDir), 37 | filename: "[name].js", 38 | chunkFilename: "[id].chunk.js", 39 | publicPath: "/dist/", 40 | }, 41 | module: { 42 | rules: [ 43 | { test: /\.ts$/, loader: aot ? "@ngtools/webpack" : ["awesome-typescript-loader?silent=true", "angular2-template-loader", "angular-router-loader"] }, 44 | { test: /\.html$/, use: "html-loader?minimize=false" }, 45 | { test: /\.css$/, use: [MiniCssExtractPlugin.loader, cssLoader] }, 46 | { test: /\.scss$/, include: /ClientApp(\\|\/)app/, use: ["to-string-loader", cssLoader, "sass-loader"] }, 47 | { test: /\.scss$/, include: /ClientApp(\\|\/)styles/, use: ["style-loader", cssLoader, "sass-loader"] }, 48 | { test: /\.(png|jpg|jpeg|gif|woff|woff2|eot|ttf|svg)(\?|$)/, use: "url-loader?limit=8192" }, 49 | { test: /[\/\\]@angular[\/\\].+\.js$/, parser: { system: true } }, // ignore System.import warnings https://github.com/angular/angular/issues/21560 50 | ], 51 | }, 52 | plugins: [ 53 | new MiniCssExtractPlugin({ 54 | filename: "[name].css", 55 | }), 56 | new ProvidePlugin({ $: "jquery", jQuery: "jquery", Hammer: "hammerjs/hammer" }), // Global identifiers 57 | ].concat(aot && !vendor ? [ 58 | new AngularCompilerPlugin({ 59 | mainPath: "./ClientApp/main.ts", 60 | tsConfigPath: "./tsconfig.json", 61 | skipCodeGeneration: false, 62 | compilerOptions: { 63 | noEmit: false, 64 | }, 65 | }), 66 | ] : [ 67 | // AOT chunk splitting does not work while this is active but doesn't seem to be needed under AOT anyway https://github.com/angular/angular-cli/issues/4431 68 | new ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)/, path.join(__dirname, "./ClientApp")), // Workaround for https://github.com/angular/angular/issues/14898 69 | ]).concat(analyse ? [ 70 | new BundleAnalyzerPlugin({ 71 | analyzerMode: "static", 72 | reportFilename: `${type}.html`, 73 | openAnalyzer: false, 74 | }), 75 | ] : []), 76 | node: { 77 | fs: "empty", 78 | }, 79 | }; 80 | 81 | return bundleConfig; 82 | }; 83 | --------------------------------------------------------------------------------