mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-24 18:47:30 +00:00
Fix templates directory structure to produce correct nupkg output
This commit is contained in:
237
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/angular/.gitignore
vendored
Normal file
237
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/angular/.gitignore
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
/Properties/launchSettings.json
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
bin/
|
||||
Bin/
|
||||
obj/
|
||||
Obj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
/wwwroot/dist/
|
||||
/ClientApp/dist/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
/node_modules
|
||||
|
||||
/yarn.lock
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/dotnetcli.host",
|
||||
"symbolInfo": {
|
||||
"TargetFrameworkOverride": {
|
||||
"isHidden": "true",
|
||||
"longName": "target-framework-override",
|
||||
"shortName": ""
|
||||
},
|
||||
"Framework": {
|
||||
"longName": "framework"
|
||||
},
|
||||
"skipRestore": {
|
||||
"longName": "no-restore",
|
||||
"shortName": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"author": "Microsoft",
|
||||
"classifications": [
|
||||
"Web",
|
||||
"MVC",
|
||||
"SPA"
|
||||
],
|
||||
"groupIdentity": "Microsoft.DotNet.Web.Spa.ProjectTemplates.Angular",
|
||||
"identity": "Microsoft.DotNet.Web.Spa.ProjectTemplates.Angular.CSharp",
|
||||
"name": "ASP.NET Core with Angular",
|
||||
"preferNameDirectory": true,
|
||||
"primaryOutputs": [
|
||||
{
|
||||
"path": "AngularSpa.csproj"
|
||||
}
|
||||
],
|
||||
"shortName": "angular",
|
||||
"sourceName": "AngularSpa",
|
||||
"sources": [
|
||||
{
|
||||
"source": "./",
|
||||
"target": "./",
|
||||
"exclude": [
|
||||
".template.config/**"
|
||||
]
|
||||
}
|
||||
],
|
||||
"symbols": {
|
||||
"TargetFrameworkOverride": {
|
||||
"type": "parameter",
|
||||
"description": "Overrides the target framework",
|
||||
"replaces": "TargetFrameworkOverride",
|
||||
"datatype": "string",
|
||||
"defaultValue": ""
|
||||
},
|
||||
"Framework": {
|
||||
"type": "parameter",
|
||||
"description": "The target framework for the project.",
|
||||
"datatype": "choice",
|
||||
"choices": [
|
||||
{
|
||||
"choice": "netcoreapp2.0",
|
||||
"description": "Target netcoreapp2.0"
|
||||
}
|
||||
],
|
||||
"replaces": "netcoreapp2.0",
|
||||
"defaultValue": "netcoreapp2.0"
|
||||
},
|
||||
"HostIdentifier": {
|
||||
"type": "bind",
|
||||
"binding": "HostIdentifier"
|
||||
},
|
||||
"skipRestore": {
|
||||
"type": "parameter",
|
||||
"datatype": "bool",
|
||||
"description": "If specified, skips the automatic restore of the project on create.",
|
||||
"defaultValue": "false"
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"language": "C#",
|
||||
"type": "project"
|
||||
},
|
||||
"postActions": [
|
||||
{
|
||||
"condition": "(!skipRestore)",
|
||||
"description": "Restore NuGet packages required by this project.",
|
||||
"manualInstructions": [
|
||||
{
|
||||
"text": "Run 'dotnet restore'"
|
||||
}
|
||||
],
|
||||
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
|
||||
"continueOnError": true
|
||||
},
|
||||
{
|
||||
"condition": "(HostIdentifier == \"dotnetcli\" || HostIdentifier == \"dotnetcli-preview\")",
|
||||
"actionId": "AC1156F7-BB77-4DB8-B28F-24EEBCCA1E5C",
|
||||
"description": "\n\n-------------------------------------------------------------------\nIMPORTANT: Before running this project on the command line,\n you must restore NPM packages by running \"npm install\"\n-------------------------------------------------------------------\n",
|
||||
"manualInstructions": [
|
||||
{
|
||||
"text": "Run \"npm install\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/vs-2017.3.host",
|
||||
"name": {
|
||||
"text": "Angular",
|
||||
"package": "{0CD94836-1526-4E85-87D3-FB5274C5AFC9}",
|
||||
"id": "1100"
|
||||
},
|
||||
"description": {
|
||||
"text": "A project template for creating an ASP.NET Core application with Angular",
|
||||
"package": "{0CD94836-1526-4E85-87D3-FB5274C5AFC9}",
|
||||
"id": "1101"
|
||||
},
|
||||
"order": 301,
|
||||
"icon": "icon.png",
|
||||
"learnMoreLink": "https://github.com/aspnet/JavaScriptServices",
|
||||
"uiFilters": [
|
||||
"oneaspnet"
|
||||
],
|
||||
"minFullFrameworkVersion": "4.6.1"
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework Condition="'$(TargetFrameworkOverride)' == ''">netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework Condition="'$(TargetFrameworkOverride)' != ''">TargetFrameworkOverride</TargetFramework>
|
||||
<TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
|
||||
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' == ''">
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFrameworkOverride)' != ''">
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Files not to publish (note that the 'dist' subfolders are re-added below) -->
|
||||
<Content Remove="ClientApp\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--/-:cnd:noEmit -->
|
||||
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
|
||||
<!-- Ensure Node.js is installed -->
|
||||
<Exec Command="node --version" ContinueOnError="true">
|
||||
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
|
||||
</Exec>
|
||||
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
|
||||
|
||||
<!-- In development, the dist files won't exist on the first run or when cloning to
|
||||
a different machine, so rebuild them if not already present. -->
|
||||
<Message Importance="high" Text="Performing first-run Webpack build..." />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js" />
|
||||
</Target>
|
||||
<!--/+:cnd:noEmit -->
|
||||
|
||||
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
|
||||
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
|
||||
<Exec Command="npm install" />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
|
||||
<Exec Command="node node_modules/webpack/bin/webpack.js --env.prod" />
|
||||
|
||||
<!-- Include the newly-built files in the publish output -->
|
||||
<ItemGroup>
|
||||
<DistFiles Include="wwwroot\dist\**; ClientApp\dist\**" />
|
||||
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
|
||||
<RelativePath>%(DistFiles.Identity)</RelativePath>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</ResolvedFileToPublish>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { AppModuleShared } from './app.module.shared';
|
||||
import { AppComponent } from './components/app/app.component';
|
||||
|
||||
@NgModule({
|
||||
bootstrap: [ AppComponent ],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppModuleShared
|
||||
],
|
||||
providers: [
|
||||
{ provide: 'BASE_URL', useFactory: getBaseUrl }
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export function getBaseUrl() {
|
||||
return document.getElementsByTagName('base')[0].href;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ServerModule } from '@angular/platform-server';
|
||||
import { AppModuleShared } from './app.module.shared';
|
||||
import { AppComponent } from './components/app/app.component';
|
||||
|
||||
@NgModule({
|
||||
bootstrap: [ AppComponent ],
|
||||
imports: [
|
||||
ServerModule,
|
||||
AppModuleShared
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpModule } from '@angular/http';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppComponent } from './components/app/app.component';
|
||||
import { NavMenuComponent } from './components/navmenu/navmenu.component';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
|
||||
import { CounterComponent } from './components/counter/counter.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
NavMenuComponent,
|
||||
CounterComponent,
|
||||
FetchDataComponent,
|
||||
HomeComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpModule,
|
||||
FormsModule,
|
||||
RouterModule.forRoot([
|
||||
{ path: '', redirectTo: 'home', pathMatch: 'full' },
|
||||
{ path: 'home', component: HomeComponent },
|
||||
{ path: 'counter', component: CounterComponent },
|
||||
{ path: 'fetch-data', component: FetchDataComponent },
|
||||
{ path: '**', redirectTo: 'home' }
|
||||
])
|
||||
]
|
||||
})
|
||||
export class AppModuleShared {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@media (max-width: 767px) {
|
||||
/* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */
|
||||
.body-content {
|
||||
padding-top: 50px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class='container-fluid'>
|
||||
<div class='row'>
|
||||
<div class='col-sm-3'>
|
||||
<nav-menu></nav-menu>
|
||||
</div>
|
||||
<div class='col-sm-9 body-content'>
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p>This is a simple example of an Angular component.</p>
|
||||
|
||||
<p>Current count: <strong>{{ currentCount }}</strong></p>
|
||||
|
||||
<button (click)="incrementCounter()">Increment</button>
|
||||
@@ -0,0 +1,29 @@
|
||||
/// <reference path="../../../../node_modules/@types/jasmine/index.d.ts" />
|
||||
import { assert } from 'chai';
|
||||
import { CounterComponent } from './counter.component';
|
||||
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
|
||||
|
||||
let fixture: ComponentFixture<CounterComponent>;
|
||||
|
||||
describe('Counter component', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({ declarations: [CounterComponent] });
|
||||
fixture = TestBed.createComponent(CounterComponent);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display a title', async(() => {
|
||||
const titleText = fixture.nativeElement.querySelector('h1').textContent;
|
||||
expect(titleText).toEqual('Counter');
|
||||
}));
|
||||
|
||||
it('should start with count 0, then increments by 1 when clicked', async(() => {
|
||||
const countElement = fixture.nativeElement.querySelector('strong');
|
||||
expect(countElement.textContent).toEqual('0');
|
||||
|
||||
const incrementButton = fixture.nativeElement.querySelector('button');
|
||||
incrementButton.click();
|
||||
fixture.detectChanges();
|
||||
expect(countElement.textContent).toEqual('1');
|
||||
}));
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'counter',
|
||||
templateUrl: './counter.component.html'
|
||||
})
|
||||
export class CounterComponent {
|
||||
public currentCount = 0;
|
||||
|
||||
public incrementCounter() {
|
||||
this.currentCount++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<h1>Weather forecast</h1>
|
||||
|
||||
<p>This component demonstrates fetching data from the server.</p>
|
||||
|
||||
<p *ngIf="!forecasts"><em>Loading...</em></p>
|
||||
|
||||
<table class='table' *ngIf="forecasts">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let forecast of forecasts">
|
||||
<td>{{ forecast.dateFormatted }}</td>
|
||||
<td>{{ forecast.temperatureC }}</td>
|
||||
<td>{{ forecast.temperatureF }}</td>
|
||||
<td>{{ forecast.summary }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
|
||||
@Component({
|
||||
selector: 'fetchdata',
|
||||
templateUrl: './fetchdata.component.html'
|
||||
})
|
||||
export class FetchDataComponent {
|
||||
public forecasts: WeatherForecast[];
|
||||
|
||||
constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
|
||||
http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
|
||||
this.forecasts = result.json() as WeatherForecast[];
|
||||
}, error => console.error(error));
|
||||
}
|
||||
}
|
||||
|
||||
interface WeatherForecast {
|
||||
dateFormatted: string;
|
||||
temperatureC: number;
|
||||
temperatureF: number;
|
||||
summary: string;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<h1>Hello, world!</h1>
|
||||
<p>Welcome to your new single-page application, built with:</p>
|
||||
<ul>
|
||||
<li><a href='https://get.asp.net/'>ASP.NET Core</a> and <a href='https://msdn.microsoft.com/en-us/library/67ef8sbd.aspx'>C#</a> for cross-platform server-side code</li>
|
||||
<li><a href='https://angular.io/'>Angular</a> and <a href='http://www.typescriptlang.org/'>TypeScript</a> for client-side code</li>
|
||||
<li><a href='https://webpack.github.io/'>Webpack</a> for building and bundling client-side resources</li>
|
||||
<li><a href='http://getbootstrap.com/'>Bootstrap</a> for layout and styling</li>
|
||||
</ul>
|
||||
<p>To help you get started, we've also set up:</p>
|
||||
<ul>
|
||||
<li><strong>Client-side navigation</strong>. For example, click <em>Counter</em> then <em>Back</em> to return here.</li>
|
||||
<li><strong>Server-side prerendering</strong>. For faster initial loading and improved SEO, your Angular app is prerendered on the server. The resulting HTML is then transferred to the browser where a client-side copy of the app takes over.</li>
|
||||
<li><strong>Webpack dev middleware</strong>. In development mode, there's no need to run the <code>webpack</code> build tool. Your client-side resources are dynamically built on demand. Updates are available as soon as you modify any file.</li>
|
||||
<li><strong>Hot module replacement</strong>. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, your Angular app will be rebuilt and a new instance injected into the page.</li>
|
||||
<li><strong>Efficient production builds</strong>. In production mode, development-time features are disabled, and the <code>webpack</code> build tool produces minified static CSS and JavaScript files.</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'home',
|
||||
templateUrl: './home.component.html'
|
||||
})
|
||||
export class HomeComponent {
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
li .glyphicon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* Highlighting rules for nav menu items */
|
||||
li.link-active a,
|
||||
li.link-active a:hover,
|
||||
li.link-active a:focus {
|
||||
background-color: #4189C7;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Keep the nav menu independent of scrolling and on top of other items */
|
||||
.main-nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
/* On small screens, convert the nav menu to a vertical sidebar */
|
||||
.main-nav {
|
||||
height: 100%;
|
||||
width: calc(25% - 20px);
|
||||
}
|
||||
.navbar {
|
||||
border-radius: 0px;
|
||||
border-width: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
.navbar-header {
|
||||
float: none;
|
||||
}
|
||||
.navbar-collapse {
|
||||
border-top: 1px solid #444;
|
||||
padding: 0px;
|
||||
}
|
||||
.navbar ul {
|
||||
float: none;
|
||||
}
|
||||
.navbar li {
|
||||
float: none;
|
||||
font-size: 15px;
|
||||
margin: 6px;
|
||||
}
|
||||
.navbar li a {
|
||||
padding: 10px 16px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navbar a {
|
||||
/* If a menu item's text is too long, truncate it */
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<div class='main-nav'>
|
||||
<div class='navbar navbar-inverse'>
|
||||
<div class='navbar-header'>
|
||||
<button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>
|
||||
<span class='sr-only'>Toggle navigation</span>
|
||||
<span class='icon-bar'></span>
|
||||
<span class='icon-bar'></span>
|
||||
<span class='icon-bar'></span>
|
||||
</button>
|
||||
<a class='navbar-brand' [routerLink]="['/home']">AngularSpa</a>
|
||||
</div>
|
||||
<div class='clearfix'></div>
|
||||
<div class='navbar-collapse collapse'>
|
||||
<ul class='nav navbar-nav'>
|
||||
<li [routerLinkActive]="['link-active']">
|
||||
<a [routerLink]="['/home']">
|
||||
<span class='glyphicon glyphicon-home'></span> Home
|
||||
</a>
|
||||
</li>
|
||||
<li [routerLinkActive]="['link-active']">
|
||||
<a [routerLink]="['/counter']">
|
||||
<span class='glyphicon glyphicon-education'></span> Counter
|
||||
</a>
|
||||
</li>
|
||||
<li [routerLinkActive]="['link-active']">
|
||||
<a [routerLink]="['/fetch-data']">
|
||||
<span class='glyphicon glyphicon-th-list'></span> Fetch data
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'nav-menu',
|
||||
templateUrl: './navmenu.component.html',
|
||||
styleUrls: ['./navmenu.component.css']
|
||||
})
|
||||
export class NavMenuComponent {
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'reflect-metadata';
|
||||
import 'zone.js';
|
||||
import 'bootstrap';
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { AppModule } from './app/app.module.browser';
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept();
|
||||
module.hot.dispose(() => {
|
||||
// Before restarting the app, we create a new root element and dispose the old one
|
||||
const oldRootElem = document.querySelector('app');
|
||||
const newRootElem = document.createElement('app');
|
||||
oldRootElem!.parentNode!.insertBefore(newRootElem, oldRootElem);
|
||||
modulePromise.then(appModule => appModule.destroy());
|
||||
});
|
||||
} else {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
// Note: @ng-tools/webpack looks for the following expression when performing production
|
||||
// builds. Don't change how this line looks, otherwise you may break tree-shaking.
|
||||
const modulePromise = platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
@@ -0,0 +1,38 @@
|
||||
import 'reflect-metadata';
|
||||
import 'zone.js';
|
||||
import 'rxjs/add/operator/first';
|
||||
import { APP_BASE_HREF } from '@angular/common';
|
||||
import { enableProdMode, ApplicationRef, NgZone, ValueProvider } from '@angular/core';
|
||||
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
|
||||
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
|
||||
import { AppModule } from './app/app.module.server';
|
||||
|
||||
enableProdMode();
|
||||
|
||||
export default createServerRenderer(params => {
|
||||
const providers = [
|
||||
{ provide: INITIAL_CONFIG, useValue: { document: '<app></app>', url: params.url } },
|
||||
{ provide: APP_BASE_HREF, useValue: params.baseUrl },
|
||||
{ provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
|
||||
];
|
||||
|
||||
return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
|
||||
const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
|
||||
const state = moduleRef.injector.get(PlatformState);
|
||||
const zone = moduleRef.injector.get(NgZone);
|
||||
|
||||
return new Promise<RenderResult>((resolve, reject) => {
|
||||
zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
|
||||
appRef.isStable.first(isStable => isStable).subscribe(() => {
|
||||
// Because 'onStable' fires before 'onError', we have to delay slightly before
|
||||
// completing the request in case there's an error to report
|
||||
setImmediate(() => {
|
||||
resolve({
|
||||
html: state.renderToString()
|
||||
});
|
||||
moduleRef.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
// Load required polyfills and testing libraries
|
||||
import 'reflect-metadata';
|
||||
import 'zone.js';
|
||||
import 'zone.js/dist/long-stack-trace-zone';
|
||||
import 'zone.js/dist/proxy.js';
|
||||
import 'zone.js/dist/sync-test';
|
||||
import 'zone.js/dist/jasmine-patch';
|
||||
import 'zone.js/dist/async-test';
|
||||
import 'zone.js/dist/fake-async-test';
|
||||
import * as testing from '@angular/core/testing';
|
||||
import * as testingBrowser from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// There's no typing for the `__karma__` variable. Just declare it as any
|
||||
declare var __karma__: any;
|
||||
declare var require: any;
|
||||
|
||||
// Prevent Karma from running prematurely
|
||||
__karma__.loaded = function () {};
|
||||
|
||||
// First, initialize the Angular testing environment
|
||||
testing.getTestBed().initTestEnvironment(
|
||||
testingBrowser.BrowserDynamicTestingModule,
|
||||
testingBrowser.platformBrowserDynamicTesting()
|
||||
);
|
||||
|
||||
// Then we find all the tests
|
||||
const context = require.context('../', true, /\.spec\.ts$/);
|
||||
|
||||
// And load the modules
|
||||
context.keys().map(context);
|
||||
|
||||
// Finally, start Karma to run the tests
|
||||
__karma__.start();
|
||||
@@ -0,0 +1,26 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/0.13/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '.',
|
||||
frameworks: ['jasmine'],
|
||||
files: [
|
||||
'../../wwwroot/dist/vendor.js',
|
||||
'./boot-tests.ts'
|
||||
],
|
||||
preprocessors: {
|
||||
'./boot-tests.ts': ['webpack']
|
||||
},
|
||||
reporters: ['progress'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
mime: { 'application/javascript': ['ts','tsx'] },
|
||||
singleRun: false,
|
||||
webpack: require('../../webpack.config.js')().filter(config => config.target !== 'node'), // Test against client bundle, because tests run in a browser
|
||||
webpackMiddleware: { stats: 'errors-only' }
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AngularSpa.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Error()
|
||||
{
|
||||
ViewData["RequestId"] = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AngularSpa.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
public class SampleDataController : Controller
|
||||
{
|
||||
private static string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
[HttpGet("[action]")]
|
||||
public IEnumerable<WeatherForecast> WeatherForecasts()
|
||||
{
|
||||
var rng = new Random();
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
DateFormatted = DateTime.Now.AddDays(index).ToString("d"),
|
||||
TemperatureC = rng.Next(-20, 55),
|
||||
Summary = Summaries[rng.Next(Summaries.Length)]
|
||||
});
|
||||
}
|
||||
|
||||
public class WeatherForecast
|
||||
{
|
||||
public string DateFormatted { get; set; }
|
||||
public int TemperatureC { get; set; }
|
||||
public string Summary { get; set; }
|
||||
|
||||
public int TemperatureF
|
||||
{
|
||||
get
|
||||
{
|
||||
return 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace AngularSpa
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
BuildWebHost(args).Run();
|
||||
}
|
||||
|
||||
public static IWebHost BuildWebHost(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.SpaServices.Webpack;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AngularSpa
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
|
||||
{
|
||||
HotModuleReplacement = true
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
routes.MapSpaFallbackRoute(
|
||||
name: "spa-fallback",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>
|
||||
|
||||
<script src="~/dist/vendor.js" asp-append-version="true"></script>
|
||||
@section scripts {
|
||||
<script src="~/dist/main-client.js" asp-append-version="true"></script>
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (!string.IsNullOrEmpty((string)ViewData["RequestId"]))
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@ViewData["RequestId"]</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
||||
</p>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - AngularSpa</title>
|
||||
<base href="~/" />
|
||||
|
||||
<link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true" />
|
||||
</head>
|
||||
<body>
|
||||
@RenderBody()
|
||||
|
||||
@RenderSection("scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
@using AngularSpa
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper *, Microsoft.AspNetCore.SpaServices
|
||||
@@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3730
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/angular/npm-shrinkwrap.json
generated
Normal file
3730
templates/Microsoft.DotNet.Web.Spa.ProjectTemplates/angular/npm-shrinkwrap.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "AngularSpa",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"test": "karma start ClientApp/test/karma.conf.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "4.2.5",
|
||||
"@angular/common": "4.2.5",
|
||||
"@angular/compiler": "4.2.5",
|
||||
"@angular/compiler-cli": "4.2.5",
|
||||
"@angular/core": "4.2.5",
|
||||
"@angular/forms": "4.2.5",
|
||||
"@angular/http": "4.2.5",
|
||||
"@angular/platform-browser": "4.2.5",
|
||||
"@angular/platform-browser-dynamic": "4.2.5",
|
||||
"@angular/platform-server": "4.2.5",
|
||||
"@angular/router": "4.2.5",
|
||||
"@ngtools/webpack": "1.5.0",
|
||||
"@types/webpack-env": "1.13.0",
|
||||
"angular2-router-loader": "0.3.5",
|
||||
"angular2-template-loader": "0.6.2",
|
||||
"aspnet-prerendering": "^3.0.1",
|
||||
"aspnet-webpack": "^2.0.1",
|
||||
"awesome-typescript-loader": "3.2.1",
|
||||
"bootstrap": "3.3.7",
|
||||
"css": "2.2.1",
|
||||
"css-loader": "0.28.4",
|
||||
"es6-shim": "0.35.3",
|
||||
"event-source-polyfill": "0.0.9",
|
||||
"expose-loader": "0.7.3",
|
||||
"extract-text-webpack-plugin": "2.1.2",
|
||||
"file-loader": "0.11.2",
|
||||
"html-loader": "0.4.5",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"jquery": "3.2.1",
|
||||
"json-loader": "0.5.4",
|
||||
"preboot": "4.5.2",
|
||||
"raw-loader": "0.5.1",
|
||||
"reflect-metadata": "0.1.10",
|
||||
"rxjs": "5.4.2",
|
||||
"style-loader": "0.18.2",
|
||||
"to-string-loader": "1.1.5",
|
||||
"typescript": "2.4.1",
|
||||
"url-loader": "0.5.9",
|
||||
"webpack": "2.5.1",
|
||||
"webpack-hot-middleware": "2.18.2",
|
||||
"webpack-merge": "4.1.0",
|
||||
"zone.js": "0.8.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "4.0.1",
|
||||
"@types/jasmine": "2.5.53",
|
||||
"chai": "4.0.2",
|
||||
"jasmine-core": "2.6.4",
|
||||
"karma": "1.7.0",
|
||||
"karma-chai": "0.1.0",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-jasmine": "1.1.0",
|
||||
"karma-webpack": "2.0.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"target": "es5",
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"skipLibCheck": true, // Workaround for https://github.com/angular/angular/issues/17863. Remove this if you upgrade to a fixed version of Angular.
|
||||
"strict": true,
|
||||
"lib": [ "es6", "dom" ],
|
||||
"types": [ "webpack-env" ]
|
||||
},
|
||||
"exclude": [ "bin", "node_modules" ],
|
||||
"atom": { "rewriteTsconfig": false }
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const merge = require('webpack-merge');
|
||||
const AotPlugin = require('@ngtools/webpack').AotPlugin;
|
||||
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
|
||||
|
||||
module.exports = (env) => {
|
||||
// Configuration in common to both client-side and server-side bundles
|
||||
const isDevBuild = !(env && env.prod);
|
||||
const sharedConfig = {
|
||||
stats: { modules: false },
|
||||
context: __dirname,
|
||||
resolve: { extensions: [ '.js', '.ts' ] },
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.ts$/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader', 'angular2-router-loader'] : '@ngtools/webpack' },
|
||||
{ test: /\.html$/, use: 'html-loader?minimize=false' },
|
||||
{ test: /\.css$/, use: [ 'to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
|
||||
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
|
||||
]
|
||||
},
|
||||
plugins: [new CheckerPlugin()]
|
||||
};
|
||||
|
||||
// Configuration for client-side bundle suitable for running in browsers
|
||||
const clientBundleOutputDir = './wwwroot/dist';
|
||||
const clientBundleConfig = merge(sharedConfig, {
|
||||
entry: { 'main-client': './ClientApp/boot.browser.ts' },
|
||||
output: { path: path.join(__dirname, clientBundleOutputDir) },
|
||||
plugins: [
|
||||
new webpack.DllReferencePlugin({
|
||||
context: __dirname,
|
||||
manifest: require('./wwwroot/dist/vendor-manifest.json')
|
||||
})
|
||||
].concat(isDevBuild ? [
|
||||
// Plugins that apply in development builds only
|
||||
new webpack.SourceMapDevToolPlugin({
|
||||
filename: '[file].map', // Remove this line if you prefer inline source maps
|
||||
moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
|
||||
})
|
||||
] : [
|
||||
// Plugins that apply in production builds only
|
||||
new webpack.optimize.UglifyJsPlugin(),
|
||||
new AotPlugin({
|
||||
tsConfigPath: './tsconfig.json',
|
||||
entryModule: path.join(__dirname, 'ClientApp/app/app.module.browser#AppModule'),
|
||||
exclude: ['./**/*.server.ts']
|
||||
})
|
||||
])
|
||||
});
|
||||
|
||||
// Configuration for server-side (prerendering) bundle suitable for running in Node
|
||||
const serverBundleConfig = merge(sharedConfig, {
|
||||
resolve: { mainFields: ['main'] },
|
||||
entry: { 'main-server': './ClientApp/boot.server.ts' },
|
||||
plugins: [
|
||||
new webpack.DllReferencePlugin({
|
||||
context: __dirname,
|
||||
manifest: require('./ClientApp/dist/vendor-manifest.json'),
|
||||
sourceType: 'commonjs2',
|
||||
name: './vendor'
|
||||
})
|
||||
].concat(isDevBuild ? [] : [
|
||||
// Plugins that apply in production builds only
|
||||
new AotPlugin({
|
||||
tsConfigPath: './tsconfig.json',
|
||||
entryModule: path.join(__dirname, 'ClientApp/app/app.module.server#AppModule'),
|
||||
exclude: ['./**/*.browser.ts']
|
||||
})
|
||||
]),
|
||||
output: {
|
||||
libraryTarget: 'commonjs',
|
||||
path: path.join(__dirname, './ClientApp/dist')
|
||||
},
|
||||
target: 'node',
|
||||
devtool: 'inline-source-map'
|
||||
});
|
||||
|
||||
return [clientBundleConfig, serverBundleConfig];
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const merge = require('webpack-merge');
|
||||
const treeShakableModules = [
|
||||
'@angular/animations',
|
||||
'@angular/common',
|
||||
'@angular/compiler',
|
||||
'@angular/core',
|
||||
'@angular/forms',
|
||||
'@angular/http',
|
||||
'@angular/platform-browser',
|
||||
'@angular/platform-browser-dynamic',
|
||||
'@angular/router',
|
||||
'zone.js',
|
||||
];
|
||||
const nonTreeShakableModules = [
|
||||
'bootstrap',
|
||||
'bootstrap/dist/css/bootstrap.css',
|
||||
'es6-promise',
|
||||
'es6-shim',
|
||||
'event-source-polyfill',
|
||||
'jquery',
|
||||
];
|
||||
const allModules = treeShakableModules.concat(nonTreeShakableModules);
|
||||
|
||||
module.exports = (env) => {
|
||||
const extractCSS = new ExtractTextPlugin('vendor.css');
|
||||
const isDevBuild = !(env && env.prod);
|
||||
const sharedConfig = {
|
||||
stats: { modules: false },
|
||||
resolve: { extensions: [ '.js' ] },
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }
|
||||
]
|
||||
},
|
||||
output: {
|
||||
publicPath: 'dist/',
|
||||
filename: '[name].js',
|
||||
library: '[name]_[hash]'
|
||||
},
|
||||
plugins: [
|
||||
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
|
||||
new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/11580
|
||||
new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)@angular/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/14898
|
||||
new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
|
||||
]
|
||||
};
|
||||
|
||||
const clientBundleConfig = merge(sharedConfig, {
|
||||
entry: {
|
||||
// To keep development builds fast, include all vendor dependencies in the vendor bundle.
|
||||
// But for production builds, leave the tree-shakable ones out so the AOT compiler can produce a smaller bundle.
|
||||
vendor: isDevBuild ? allModules : nonTreeShakableModules
|
||||
},
|
||||
output: { path: path.join(__dirname, 'wwwroot', 'dist') },
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.css(\?|$)/, use: extractCSS.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) }
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
extractCSS,
|
||||
new webpack.DllPlugin({
|
||||
path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
|
||||
name: '[name]_[hash]'
|
||||
})
|
||||
].concat(isDevBuild ? [] : [
|
||||
new webpack.optimize.UglifyJsPlugin()
|
||||
])
|
||||
});
|
||||
|
||||
const serverBundleConfig = merge(sharedConfig, {
|
||||
target: 'node',
|
||||
resolve: { mainFields: ['main'] },
|
||||
entry: { vendor: allModules.concat(['aspnet-prerendering']) },
|
||||
output: {
|
||||
path: path.join(__dirname, 'ClientApp', 'dist'),
|
||||
libraryTarget: 'commonjs2',
|
||||
},
|
||||
module: {
|
||||
rules: [ { test: /\.css(\?|$)/, use: ['to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] } ]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DllPlugin({
|
||||
path: path.join(__dirname, 'ClientApp', 'dist', '[name]-manifest.json'),
|
||||
name: '[name]_[hash]'
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
return [clientBundleConfig, serverBundleConfig];
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Reference in New Issue
Block a user