From 64a8ef11120418f4b7641ff9664186b3d955ffb6 Mon Sep 17 00:00:00 2001 From: Mike Mazmanyan Date: Tue, 26 Jul 2016 17:44:07 +0400 Subject: [PATCH 01/19] Moving and updating "aspnet-webpack" package in templates (#207) --- templates/Angular2Spa/package.json | 2 +- templates/KnockoutSpa/package.json | 2 +- templates/ReactReduxSpa/package.json | 2 +- templates/ReactSpa/package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/Angular2Spa/package.json b/templates/Angular2Spa/package.json index 047a6ea..afb4200 100644 --- a/templates/Angular2Spa/package.json +++ b/templates/Angular2Spa/package.json @@ -2,6 +2,7 @@ "name": "WebApplicationBasic", "version": "0.0.0", "devDependencies": { + "aspnet-webpack": "^1.0.6", "bootstrap": "^3.3.6", "css-loader": "^0.23.1", "expose-loader": "^0.7.1", @@ -28,7 +29,6 @@ "@angular/router": "3.0.0-alpha.8", "angular2-universal": "^0.104.1", "aspnet-prerendering": "^1.0.2", - "aspnet-webpack": "^1.0.1", "css": "^2.2.1", "isomorphic-fetch": "^2.2.1", "preboot": "^2.0.10", diff --git a/templates/KnockoutSpa/package.json b/templates/KnockoutSpa/package.json index c00f895..9de9738 100644 --- a/templates/KnockoutSpa/package.json +++ b/templates/KnockoutSpa/package.json @@ -2,7 +2,7 @@ "name": "WebApplicationBasic", "version": "0.0.0", "devDependencies": { - "aspnet-webpack": "^1.0.0", + "aspnet-webpack": "^1.0.6", "bootstrap": "^3.3.6", "bundle-loader": "^0.5.4", "crossroads": "^0.12.2", diff --git a/templates/ReactReduxSpa/package.json b/templates/ReactReduxSpa/package.json index 4070c8a..a1d53df 100644 --- a/templates/ReactReduxSpa/package.json +++ b/templates/ReactReduxSpa/package.json @@ -2,6 +2,7 @@ "name": "WebApplicationBasic", "version": "0.0.0", "devDependencies": { + "aspnet-webpack": "^1.0.6", "aspnet-webpack-react": "^1.0.1", "babel-loader": "^6.2.3", "babel-preset-es2015": "^6.5.0", @@ -21,7 +22,6 @@ }, "dependencies": { "aspnet-prerendering": "^1.0.2", - "aspnet-webpack": "^1.0.2", "babel-core": "^6.5.2", "domain-task": "^2.0.0", "react": "^15.0.1", diff --git a/templates/ReactSpa/package.json b/templates/ReactSpa/package.json index 2b6d0b0..9776cdb 100644 --- a/templates/ReactSpa/package.json +++ b/templates/ReactSpa/package.json @@ -2,7 +2,7 @@ "name": "WebApplicationBasic", "version": "0.0.0", "devDependencies": { - "aspnet-webpack": "^1.0.2", + "aspnet-webpack": "^1.0.6", "aspnet-webpack-react": "^1.0.0", "babel-loader": "^6.2.3", "babel-preset-es2015": "^6.5.0", From 96228711f26cd356bdab816fadfa235383b43b5f Mon Sep 17 00:00:00 2001 From: Mark Pieszak Date: Thu, 21 Jul 2016 11:41:43 -0400 Subject: [PATCH 02/19] chore(package): Update to rc4, beta router & universal 104.5 104.5 includes some bug fixes. Router beta update required pathMatch on home. Tested w/ JS on/off everything passes & works. --- templates/Angular2Spa/ClientApp/routes.ts | 2 +- templates/Angular2Spa/package.json | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/templates/Angular2Spa/ClientApp/routes.ts b/templates/Angular2Spa/ClientApp/routes.ts index d693c44..c0a45b7 100644 --- a/templates/Angular2Spa/ClientApp/routes.ts +++ b/templates/Angular2Spa/ClientApp/routes.ts @@ -4,7 +4,7 @@ import { FetchData } from './components/fetch-data/fetch-data'; import { Counter } from './components/counter/counter'; export const routes: RouterConfig = [ - { path: '', redirectTo: 'home' }, + { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: Home }, { path: 'counter', component: Counter }, { path: 'fetch-data', component: FetchData }, diff --git a/templates/Angular2Spa/package.json b/templates/Angular2Spa/package.json index afb4200..5c09d17 100644 --- a/templates/Angular2Spa/package.json +++ b/templates/Angular2Spa/package.json @@ -19,15 +19,15 @@ "webpack-hot-middleware": "^2.10.0" }, "dependencies": { - "@angular/common": "2.0.0-rc.3", - "@angular/compiler": "2.0.0-rc.3", - "@angular/core": "2.0.0-rc.3", - "@angular/http": "2.0.0-rc.3", - "@angular/platform-browser": "2.0.0-rc.3", - "@angular/platform-browser-dynamic": "2.0.0-rc.3", - "@angular/platform-server": "2.0.0-rc.3", - "@angular/router": "3.0.0-alpha.8", - "angular2-universal": "^0.104.1", + "@angular/common": "2.0.0-rc.4", + "@angular/compiler": "2.0.0-rc.4", + "@angular/core": "2.0.0-rc.4", + "@angular/http": "2.0.0-rc.4", + "@angular/platform-browser": "2.0.0-rc.4", + "@angular/platform-browser-dynamic": "2.0.0-rc.4", + "@angular/platform-server": "2.0.0-rc.4", + "@angular/router": "3.0.0-beta.2", + "angular2-universal": "^0.104.5", "aspnet-prerendering": "^1.0.2", "css": "^2.2.1", "isomorphic-fetch": "^2.2.1", From 77b404188bdeebbf33676dc2322de07f6a793031 Mon Sep 17 00:00:00 2001 From: Simon Kamlet Date: Fri, 22 Jul 2016 11:04:51 +0200 Subject: [PATCH 03/19] fix angular's (click) events not being triggered on IE9 --- templates/Angular2Spa/ClientApp/boot-client.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/Angular2Spa/ClientApp/boot-client.ts b/templates/Angular2Spa/ClientApp/boot-client.ts index be3ca22..d19ff24 100644 --- a/templates/Angular2Spa/ClientApp/boot-client.ts +++ b/templates/Angular2Spa/ClientApp/boot-client.ts @@ -1,3 +1,4 @@ +import 'es6-shim'; require('zone.js'); import 'bootstrap'; import 'reflect-metadata'; From 2fe06ea784d9413a9fb54dd839d5a8c9db0d6421 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Tue, 26 Jul 2016 14:57:14 +0100 Subject: [PATCH 04/19] Make the dependency on es6-shim explicit, and include it in the vendor bundle --- templates/Angular2Spa/package.json | 1 + templates/Angular2Spa/webpack.config.vendor.js | 1 + 2 files changed, 2 insertions(+) diff --git a/templates/Angular2Spa/package.json b/templates/Angular2Spa/package.json index 5c09d17..3797004 100644 --- a/templates/Angular2Spa/package.json +++ b/templates/Angular2Spa/package.json @@ -30,6 +30,7 @@ "angular2-universal": "^0.104.5", "aspnet-prerendering": "^1.0.2", "css": "^2.2.1", + "es6-shim": "^0.35.1", "isomorphic-fetch": "^2.2.1", "preboot": "^2.0.10", "rxjs": "5.0.0-beta.6", diff --git a/templates/Angular2Spa/webpack.config.vendor.js b/templates/Angular2Spa/webpack.config.vendor.js index 0fc256a..cd2bbe0 100644 --- a/templates/Angular2Spa/webpack.config.vendor.js +++ b/templates/Angular2Spa/webpack.config.vendor.js @@ -18,6 +18,7 @@ module.exports = { vendor: [ 'bootstrap', 'bootstrap/dist/css/bootstrap.css', + 'es6-shim', 'style-loader', 'jquery', '@angular/common', From 79872c1bde1276861455ed72e216c469c4fd45a3 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Tue, 26 Jul 2016 16:38:46 +0100 Subject: [PATCH 05/19] Amend aspnet-webpack for better node-inspector support --- .../npm/aspnet-webpack/package.json | 2 +- .../npm/aspnet-webpack/src/LoadViaWebpack.ts | 13 ++++++++++++- .../src/typings/require-from-string.d.ts | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json index 6ff72aa..6e12ac7 100644 --- a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json +++ b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json @@ -1,6 +1,6 @@ { "name": "aspnet-webpack", - "version": "1.0.6", + "version": "1.0.7", "description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.", "main": "index.js", "scripts": { diff --git a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/LoadViaWebpack.ts b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/LoadViaWebpack.ts index a6f6fa7..c41d7e8 100644 --- a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/LoadViaWebpack.ts +++ b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/LoadViaWebpack.ts @@ -35,6 +35,12 @@ export function loadViaWebpack(webpackConfigPath: string, modulePath: string, }) } +function setExtension(filePath: string, newExtension: string) { + const oldExtensionIfAny = path.extname(filePath); + const basenameWithoutExtension = path.basename(filePath, oldExtensionIfAny); + return path.join(path.dirname(filePath), basenameWithoutExtension) + newExtension; +} + function loadViaWebpackNoCache(webpackConfigPath: string, modulePath: string) { return new Promise((resolve, reject) => { // Load the Webpack config and make alterations needed for loading the output into Node @@ -94,8 +100,13 @@ function loadViaWebpackNoCache(webpackConfigPath: string, modulePath: string) + stats.toString({ chunks: false })); } + // The dynamically-built module will only appear in node-inspector if it has some nonempty + // file path. The following value is arbitrary (since there's no real compiled file on disk) + // but is sufficient to enable debugging. + const fakeModulePath = setExtension(modulePath, '.js'); + const fileContent = compiler.outputFileSystem.readFileSync(outputVirtualPath, 'utf8'); - const moduleInstance = requireFromString(fileContent); + const moduleInstance = requireFromString(fileContent, fakeModulePath); resolve(moduleInstance); } catch(ex) { reject(ex); diff --git a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/typings/require-from-string.d.ts b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/typings/require-from-string.d.ts index 80e4645..ba41884 100644 --- a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/typings/require-from-string.d.ts +++ b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/typings/require-from-string.d.ts @@ -1,3 +1,3 @@ export namespace requirefromstring { - export function requireFromString(fileContent: string): T; + export function requireFromString(fileContent: string, filename?: string): T; } From f2f67fe880dc78e7aa07c89f2dff0c76c7993cb7 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Tue, 26 Jul 2016 18:33:27 +0100 Subject: [PATCH 06/19] Support new config options to launch the Node process with a debug listener. This is compatible with node-inspector. --- .../Configuration/Configuration.cs | 6 ++- .../Configuration/NodeServicesOptions.cs | 2 + .../HostingModels/HttpNodeInstance.cs | 9 ++-- .../HostingModels/OutOfProcessNodeInstance.cs | 48 ++++++++++++++++--- .../HostingModels/SocketNodeInstance.cs | 8 +++- 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.AspNetCore.NodeServices/Configuration/Configuration.cs b/src/Microsoft.AspNetCore.NodeServices/Configuration/Configuration.cs index bbae3d2..6ecd43f 100644 --- a/src/Microsoft.AspNetCore.NodeServices/Configuration/Configuration.cs +++ b/src/Microsoft.AspNetCore.NodeServices/Configuration/Configuration.cs @@ -68,10 +68,12 @@ namespace Microsoft.AspNetCore.NodeServices switch (options.HostingModel) { case NodeHostingModel.Http: - return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, logger, /* port */ 0); + return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, logger, + options.LaunchWithDebugging, options.DebuggingPort, /* port */ 0); case NodeHostingModel.Socket: var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string - return new SocketNodeInstance(options.ProjectPath, options.WatchFileExtensions, pipeName, logger); + return new SocketNodeInstance(options.ProjectPath, options.WatchFileExtensions, pipeName, logger, + options.LaunchWithDebugging, options.DebuggingPort); default: throw new ArgumentException("Unknown hosting model: " + options.HostingModel); } diff --git a/src/Microsoft.AspNetCore.NodeServices/Configuration/NodeServicesOptions.cs b/src/Microsoft.AspNetCore.NodeServices/Configuration/NodeServicesOptions.cs index 98c50ec..5e6f518 100644 --- a/src/Microsoft.AspNetCore.NodeServices/Configuration/NodeServicesOptions.cs +++ b/src/Microsoft.AspNetCore.NodeServices/Configuration/NodeServicesOptions.cs @@ -21,5 +21,7 @@ namespace Microsoft.AspNetCore.NodeServices public string ProjectPath { get; set; } public string[] WatchFileExtensions { get; set; } public ILogger NodeInstanceOutputLogger { get; set; } + public bool LaunchWithDebugging { get; set; } + public int? DebuggingPort { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs index 53dabf9..0e828ea 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs @@ -33,15 +33,18 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels private bool _disposed; private int _portNumber; - public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger, int port = 0) - : base( + public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger, + bool launchWithDebugging, int? debuggingPort, int port = 0) + : base( EmbeddedResourceReader.Read( typeof(HttpNodeInstance), "/Content/Node/entrypoint-http.js"), projectPath, watchFileExtensions, MakeCommandLineOptions(port), - nodeInstanceOutputLogger) + nodeInstanceOutputLogger, + launchWithDebugging, + debuggingPort) { _client = new HttpClient(); } diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs index 0664999..01a9055 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs @@ -21,11 +21,22 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels { protected readonly ILogger OutputLogger; private const string ConnectionEstablishedMessage = "[Microsoft.AspNetCore.NodeServices:Listening]"; + private const string DebuggingStartedMessageFormat = @"----- +*** Node.js debugging is enabled *** +{0} + +To debug, run: + node-inspector{1} + +If you haven't yet installed node-inspector, you can do so as follows: + npm install -g node-inspector +-----"; private readonly TaskCompletionSource _connectionIsReadySource = new TaskCompletionSource(); private bool _disposed; private readonly StringAsTempFile _entryPointScript; private FileSystemWatcher _fileSystemWatcher; private readonly Process _nodeProcess; + private int? _nodeDebuggingPort; private bool _nodeProcessNeedsRestart; private readonly string[] _watchFileExtensions; @@ -34,7 +45,9 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels string projectPath, string[] watchFileExtensions, string commandLineArguments, - ILogger nodeOutputLogger) + ILogger nodeOutputLogger, + bool launchWithDebugging, + int? debuggingPort) { if (nodeOutputLogger == null) { @@ -43,8 +56,9 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels OutputLogger = nodeOutputLogger; _entryPointScript = new StringAsTempFile(entryPointScript); - - var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments); + + var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments, + launchWithDebugging, debuggingPort); _nodeProcess = LaunchNodeProcess(startInfo); _watchFileExtensions = watchFileExtensions; _fileSystemWatcher = BeginFileWatcher(projectPath); @@ -84,11 +98,23 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels // This method is virtual, as it provides a way to override the NODE_PATH or the path to node.exe protected virtual ProcessStartInfo PrepareNodeProcessStartInfo( - string entryPointFilename, string projectPath, string commandLineArguments) + string entryPointFilename, string projectPath, string commandLineArguments, + bool launchWithDebugging, int? debuggingPort) { + string debuggingArgs; + if (launchWithDebugging) + { + debuggingArgs = debuggingPort.HasValue ? $"--debug={debuggingPort.Value} " : "--debug "; + _nodeDebuggingPort = debuggingPort; + } + else + { + debuggingArgs = string.Empty; + } + var startInfo = new ProcessStartInfo("node") { - Arguments = "\"" + entryPointFilename + "\" " + (commandLineArguments ?? string.Empty), + Arguments = debuggingArgs + "\"" + entryPointFilename + "\" " + (commandLineArguments ?? string.Empty), UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, @@ -201,7 +227,12 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels { if (evt.Data != null) { - if (!initializationIsCompleted) + if (IsDebuggerListeningMessage(evt.Data)) + { + var debugPortArg = _nodeDebuggingPort.HasValue ? $" --debug-port={_nodeDebuggingPort.Value}" : string.Empty; + OutputLogger.LogWarning(string.Format(DebuggingStartedMessageFormat, evt.Data, debugPortArg)); + } + else if (!initializationIsCompleted) { _connectionIsReadySource.SetException( new InvalidOperationException("The Node.js process failed to initialize: " + evt.Data)); @@ -218,6 +249,11 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels _nodeProcess.BeginErrorReadLine(); } + private static bool IsDebuggerListeningMessage(string message) + { + return message.StartsWith("Debugger listening on port ", StringComparison.OrdinalIgnoreCase); + } + private FileSystemWatcher BeginFileWatcher(string rootDir) { if (_watchFileExtensions == null || _watchFileExtensions.Length == 0) diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/SocketNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/SocketNodeInstance.cs index f5bbce1..5f3a6ec 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/SocketNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/SocketNodeInstance.cs @@ -37,14 +37,18 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels private string _socketAddress; private VirtualConnectionClient _virtualConnectionClient; - public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress, ILogger nodeInstanceOutputLogger) : base( + public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress, + ILogger nodeInstanceOutputLogger, bool launchWithDebugging, int? debuggingPort) + : base( EmbeddedResourceReader.Read( typeof(SocketNodeInstance), "/Content/Node/entrypoint-socket.js"), projectPath, watchFileExtensions, MakeNewCommandLineOptions(socketAddress), - nodeInstanceOutputLogger) + nodeInstanceOutputLogger, + launchWithDebugging, + debuggingPort) { _socketAddress = socketAddress; } From c892f7da35560c79d9a6a46b20607c4ecb4f812c Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 27 Jul 2016 09:50:43 +0100 Subject: [PATCH 07/19] Support debugging when on IPv6 network (Node's "Debugger listening" message is phrased differently there) --- .../HostingModels/OutOfProcessNodeInstance.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs index 01a9055..e85ed8c 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs @@ -251,7 +251,7 @@ If you haven't yet installed node-inspector, you can do so as follows: private static bool IsDebuggerListeningMessage(string message) { - return message.StartsWith("Debugger listening on port ", StringComparison.OrdinalIgnoreCase); + return message.StartsWith("Debugger listening ", StringComparison.OrdinalIgnoreCase); } private FileSystemWatcher BeginFileWatcher(string rootDir) From 698921d15751a12296cf106479203c1e7bc4f3d8 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 27 Jul 2016 10:43:16 +0100 Subject: [PATCH 08/19] Update Dockerfile in all templates to match .NET Core 1.0 RTM. Fixes #120 --- templates/Angular2Spa/Dockerfile | 14 ++++++++------ templates/KnockoutSpa/Dockerfile | 14 ++++++++------ templates/ReactReduxSpa/Dockerfile | 14 ++++++++------ templates/ReactSpa/Dockerfile | 14 ++++++++------ templates/WebApplicationBasic/Dockerfile | 14 ++++++++------ 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/templates/Angular2Spa/Dockerfile b/templates/Angular2Spa/Dockerfile index 63d7c45..10eb41a 100644 --- a/templates/Angular2Spa/Dockerfile +++ b/templates/Angular2Spa/Dockerfile @@ -1,11 +1,13 @@ -FROM microsoft/aspnet:1.0.0-rc1-update1 - -RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list -RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/* +FROM microsoft/dotnet:latest COPY . /app + WORKDIR /app -RUN ["dnu", "restore"] + +RUN ["dotnet", "restore"] + +RUN ["dotnet", "build"] EXPOSE 5000/tcp -ENTRYPOINT ["dnx", "-p", "project.json", "web"] + +ENTRYPOINT ["dotnet", "run", "--server.urls", "http://0.0.0.0:5000"] diff --git a/templates/KnockoutSpa/Dockerfile b/templates/KnockoutSpa/Dockerfile index 63d7c45..10eb41a 100644 --- a/templates/KnockoutSpa/Dockerfile +++ b/templates/KnockoutSpa/Dockerfile @@ -1,11 +1,13 @@ -FROM microsoft/aspnet:1.0.0-rc1-update1 - -RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list -RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/* +FROM microsoft/dotnet:latest COPY . /app + WORKDIR /app -RUN ["dnu", "restore"] + +RUN ["dotnet", "restore"] + +RUN ["dotnet", "build"] EXPOSE 5000/tcp -ENTRYPOINT ["dnx", "-p", "project.json", "web"] + +ENTRYPOINT ["dotnet", "run", "--server.urls", "http://0.0.0.0:5000"] diff --git a/templates/ReactReduxSpa/Dockerfile b/templates/ReactReduxSpa/Dockerfile index 63d7c45..10eb41a 100644 --- a/templates/ReactReduxSpa/Dockerfile +++ b/templates/ReactReduxSpa/Dockerfile @@ -1,11 +1,13 @@ -FROM microsoft/aspnet:1.0.0-rc1-update1 - -RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list -RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/* +FROM microsoft/dotnet:latest COPY . /app + WORKDIR /app -RUN ["dnu", "restore"] + +RUN ["dotnet", "restore"] + +RUN ["dotnet", "build"] EXPOSE 5000/tcp -ENTRYPOINT ["dnx", "-p", "project.json", "web"] + +ENTRYPOINT ["dotnet", "run", "--server.urls", "http://0.0.0.0:5000"] diff --git a/templates/ReactSpa/Dockerfile b/templates/ReactSpa/Dockerfile index 63d7c45..10eb41a 100644 --- a/templates/ReactSpa/Dockerfile +++ b/templates/ReactSpa/Dockerfile @@ -1,11 +1,13 @@ -FROM microsoft/aspnet:1.0.0-rc1-update1 - -RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list -RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/* +FROM microsoft/dotnet:latest COPY . /app + WORKDIR /app -RUN ["dnu", "restore"] + +RUN ["dotnet", "restore"] + +RUN ["dotnet", "build"] EXPOSE 5000/tcp -ENTRYPOINT ["dnx", "-p", "project.json", "web"] + +ENTRYPOINT ["dotnet", "run", "--server.urls", "http://0.0.0.0:5000"] diff --git a/templates/WebApplicationBasic/Dockerfile b/templates/WebApplicationBasic/Dockerfile index 63d7c45..10eb41a 100644 --- a/templates/WebApplicationBasic/Dockerfile +++ b/templates/WebApplicationBasic/Dockerfile @@ -1,11 +1,13 @@ -FROM microsoft/aspnet:1.0.0-rc1-update1 - -RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list -RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/* +FROM microsoft/dotnet:latest COPY . /app + WORKDIR /app -RUN ["dnu", "restore"] + +RUN ["dotnet", "restore"] + +RUN ["dotnet", "build"] EXPOSE 5000/tcp -ENTRYPOINT ["dnx", "-p", "project.json", "web"] + +ENTRYPOINT ["dotnet", "run", "--server.urls", "http://0.0.0.0:5000"] From 14337e32abe12a47e6365b54102f9dbb1b058e1e Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 27 Jul 2016 11:03:04 +0100 Subject: [PATCH 09/19] WebpackDevMiddleware now preserves client's view of hostname when doing 302 to /__webpack_hmr --- .../Webpack/WebpackDevMiddleware.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddleware.cs b/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddleware.cs index 959ee46..a9398d7 100644 --- a/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddleware.cs +++ b/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddleware.cs @@ -15,7 +15,6 @@ namespace Microsoft.AspNetCore.Builder public static class WebpackDevMiddleware { private const string WebpackDevMiddlewareScheme = "http"; - private const string WebpackDevMiddlewareHostname = "localhost"; private const string WebpackHotMiddlewareEndpoint = "/__webpack_hmr"; private const string DefaultConfigFile = "webpack.config.js"; @@ -64,19 +63,27 @@ namespace Microsoft.AspNetCore.Builder JsonConvert.SerializeObject(devServerOptions)).Result; // Proxy the corresponding requests through ASP.NET and into the Node listener + // Note that this is hardcoded to make requests to "localhost" regardless of the hostname of the + // server as far as the client is concerned. This is because ConditionalProxyMiddlewareOptions is + // the one making the internal HTTP requests, and it's going to be to some port on this machine + // because aspnet-webpack hosts the dev server there. We can't use the hostname that the client + // sees, because that could be anything (e.g., some upstream load balancer) and we might not be + // able to make outbound requests to it from here. var proxyOptions = new ConditionalProxyMiddlewareOptions(WebpackDevMiddlewareScheme, - WebpackDevMiddlewareHostname, devServerInfo.Port.ToString()); + "localhost", devServerInfo.Port.ToString()); appBuilder.UseMiddleware(devServerInfo.PublicPath, proxyOptions); // While it would be nice to proxy the /__webpack_hmr requests too, these return an EventStream, // and the Microsoft.AspNetCore.Proxy code doesn't handle that entirely - it throws an exception after - // a while. So, just serve a 302 for those. + // a while. So, just serve a 302 for those. But note that we must use the hostname that the client + // sees, not "localhost", so that it works even when you're not running on localhost (e.g., Docker). appBuilder.Map(WebpackHotMiddlewareEndpoint, builder => { builder.Use(next => async ctx => { + var hostname = ctx.Request.Host.Host; ctx.Response.Redirect( - $"{WebpackDevMiddlewareScheme}://{WebpackDevMiddlewareHostname}:{devServerInfo.Port.ToString()}{WebpackHotMiddlewareEndpoint}"); + $"{WebpackDevMiddlewareScheme}://{hostname}:{devServerInfo.Port.ToString()}{WebpackHotMiddlewareEndpoint}"); await Task.Yield(); }); }); From de960d80aa25c369bf2d49cc53b392f10fd834b7 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 27 Jul 2016 11:13:09 +0100 Subject: [PATCH 10/19] Allow explicit configuration of port number for webpack dev middleware server. Fixes #223. --- .../Webpack/WebpackDevMiddlewareOptions.cs | 1 + .../npm/aspnet-webpack/package.json | 2 +- .../npm/aspnet-webpack/src/WebpackDevMiddleware.ts | 7 +++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddlewareOptions.cs b/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddlewareOptions.cs index 08a6dbd..fcdde44 100644 --- a/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddlewareOptions.cs +++ b/src/Microsoft.AspNetCore.SpaServices/Webpack/WebpackDevMiddlewareOptions.cs @@ -3,6 +3,7 @@ namespace Microsoft.AspNetCore.SpaServices.Webpack public class WebpackDevMiddlewareOptions { public bool HotModuleReplacement { get; set; } + public int HotModuleReplacementServerPort { get; set; } public bool ReactHotModuleReplacement { get; set; } public string ConfigFile { get; set; } } diff --git a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json index 6e12ac7..4f652b7 100644 --- a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json +++ b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json @@ -1,6 +1,6 @@ { "name": "aspnet-webpack", - "version": "1.0.7", + "version": "1.0.8", "description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.", "main": "index.js", "scripts": { diff --git a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts index e33433f..af639c9 100644 --- a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts +++ b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts @@ -16,6 +16,7 @@ interface CreateDevServerOptions { // These are the options configured in C# and then JSON-serialized, hence the C#-style naming interface DevServerOptions { HotModuleReplacement: boolean; + HotModuleReplacementServerPort: number; ReactHotModuleReplacement: boolean; } @@ -35,9 +36,11 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option return; } + // The default value, 0, means 'choose randomly' + const suggestedHMRPortOrZero = options.suppliedOptions.HotModuleReplacementServerPort; + const app = connect(); - const defaultPort = 0; // 0 means 'choose randomly'. Could allow an explicit value to be supplied instead. - const listener = app.listen(defaultPort, () => { + const listener = app.listen(suggestedHMRPortOrZero, () => { // Build the final Webpack config based on supplied options if (enableHotModuleReplacement) { // TODO: Stop assuming there's an entry point called 'main' From e9ca43440512f06e0e7ef1aedad8ee58b1b90afa Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 27 Jul 2016 12:25:32 +0100 Subject: [PATCH 11/19] Update all templates to match latest "yo aspnet" output --- templates/Angular2Spa/Program.cs | 31 ++++++++++++ templates/Angular2Spa/Startup.cs | 49 ++++++++++--------- templates/Angular2Spa/appsettings.json | 2 +- templates/Angular2Spa/project.json | 41 ++-------------- templates/KnockoutSpa/Program.cs | 31 ++++++++++++ templates/KnockoutSpa/Startup.cs | 49 ++++++++++--------- templates/KnockoutSpa/appsettings.json | 2 +- templates/KnockoutSpa/project.json | 41 ++-------------- templates/ReactReduxSpa/Program.cs | 31 ++++++++++++ templates/ReactReduxSpa/Startup.cs | 49 ++++++++++--------- templates/ReactReduxSpa/appsettings.json | 2 +- templates/ReactReduxSpa/project.json | 41 ++-------------- templates/ReactSpa/Program.cs | 31 ++++++++++++ templates/ReactSpa/Startup.cs | 49 ++++++++++--------- templates/ReactSpa/appsettings.json | 2 +- templates/ReactSpa/project.json | 41 ++-------------- templates/WebApplicationBasic/Program.cs | 31 ++++++++++++ templates/WebApplicationBasic/Startup.cs | 44 ++++++++++------- .../WebApplicationBasic/appsettings.json | 2 +- templates/WebApplicationBasic/project.json | 41 ++-------------- 20 files changed, 311 insertions(+), 299 deletions(-) create mode 100644 templates/Angular2Spa/Program.cs create mode 100644 templates/KnockoutSpa/Program.cs create mode 100644 templates/ReactReduxSpa/Program.cs create mode 100644 templates/ReactSpa/Program.cs create mode 100644 templates/WebApplicationBasic/Program.cs diff --git a/templates/Angular2Spa/Program.cs b/templates/Angular2Spa/Program.cs new file mode 100644 index 0000000..b2e5e4b --- /dev/null +++ b/templates/Angular2Spa/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace WebApplicationBasic +{ + public class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .AddCommandLine(args) + .AddEnvironmentVariables(prefix: "ASPNETCORE_") + .Build(); + + var host = new WebHostBuilder() + .UseConfiguration(config) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/templates/Angular2Spa/Startup.cs b/templates/Angular2Spa/Startup.cs index 0c5cc48..e5d73ed 100755 --- a/templates/Angular2Spa/Startup.cs +++ b/templates/Angular2Spa/Startup.cs @@ -1,42 +1,57 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SpaServices.Webpack; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Serialization; namespace WebApplicationBasic { public class Startup { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot 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().AddJsonOptions(options => - { - options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - }); + // Add framework services. + services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - app.UseDeveloperExceptionPage(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - if (env.IsDevelopment()) { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true }); } + else + { + app.UseExceptionHandler("/Home/Error"); + } app.UseStaticFiles(); - loggerFactory.AddConsole(); + app.UseMvc(routes => { routes.MapRoute( @@ -48,17 +63,5 @@ namespace WebApplicationBasic defaults: new { controller = "Home", action = "Index" }); }); } - - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseKestrel() - .UseStartup() - .Build(); - - host.Run(); - } } } diff --git a/templates/Angular2Spa/appsettings.json b/templates/Angular2Spa/appsettings.json index e5472e5..723c096 100755 --- a/templates/Angular2Spa/appsettings.json +++ b/templates/Angular2Spa/appsettings.json @@ -2,7 +2,7 @@ "Logging": { "IncludeScopes": false, "LogLevel": { - "Default": "Verbose", + "Default": "Debug", "System": "Information", "Microsoft": "Information" } diff --git a/templates/Angular2Spa/project.json b/templates/Angular2Spa/project.json index 1ce5f41..845fe68 100755 --- a/templates/Angular2Spa/project.json +++ b/templates/Angular2Spa/project.json @@ -4,7 +4,6 @@ "version": "1.0.0", "type": "platform" }, - "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0", "Microsoft.AspNetCore.AngularServices": "1.0.0-*", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", @@ -17,46 +16,16 @@ "Microsoft.AspNetCore.StaticFiles": "1.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.Configuration.CommandLine": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "type": "build" - }, - "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": { - "version": "1.0.0-preview2-final", - "type": "build" - } + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0" }, "tools": { - "Microsoft.AspNetCore.Razor.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.AspNetCore.Server.IISIntegration.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.EntityFrameworkCore.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, - "Microsoft.Extensions.SecretManager.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, + "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final", "Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final" }, @@ -64,14 +33,12 @@ "netcoreapp1.0": { "imports": [ "dotnet5.6", - "dnxcore50", "portable-net45+win8" ] } }, "buildOptions": { - "debugType": "portable", "emitEntryPoint": true, "preserveCompilationContext": true }, diff --git a/templates/KnockoutSpa/Program.cs b/templates/KnockoutSpa/Program.cs new file mode 100644 index 0000000..b2e5e4b --- /dev/null +++ b/templates/KnockoutSpa/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace WebApplicationBasic +{ + public class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .AddCommandLine(args) + .AddEnvironmentVariables(prefix: "ASPNETCORE_") + .Build(); + + var host = new WebHostBuilder() + .UseConfiguration(config) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/templates/KnockoutSpa/Startup.cs b/templates/KnockoutSpa/Startup.cs index 0c5cc48..e5d73ed 100755 --- a/templates/KnockoutSpa/Startup.cs +++ b/templates/KnockoutSpa/Startup.cs @@ -1,42 +1,57 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SpaServices.Webpack; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Serialization; namespace WebApplicationBasic { public class Startup { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot 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().AddJsonOptions(options => - { - options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - }); + // Add framework services. + services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - app.UseDeveloperExceptionPage(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - if (env.IsDevelopment()) { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true }); } + else + { + app.UseExceptionHandler("/Home/Error"); + } app.UseStaticFiles(); - loggerFactory.AddConsole(); + app.UseMvc(routes => { routes.MapRoute( @@ -48,17 +63,5 @@ namespace WebApplicationBasic defaults: new { controller = "Home", action = "Index" }); }); } - - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseKestrel() - .UseStartup() - .Build(); - - host.Run(); - } } } diff --git a/templates/KnockoutSpa/appsettings.json b/templates/KnockoutSpa/appsettings.json index e5472e5..723c096 100755 --- a/templates/KnockoutSpa/appsettings.json +++ b/templates/KnockoutSpa/appsettings.json @@ -2,7 +2,7 @@ "Logging": { "IncludeScopes": false, "LogLevel": { - "Default": "Verbose", + "Default": "Debug", "System": "Information", "Microsoft": "Information" } diff --git a/templates/KnockoutSpa/project.json b/templates/KnockoutSpa/project.json index 66ff147..d3e2777 100755 --- a/templates/KnockoutSpa/project.json +++ b/templates/KnockoutSpa/project.json @@ -4,7 +4,6 @@ "version": "1.0.0", "type": "platform" }, - "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0", "Microsoft.AspNetCore.SpaServices": "1.0.0-*", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", @@ -17,46 +16,16 @@ "Microsoft.AspNetCore.StaticFiles": "1.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.Configuration.CommandLine": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "type": "build" - }, - "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": { - "version": "1.0.0-preview2-final", - "type": "build" - } + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0" }, "tools": { - "Microsoft.AspNetCore.Razor.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.AspNetCore.Server.IISIntegration.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.EntityFrameworkCore.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, - "Microsoft.Extensions.SecretManager.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, + "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final", "Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final" }, @@ -64,14 +33,12 @@ "netcoreapp1.0": { "imports": [ "dotnet5.6", - "dnxcore50", "portable-net45+win8" ] } }, "buildOptions": { - "debugType": "portable", "emitEntryPoint": true, "preserveCompilationContext": true }, diff --git a/templates/ReactReduxSpa/Program.cs b/templates/ReactReduxSpa/Program.cs new file mode 100644 index 0000000..b2e5e4b --- /dev/null +++ b/templates/ReactReduxSpa/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace WebApplicationBasic +{ + public class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .AddCommandLine(args) + .AddEnvironmentVariables(prefix: "ASPNETCORE_") + .Build(); + + var host = new WebHostBuilder() + .UseConfiguration(config) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/templates/ReactReduxSpa/Startup.cs b/templates/ReactReduxSpa/Startup.cs index 6f4babb..750d79c 100755 --- a/templates/ReactReduxSpa/Startup.cs +++ b/templates/ReactReduxSpa/Startup.cs @@ -1,43 +1,58 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SpaServices.Webpack; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Serialization; namespace WebApplicationBasic { public class Startup { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot 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().AddJsonOptions(options => - { - options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - }); + // Add framework services. + services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - app.UseDeveloperExceptionPage(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - if (env.IsDevelopment()) { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true, ReactHotModuleReplacement = true }); } + else + { + app.UseExceptionHandler("/Home/Error"); + } app.UseStaticFiles(); - loggerFactory.AddConsole(); + app.UseMvc(routes => { routes.MapRoute( @@ -49,17 +64,5 @@ namespace WebApplicationBasic defaults: new { controller = "Home", action = "Index" }); }); } - - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseKestrel() - .UseStartup() - .Build(); - - host.Run(); - } } } diff --git a/templates/ReactReduxSpa/appsettings.json b/templates/ReactReduxSpa/appsettings.json index e5472e5..723c096 100755 --- a/templates/ReactReduxSpa/appsettings.json +++ b/templates/ReactReduxSpa/appsettings.json @@ -2,7 +2,7 @@ "Logging": { "IncludeScopes": false, "LogLevel": { - "Default": "Verbose", + "Default": "Debug", "System": "Information", "Microsoft": "Information" } diff --git a/templates/ReactReduxSpa/project.json b/templates/ReactReduxSpa/project.json index f768eca..0794a38 100755 --- a/templates/ReactReduxSpa/project.json +++ b/templates/ReactReduxSpa/project.json @@ -4,7 +4,6 @@ "version": "1.0.0", "type": "platform" }, - "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0", "Microsoft.AspNetCore.ReactServices": "1.0.0-*", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", @@ -17,46 +16,16 @@ "Microsoft.AspNetCore.StaticFiles": "1.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.Configuration.CommandLine": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "type": "build" - }, - "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": { - "version": "1.0.0-preview2-final", - "type": "build" - } + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0" }, "tools": { - "Microsoft.AspNetCore.Razor.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.AspNetCore.Server.IISIntegration.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.EntityFrameworkCore.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, - "Microsoft.Extensions.SecretManager.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, + "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final", "Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final" }, @@ -64,14 +33,12 @@ "netcoreapp1.0": { "imports": [ "dotnet5.6", - "dnxcore50", "portable-net45+win8" ] } }, "buildOptions": { - "debugType": "portable", "emitEntryPoint": true, "preserveCompilationContext": true }, diff --git a/templates/ReactSpa/Program.cs b/templates/ReactSpa/Program.cs new file mode 100644 index 0000000..b2e5e4b --- /dev/null +++ b/templates/ReactSpa/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace WebApplicationBasic +{ + public class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .AddCommandLine(args) + .AddEnvironmentVariables(prefix: "ASPNETCORE_") + .Build(); + + var host = new WebHostBuilder() + .UseConfiguration(config) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/templates/ReactSpa/Startup.cs b/templates/ReactSpa/Startup.cs index 6f4babb..750d79c 100755 --- a/templates/ReactSpa/Startup.cs +++ b/templates/ReactSpa/Startup.cs @@ -1,43 +1,58 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SpaServices.Webpack; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Serialization; namespace WebApplicationBasic { public class Startup { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot 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().AddJsonOptions(options => - { - options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - }); + // Add framework services. + services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - app.UseDeveloperExceptionPage(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); - if (env.IsDevelopment()) { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true, ReactHotModuleReplacement = true }); } + else + { + app.UseExceptionHandler("/Home/Error"); + } app.UseStaticFiles(); - loggerFactory.AddConsole(); + app.UseMvc(routes => { routes.MapRoute( @@ -49,17 +64,5 @@ namespace WebApplicationBasic defaults: new { controller = "Home", action = "Index" }); }); } - - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseKestrel() - .UseStartup() - .Build(); - - host.Run(); - } } } diff --git a/templates/ReactSpa/appsettings.json b/templates/ReactSpa/appsettings.json index e5472e5..723c096 100755 --- a/templates/ReactSpa/appsettings.json +++ b/templates/ReactSpa/appsettings.json @@ -2,7 +2,7 @@ "Logging": { "IncludeScopes": false, "LogLevel": { - "Default": "Verbose", + "Default": "Debug", "System": "Information", "Microsoft": "Information" } diff --git a/templates/ReactSpa/project.json b/templates/ReactSpa/project.json index f768eca..0794a38 100755 --- a/templates/ReactSpa/project.json +++ b/templates/ReactSpa/project.json @@ -4,7 +4,6 @@ "version": "1.0.0", "type": "platform" }, - "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0", "Microsoft.AspNetCore.ReactServices": "1.0.0-*", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", @@ -17,46 +16,16 @@ "Microsoft.AspNetCore.StaticFiles": "1.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.Configuration.CommandLine": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "type": "build" - }, - "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": { - "version": "1.0.0-preview2-final", - "type": "build" - } + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0" }, "tools": { - "Microsoft.AspNetCore.Razor.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.AspNetCore.Server.IISIntegration.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.EntityFrameworkCore.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, - "Microsoft.Extensions.SecretManager.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, + "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final", "Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final" }, @@ -64,14 +33,12 @@ "netcoreapp1.0": { "imports": [ "dotnet5.6", - "dnxcore50", "portable-net45+win8" ] } }, "buildOptions": { - "debugType": "portable", "emitEntryPoint": true, "preserveCompilationContext": true }, diff --git a/templates/WebApplicationBasic/Program.cs b/templates/WebApplicationBasic/Program.cs new file mode 100644 index 0000000..b2e5e4b --- /dev/null +++ b/templates/WebApplicationBasic/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace WebApplicationBasic +{ + public class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .AddCommandLine(args) + .AddEnvironmentVariables(prefix: "ASPNETCORE_") + .Build(); + + var host = new WebHostBuilder() + .UseConfiguration(config) + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/templates/WebApplicationBasic/Startup.cs b/templates/WebApplicationBasic/Startup.cs index 4ddc86c..fe5473d 100755 --- a/templates/WebApplicationBasic/Startup.cs +++ b/templates/WebApplicationBasic/Startup.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -13,19 +12,42 @@ namespace WebApplicationBasic { public class Startup { + public Startup(IHostingEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot Configuration { get; } + // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + // Add framework services. services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { - app.UseDeveloperExceptionPage(); + loggerFactory.AddConsole(Configuration.GetSection("Logging")); + loggerFactory.AddDebug(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + } app.UseStaticFiles(); - loggerFactory.AddConsole(); + app.UseMvc(routes => { routes.MapRoute( @@ -33,17 +55,5 @@ namespace WebApplicationBasic template: "{controller=Home}/{action=Index}/{id?}"); }); } - - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() - .UseKestrel() - .UseStartup() - .Build(); - - host.Run(); - } } } diff --git a/templates/WebApplicationBasic/appsettings.json b/templates/WebApplicationBasic/appsettings.json index e5472e5..723c096 100755 --- a/templates/WebApplicationBasic/appsettings.json +++ b/templates/WebApplicationBasic/appsettings.json @@ -2,7 +2,7 @@ "Logging": { "IncludeScopes": false, "LogLevel": { - "Default": "Verbose", + "Default": "Debug", "System": "Information", "Microsoft": "Information" } diff --git a/templates/WebApplicationBasic/project.json b/templates/WebApplicationBasic/project.json index a28b4b3..4464a43 100755 --- a/templates/WebApplicationBasic/project.json +++ b/templates/WebApplicationBasic/project.json @@ -4,7 +4,6 @@ "version": "1.0.0", "type": "platform" }, - "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.AspNetCore.Razor.Tools": { @@ -16,60 +15,28 @@ "Microsoft.AspNetCore.StaticFiles": "1.0.0", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.Configuration.CommandLine": "1.0.0", "Microsoft.Extensions.Logging": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "type": "build" - }, - "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": { - "version": "1.0.0-preview2-final", - "type": "build" - } + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0" }, "tools": { - "Microsoft.AspNetCore.Razor.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.AspNetCore.Server.IISIntegration.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.EntityFrameworkCore.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - }, - "Microsoft.Extensions.SecretManager.Tools": { - "version": "1.0.0-preview2-final", - "imports": "portable-net45+win8+dnxcore50" - }, - "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { - "version": "1.0.0-preview2-final", - "imports": [ - "portable-net45+win8+dnxcore50", - "portable-net45+win8" - ] - } + "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" }, "frameworks": { "netcoreapp1.0": { "imports": [ "dotnet5.6", - "dnxcore50", "portable-net45+win8" ] } }, "buildOptions": { - "debugType": "portable", "emitEntryPoint": true, "preserveCompilationContext": true }, From 0a3463031b622f7d9e5b6a426c979f5055e69c4d Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 27 Jul 2016 13:09:54 +0100 Subject: [PATCH 12/19] Add Node.js support in all the Docker containers --- templates/Angular2Spa/Dockerfile | 5 +++++ templates/KnockoutSpa/Dockerfile | 5 +++++ templates/ReactReduxSpa/Dockerfile | 5 +++++ templates/ReactSpa/Dockerfile | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/templates/Angular2Spa/Dockerfile b/templates/Angular2Spa/Dockerfile index 10eb41a..b382b9e 100644 --- a/templates/Angular2Spa/Dockerfile +++ b/templates/Angular2Spa/Dockerfile @@ -4,6 +4,11 @@ COPY . /app WORKDIR /app +# Add Node.js to the container. If you don't want to wait for this to install every +# time you rebuild your container, consider creating an image that has it preinstalled. +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + RUN ["dotnet", "restore"] RUN ["dotnet", "build"] diff --git a/templates/KnockoutSpa/Dockerfile b/templates/KnockoutSpa/Dockerfile index 10eb41a..b382b9e 100644 --- a/templates/KnockoutSpa/Dockerfile +++ b/templates/KnockoutSpa/Dockerfile @@ -4,6 +4,11 @@ COPY . /app WORKDIR /app +# Add Node.js to the container. If you don't want to wait for this to install every +# time you rebuild your container, consider creating an image that has it preinstalled. +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + RUN ["dotnet", "restore"] RUN ["dotnet", "build"] diff --git a/templates/ReactReduxSpa/Dockerfile b/templates/ReactReduxSpa/Dockerfile index 10eb41a..b382b9e 100644 --- a/templates/ReactReduxSpa/Dockerfile +++ b/templates/ReactReduxSpa/Dockerfile @@ -4,6 +4,11 @@ COPY . /app WORKDIR /app +# Add Node.js to the container. If you don't want to wait for this to install every +# time you rebuild your container, consider creating an image that has it preinstalled. +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + RUN ["dotnet", "restore"] RUN ["dotnet", "build"] diff --git a/templates/ReactSpa/Dockerfile b/templates/ReactSpa/Dockerfile index 10eb41a..b382b9e 100644 --- a/templates/ReactSpa/Dockerfile +++ b/templates/ReactSpa/Dockerfile @@ -4,6 +4,11 @@ COPY . /app WORKDIR /app +# Add Node.js to the container. If you don't want to wait for this to install every +# time you rebuild your container, consider creating an image that has it preinstalled. +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + RUN ["dotnet", "restore"] RUN ["dotnet", "build"] From 3403eb75487cd487666e550777d18fd9c2116a52 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Wed, 27 Jul 2016 13:29:18 +0100 Subject: [PATCH 13/19] Make aspnet-webpack compatible with older versions of the NodeServices package --- .../npm/aspnet-webpack/package.json | 2 +- .../npm/aspnet-webpack/src/WebpackDevMiddleware.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json index 4f652b7..8980b92 100644 --- a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json +++ b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/package.json @@ -1,6 +1,6 @@ { "name": "aspnet-webpack", - "version": "1.0.8", + "version": "1.0.9", "description": "Helpers for using Webpack in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.", "main": "index.js", "scripts": { diff --git a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts index af639c9..f34eefd 100644 --- a/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts +++ b/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts @@ -37,7 +37,7 @@ export function createWebpackDevServer(callback: CreateDevServerCallback, option } // The default value, 0, means 'choose randomly' - const suggestedHMRPortOrZero = options.suppliedOptions.HotModuleReplacementServerPort; + const suggestedHMRPortOrZero = options.suppliedOptions.HotModuleReplacementServerPort || 0; const app = connect(); const listener = app.listen(suggestedHMRPortOrZero, () => { From c07bd9627009ef63b17d809093488ee94f62cab9 Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Thu, 4 Aug 2016 17:45:04 +1000 Subject: [PATCH 14/19] Update generator-aspnetcore-spa version --- templates/yeoman/src/generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/yeoman/src/generator/package.json b/templates/yeoman/src/generator/package.json index ad60454..839ed75 100644 --- a/templates/yeoman/src/generator/package.json +++ b/templates/yeoman/src/generator/package.json @@ -1,6 +1,6 @@ { "name": "generator-aspnetcore-spa", - "version": "0.2.2", + "version": "0.2.3", "description": "Single-Page App templates for ASP.NET Core", "author": "Microsoft", "license": "Apache-2.0", From cf1a127e7dac44b8975d0f0ec5267eece1088db9 Mon Sep 17 00:00:00 2001 From: Aidan Steele Date: Thu, 4 Aug 2016 11:42:15 +1000 Subject: [PATCH 15/19] Perform nodejs installation before COPY in Dockerfile templates --- templates/Angular2Spa/Dockerfile | 8 +++----- templates/KnockoutSpa/Dockerfile | 8 +++----- templates/ReactReduxSpa/Dockerfile | 8 +++----- templates/ReactSpa/Dockerfile | 8 +++----- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/templates/Angular2Spa/Dockerfile b/templates/Angular2Spa/Dockerfile index b382b9e..748edec 100644 --- a/templates/Angular2Spa/Dockerfile +++ b/templates/Angular2Spa/Dockerfile @@ -1,14 +1,12 @@ FROM microsoft/dotnet:latest +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + COPY . /app WORKDIR /app -# Add Node.js to the container. If you don't want to wait for this to install every -# time you rebuild your container, consider creating an image that has it preinstalled. -RUN apt-get update -RUN apt-get install -y build-essential nodejs nodejs-legacy - RUN ["dotnet", "restore"] RUN ["dotnet", "build"] diff --git a/templates/KnockoutSpa/Dockerfile b/templates/KnockoutSpa/Dockerfile index b382b9e..748edec 100644 --- a/templates/KnockoutSpa/Dockerfile +++ b/templates/KnockoutSpa/Dockerfile @@ -1,14 +1,12 @@ FROM microsoft/dotnet:latest +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + COPY . /app WORKDIR /app -# Add Node.js to the container. If you don't want to wait for this to install every -# time you rebuild your container, consider creating an image that has it preinstalled. -RUN apt-get update -RUN apt-get install -y build-essential nodejs nodejs-legacy - RUN ["dotnet", "restore"] RUN ["dotnet", "build"] diff --git a/templates/ReactReduxSpa/Dockerfile b/templates/ReactReduxSpa/Dockerfile index b382b9e..748edec 100644 --- a/templates/ReactReduxSpa/Dockerfile +++ b/templates/ReactReduxSpa/Dockerfile @@ -1,14 +1,12 @@ FROM microsoft/dotnet:latest +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + COPY . /app WORKDIR /app -# Add Node.js to the container. If you don't want to wait for this to install every -# time you rebuild your container, consider creating an image that has it preinstalled. -RUN apt-get update -RUN apt-get install -y build-essential nodejs nodejs-legacy - RUN ["dotnet", "restore"] RUN ["dotnet", "build"] diff --git a/templates/ReactSpa/Dockerfile b/templates/ReactSpa/Dockerfile index b382b9e..748edec 100644 --- a/templates/ReactSpa/Dockerfile +++ b/templates/ReactSpa/Dockerfile @@ -1,14 +1,12 @@ FROM microsoft/dotnet:latest +RUN apt-get update +RUN apt-get install -y build-essential nodejs nodejs-legacy + COPY . /app WORKDIR /app -# Add Node.js to the container. If you don't want to wait for this to install every -# time you rebuild your container, consider creating an image that has it preinstalled. -RUN apt-get update -RUN apt-get install -y build-essential nodejs nodejs-legacy - RUN ["dotnet", "restore"] RUN ["dotnet", "build"] From a631f77a33a493d2e9961da1e8535f0ef2466703 Mon Sep 17 00:00:00 2001 From: Aidan Steele Date: Thu, 4 Aug 2016 11:56:10 +1000 Subject: [PATCH 16/19] Copy only project.json before dotnet restore in Dockerfile templates --- templates/Angular2Spa/Dockerfile | 4 ++-- templates/KnockoutSpa/Dockerfile | 4 ++-- templates/ReactReduxSpa/Dockerfile | 4 ++-- templates/ReactSpa/Dockerfile | 4 ++-- templates/WebApplicationBasic/Dockerfile | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/templates/Angular2Spa/Dockerfile b/templates/Angular2Spa/Dockerfile index 748edec..b828f96 100644 --- a/templates/Angular2Spa/Dockerfile +++ b/templates/Angular2Spa/Dockerfile @@ -3,12 +3,12 @@ FROM microsoft/dotnet:latest RUN apt-get update RUN apt-get install -y build-essential nodejs nodejs-legacy -COPY . /app - WORKDIR /app +COPY project.json . RUN ["dotnet", "restore"] +COPY . /app RUN ["dotnet", "build"] EXPOSE 5000/tcp diff --git a/templates/KnockoutSpa/Dockerfile b/templates/KnockoutSpa/Dockerfile index 748edec..b828f96 100644 --- a/templates/KnockoutSpa/Dockerfile +++ b/templates/KnockoutSpa/Dockerfile @@ -3,12 +3,12 @@ FROM microsoft/dotnet:latest RUN apt-get update RUN apt-get install -y build-essential nodejs nodejs-legacy -COPY . /app - WORKDIR /app +COPY project.json . RUN ["dotnet", "restore"] +COPY . /app RUN ["dotnet", "build"] EXPOSE 5000/tcp diff --git a/templates/ReactReduxSpa/Dockerfile b/templates/ReactReduxSpa/Dockerfile index 748edec..b828f96 100644 --- a/templates/ReactReduxSpa/Dockerfile +++ b/templates/ReactReduxSpa/Dockerfile @@ -3,12 +3,12 @@ FROM microsoft/dotnet:latest RUN apt-get update RUN apt-get install -y build-essential nodejs nodejs-legacy -COPY . /app - WORKDIR /app +COPY project.json . RUN ["dotnet", "restore"] +COPY . /app RUN ["dotnet", "build"] EXPOSE 5000/tcp diff --git a/templates/ReactSpa/Dockerfile b/templates/ReactSpa/Dockerfile index 748edec..b828f96 100644 --- a/templates/ReactSpa/Dockerfile +++ b/templates/ReactSpa/Dockerfile @@ -3,12 +3,12 @@ FROM microsoft/dotnet:latest RUN apt-get update RUN apt-get install -y build-essential nodejs nodejs-legacy -COPY . /app - WORKDIR /app +COPY project.json . RUN ["dotnet", "restore"] +COPY . /app RUN ["dotnet", "build"] EXPOSE 5000/tcp diff --git a/templates/WebApplicationBasic/Dockerfile b/templates/WebApplicationBasic/Dockerfile index 10eb41a..134c714 100644 --- a/templates/WebApplicationBasic/Dockerfile +++ b/templates/WebApplicationBasic/Dockerfile @@ -1,11 +1,11 @@ FROM microsoft/dotnet:latest -COPY . /app - WORKDIR /app +COPY project.json . RUN ["dotnet", "restore"] +COPY . /app RUN ["dotnet", "build"] EXPOSE 5000/tcp From 4665d1f458194f8f9182ba94b94e3d0fdb9a2363 Mon Sep 17 00:00:00 2001 From: Mark Pieszak Date: Wed, 27 Jul 2016 15:33:17 -0400 Subject: [PATCH 17/19] docs(readme): Show how to get started with yeoman --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ed2f172..df94094 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,19 @@ Everything here is cross-platform, and works with .NET Core 1.0 RC2 or later on If you want to build a brand-new ASP.NET Core app that uses Angular 2 / React / Knockout on the client, consider starting with the `aspnetcore-spa` generator. This lets you choose your client-side framework, and generates a starting point that includes applicable features such as Webpack dev middleware, server-side prerendering, and efficient production builds. -See: [getting started with the `aspnetcore-spa` generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/). It's much easier than configuring everything to work together manually! +```` +// install yeoman, the generator, and a short-term global webpack dependency +npm install -g yo generator-aspnetcore-spa webpack + +// go to a new directory and install your framework of choice! +cd some-empty-directory +yo aspnetcore-spa + +// Run it! +dotnet run +```` + +For more details see: [getting started with the `aspnetcore-spa` generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/). It's much easier than configuring everything to work together manually! ## Adding to existing applications From 7052fa0ad27d272257fec53c7c12cb25a35412ec Mon Sep 17 00:00:00 2001 From: SteveSandersonMS Date: Thu, 4 Aug 2016 18:03:43 +1000 Subject: [PATCH 18/19] Rephrased docs to clarify which are the parts you type into the command line --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index df94094..85dd692 100644 --- a/README.md +++ b/README.md @@ -24,22 +24,22 @@ Everything here is cross-platform, and works with .NET Core 1.0 RC2 or later on ## Creating new applications -If you want to build a brand-new ASP.NET Core app that uses Angular 2 / React / Knockout on the client, consider starting with the `aspnetcore-spa` generator. This lets you choose your client-side framework, and generates a starting point that includes applicable features such as Webpack dev middleware, server-side prerendering, and efficient production builds. +If you want to build a brand-new ASP.NET Core app that uses Angular 2 / React / Knockout on the client, consider starting with the `aspnetcore-spa` generator. This lets you choose your client-side framework, and generates a starting point that includes applicable features such as Webpack dev middleware, server-side prerendering, and efficient production builds. It's much easier than configuring everything to work together manually! -```` -// install yeoman, the generator, and a short-term global webpack dependency -npm install -g yo generator-aspnetcore-spa webpack +To do this, first install Yeoman and these generator templates: -// go to a new directory and install your framework of choice! -cd some-empty-directory -yo aspnetcore-spa + npm install -g yo generator-aspnetcore-spa -// Run it! -dotnet run -```` +Then you can generate your new application starting point: -For more details see: [getting started with the `aspnetcore-spa` generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/). It's much easier than configuring everything to work together manually! + cd some-empty-directory + yo aspnetcore-spa +Finally, once the generator has run and restored all the dependencies, you can start up your new ASP.NET Core Single Page Application: + + dotnet run + +For a more detailed walkthrough, see [getting started with the `aspnetcore-spa` generator](http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/). ## Adding to existing applications From 2a6465b27aa0c8deebbeb672f5ee0e95d2f20676 Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Mon, 8 Aug 2016 10:54:22 +1000 Subject: [PATCH 19/19] FIxing path separator to address #247 (#248) * Correcting path separator to ; * Using the proper API from System.IO to get path separator --- .../HostingModels/OutOfProcessNodeInstance.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs index e85ed8c..3c9cfd5 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs @@ -126,7 +126,7 @@ If you haven't yet installed node-inspector, you can do so as follows: var existingNodePath = Environment.GetEnvironmentVariable("NODE_PATH") ?? string.Empty; if (existingNodePath != string.Empty) { - existingNodePath += ":"; + existingNodePath += Path.PathSeparator; } var nodePathValue = existingNodePath + Path.Combine(projectPath, "node_modules");