diff --git a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs b/src/Middleware/SpaServices.Extensions/src/DevelopmentServer/DevelopmentServerMiddleware.cs similarity index 72% rename from src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs rename to src/Middleware/SpaServices.Extensions/src/DevelopmentServer/DevelopmentServerMiddleware.cs index 78a7b4f03f27..81b8608f9b00 100644 --- a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs +++ b/src/Middleware/SpaServices.Extensions/src/DevelopmentServer/DevelopmentServerMiddleware.cs @@ -9,20 +9,24 @@ using System; using System.IO; using System.Collections.Generic; +using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.SpaServices.Extensions.Util; -namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer +namespace Microsoft.AspNetCore.SpaServices.DevelopmentServer { - internal static class ReactDevelopmentServerMiddleware + internal static class DevelopmentServerMiddleware { private const string LogCategoryName = "Microsoft.AspNetCore.SpaServices"; private static TimeSpan RegexMatchTimeout = TimeSpan.FromSeconds(5); // This is a development-time only feature, so a very long timeout is fine public static void Attach( ISpaBuilder spaBuilder, - string npmScriptName) + string npmScriptName, + string waitText, + Dictionary extraArgs, + string serverName = "App") { var sourcePath = spaBuilder.Options.SourcePath; if (string.IsNullOrEmpty(sourcePath)) @@ -38,7 +42,7 @@ public static void Attach( // Start create-react-app and attach to middleware pipeline var appBuilder = spaBuilder.ApplicationBuilder; var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName); - var portTask = StartCreateReactAppServerAsync(sourcePath, npmScriptName, logger); + var portTask = StartDevServerAsync(sourcePath, npmScriptName, waitText, serverName, logger, extraArgs); // Everything we proxy is hardcoded to target http://localhost because: // - the requests are always from the local machine (we're not accepting remote @@ -54,43 +58,47 @@ public static void Attach( // the first request times out, subsequent requests could still work. var timeout = spaBuilder.Options.StartupTimeout; return targetUriTask.WithTimeout(timeout, - $"The create-react-app server did not start listening for requests " + + $"The {serverName} server did not start listening for requests " + $"within the timeout period of {timeout.Seconds} seconds. " + $"Check the log output for error information."); }); } - private static async Task StartCreateReactAppServerAsync( - string sourcePath, string npmScriptName, ILogger logger) + private static async Task StartDevServerAsync( + string sourcePath, string npmScriptName, string waitText, string serverName, ILogger logger, Dictionary extraArgs = null) { var portNumber = TcpPortFinder.FindAvailablePort(); - logger.LogInformation($"Starting create-react-app server on port {portNumber}..."); + logger.LogInformation($"Starting {serverName} server on port {portNumber}..."); var envVars = new Dictionary { - { "PORT", portNumber.ToString() }, - { "BROWSER", "none" }, // We don't want create-react-app to open its own extra browser window pointing to the internal dev server port + { "PORT", portNumber.ToString() } }; + + waitText = waitText.Replace("$PORT", portNumber.ToString()); + + extraArgs = extraArgs.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Replace("$PORT", portNumber.ToString())); + var npmScriptRunner = new NpmScriptRunner( - sourcePath, npmScriptName, null, envVars); + sourcePath, npmScriptName, string.Join(" ", extraArgs.Select(x => x.Key + " " + x.Value).ToArray()), envVars); npmScriptRunner.AttachToLogger(logger); using (var stdErrReader = new EventedStreamStringReader(npmScriptRunner.StdErr)) { try { - // Although the React dev server may eventually tell us the URL it's listening on, + // Although the dev server may eventually tell us the URL it's listening on, // it doesn't do so until it's finished compiling, and even then only if there were // no compiler warnings. So instead of waiting for that, consider it ready as soon // as it starts listening for requests. await npmScriptRunner.StdOut.WaitForMatch( - new Regex("Starting the development server", RegexOptions.None, RegexMatchTimeout)); + new Regex(waitText, RegexOptions.None, RegexMatchTimeout)); } catch (EndOfStreamException ex) { throw new InvalidOperationException( $"The NPM script '{npmScriptName}' exited without indicating that the " + - $"create-react-app server was listening for requests. The error output was: " + + $"{serverName} server was listening for requests. The error output was: " + $"{stdErrReader.ReadAsString()}", ex); } } diff --git a/src/Middleware/SpaServices.Extensions/src/DevelopmentServer/DevelopmentServerMiddlewareExtensions.cs b/src/Middleware/SpaServices.Extensions/src/DevelopmentServer/DevelopmentServerMiddlewareExtensions.cs new file mode 100644 index 000000000000..84ab1864e786 --- /dev/null +++ b/src/Middleware/SpaServices.Extensions/src/DevelopmentServer/DevelopmentServerMiddlewareExtensions.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Builder; +using System; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.SpaServices.DevelopmentServer +{ + /// + /// Extension methods for enabling React development server middleware support. + /// + public static class DevelopmentServerMiddlewareExtensions + { + /// + /// Handles requests by passing them through to an instance of a development npm web server. + /// This means you can always serve up-to-date CLI-built resources without having + /// to run the npm web server manually. + /// + /// This feature should only be used in development. For production deployments, be + /// sure not to enable the npm web server. + /// + /// The . + /// The name of the script in your package.json file that launches the web server. + /// The text snippet identified during the build to indicate the Development Server has compiled and is ready. + /// The name of the Server used in the Console. + public static void UseDevelopmentServer( + this ISpaBuilder spaBuilder, + string npmScript, + string waitText, + string serverName = "App", + Dictionary extraArgs = null) + { + + if (string.IsNullOrEmpty(waitText)) + { + throw new InvalidOperationException($"To use {nameof(UseDevelopmentServer)}, you must supply a non-empty value for the {nameof(waitText)} parameter. This allows us the find when the Development Server has started."); + } + + if (spaBuilder == null) + { + throw new ArgumentNullException(nameof(spaBuilder)); + } + + var spaOptions = spaBuilder.Options; + + if (string.IsNullOrEmpty(spaOptions.SourcePath)) + { + throw new InvalidOperationException($"To use {nameof(UseDevelopmentServer)}, you must supply a non-empty value for the {nameof(SpaOptions.SourcePath)} property of {nameof(SpaOptions)} when calling {nameof(SpaApplicationBuilderExtensions.UseSpa)}."); + } + + DevelopmentServerMiddleware.Attach(spaBuilder, npmScript, waitText, extraArgs, serverName); + } + } +} diff --git a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs index f58a6d1a9dd2..69ff9677a18e 100644 --- a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs +++ b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs @@ -1,7 +1,8 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.SpaServices.DevelopmentServer; using System; namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer @@ -25,19 +26,7 @@ public static void UseReactDevelopmentServer( this ISpaBuilder spaBuilder, string npmScript) { - if (spaBuilder == null) - { - throw new ArgumentNullException(nameof(spaBuilder)); - } - - var spaOptions = spaBuilder.Options; - - if (string.IsNullOrEmpty(spaOptions.SourcePath)) - { - throw new InvalidOperationException($"To use {nameof(UseReactDevelopmentServer)}, you must supply a non-empty value for the {nameof(SpaOptions.SourcePath)} property of {nameof(SpaOptions)} when calling {nameof(SpaApplicationBuilderExtensions.UseSpa)}."); - } - - ReactDevelopmentServerMiddleware.Attach(spaBuilder, npmScript); + DevelopmentServerMiddlewareExtensions.UseDevelopmentServer(spaBuilder, npmScript, "Starting the development server", "create-react-app"); } } } diff --git a/src/Middleware/SpaServices.Extensions/src/baseline.netcore.json b/src/Middleware/SpaServices.Extensions/src/baseline.netcore.json new file mode 100644 index 000000000000..0d7fb947d996 --- /dev/null +++ b/src/Middleware/SpaServices.Extensions/src/baseline.netcore.json @@ -0,0 +1,856 @@ +{ + "AssemblyIdentity": "Microsoft.AspNetCore.SpaServices.Extensions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.Extensions.DependencyInjection.SpaStaticFilesExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "AddSpaStaticFiles", + "Parameters": [ + { + "Name": "services", + "Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection" + }, + { + "Name": "configuration", + "Type": "System.Action", + "DefaultValue": "null" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "UseSpaStaticFiles", + "Parameters": [ + { + "Name": "applicationBuilder", + "Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "UseSpaStaticFiles", + "Parameters": [ + { + "Name": "applicationBuilder", + "Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder" + }, + { + "Name": "options", + "Type": "Microsoft.AspNetCore.Builder.StaticFileOptions" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Builder.SpaPrerenderingExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "UseSpaPrerendering", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + }, + { + "Name": "configuration", + "Type": "System.Action" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Builder.SpaPrerenderingOptions", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_BootModuleBuilder", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_BootModuleBuilder", + "Parameters": [ + { + "Name": "value", + "Type": "Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_BootModulePath", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_BootModulePath", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_ExcludeUrls", + "Parameters": [], + "ReturnType": "System.String[]", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_ExcludeUrls", + "Parameters": [ + { + "Name": "value", + "Type": "System.String[]" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_SupplyData", + "Parameters": [], + "ReturnType": "System.Action>", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_SupplyData", + "Parameters": [ + { + "Name": "value", + "Type": "System.Action>" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Builder.SpaProxyingExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "UseProxyToSpaDevelopmentServer", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + }, + { + "Name": "baseUri", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "UseProxyToSpaDevelopmentServer", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + }, + { + "Name": "baseUri", + "Type": "System.Uri" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "UseProxyToSpaDevelopmentServer", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + }, + { + "Name": "baseUriTaskFactory", + "Type": "System.Func>" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.Builder.SpaApplicationBuilderExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "UseSpa", + "Parameters": [ + { + "Name": "app", + "Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder" + }, + { + "Name": "configuration", + "Type": "System.Action" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.ISpaBuilder", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_ApplicationBuilder", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_Options", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.SpaServices.SpaOptions", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.SpaOptions", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_DefaultPage", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Http.PathString", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_DefaultPage", + "Parameters": [ + { + "Name": "value", + "Type": "Microsoft.AspNetCore.Http.PathString" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_DefaultPageStaticFileOptions", + "Parameters": [], + "ReturnType": "Microsoft.AspNetCore.Builder.StaticFileOptions", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_DefaultPageStaticFileOptions", + "Parameters": [ + { + "Name": "value", + "Type": "Microsoft.AspNetCore.Builder.StaticFileOptions" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_SourcePath", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_SourcePath", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "get_StartupTimeout", + "Parameters": [], + "ReturnType": "System.TimeSpan", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_StartupTimeout", + "Parameters": [ + { + "Name": "value", + "Type": "System.TimeSpan" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.StaticFiles.ISpaStaticFileProvider", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_FileProvider", + "Parameters": [], + "ReturnType": "Microsoft.Extensions.FileProviders.IFileProvider", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.StaticFiles.SpaStaticFilesOptions", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_RootPath", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "set_RootPath", + "Parameters": [ + { + "Name": "value", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.DevelopmentServer.DevelopmentServerMiddlewareExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "UseDevelopmentServer", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + }, + { + "Name": "npmScript", + "Type": "System.String" + }, + { + "Name": "waitText", + "Type": "System.String" + }, + { + "Name": "serverName", + "Type": "System.String" + }, + { + "Name": "extraArgs", + "Type": "System.Collections.Generic.IDictionary" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "UseReactDevelopmentServer", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + }, + { + "Name": "npmScript", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder", + "Visibility": "Public", + "Kind": "Interface", + "Abstract": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Build", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + } + ], + "ReturnType": "System.Threading.Tasks.Task", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliBuilder", + "Visibility": "Public", + "Kind": "Class", + "ImplementedInterfaces": [ + "Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder" + ], + "Members": [ + { + "Kind": "Method", + "Name": "Build", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + } + ], + "ReturnType": "System.Threading.Tasks.Task", + "Sealed": true, + "Virtual": true, + "ImplementedInterface": "Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder", + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "npmScript", + "Type": "System.String" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.SpaServices.AngularCli.AngularCliMiddlewareExtensions", + "Visibility": "Public", + "Kind": "Class", + "Abstract": true, + "Static": true, + "Sealed": true, + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "UseAngularCliServer", + "Parameters": [ + { + "Name": "spaBuilder", + "Type": "Microsoft.AspNetCore.SpaServices.ISpaBuilder" + }, + { + "Name": "npmScript", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Static": true, + "Extension": true, + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.NodeServices.Util.EventedStreamReader+OnReceivedChunkHandler", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "System.MulticastDelegate", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Invoke", + "Parameters": [ + { + "Name": "chunk", + "Type": "System.ArraySegment" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "BeginInvoke", + "Parameters": [ + { + "Name": "chunk", + "Type": "System.ArraySegment" + }, + { + "Name": "callback", + "Type": "System.AsyncCallback" + }, + { + "Name": "object", + "Type": "System.Object" + } + ], + "ReturnType": "System.IAsyncResult", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "EndInvoke", + "Parameters": [ + { + "Name": "result", + "Type": "System.IAsyncResult" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "object", + "Type": "System.Object" + }, + { + "Name": "method", + "Type": "System.IntPtr" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.NodeServices.Util.EventedStreamReader+OnReceivedLineHandler", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "System.MulticastDelegate", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Invoke", + "Parameters": [ + { + "Name": "line", + "Type": "System.String" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "BeginInvoke", + "Parameters": [ + { + "Name": "line", + "Type": "System.String" + }, + { + "Name": "callback", + "Type": "System.AsyncCallback" + }, + { + "Name": "object", + "Type": "System.Object" + } + ], + "ReturnType": "System.IAsyncResult", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "EndInvoke", + "Parameters": [ + { + "Name": "result", + "Type": "System.IAsyncResult" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "object", + "Type": "System.Object" + }, + { + "Name": "method", + "Type": "System.IntPtr" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + }, + { + "Name": "Microsoft.AspNetCore.NodeServices.Util.EventedStreamReader+OnStreamClosedHandler", + "Visibility": "Public", + "Kind": "Class", + "Sealed": true, + "BaseType": "System.MulticastDelegate", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "Invoke", + "Parameters": [], + "ReturnType": "System.Void", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "BeginInvoke", + "Parameters": [ + { + "Name": "callback", + "Type": "System.AsyncCallback" + }, + { + "Name": "object", + "Type": "System.Object" + } + ], + "ReturnType": "System.IAsyncResult", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "EndInvoke", + "Parameters": [ + { + "Name": "result", + "Type": "System.IAsyncResult" + } + ], + "ReturnType": "System.Void", + "Virtual": true, + "Visibility": "Public", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [ + { + "Name": "object", + "Type": "System.Object" + }, + { + "Name": "method", + "Type": "System.IntPtr" + } + ], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + } + ] +} diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs index 2303f02e1b0f..4a99e0af0a4c 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/Startup.cs @@ -10,7 +10,8 @@ #if (RequiresHttps) using Microsoft.AspNetCore.HttpsPolicy; #endif -using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.SpaServices.DevelopmentServer; #if (IndividualLocalAuth) using Microsoft.EntityFrameworkCore; using Company.WebApplication1.Data; diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/Startup.cs b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/Startup.cs index 620d39f9af98..84e1e140b679 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/Startup.cs +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/Startup.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.HttpsPolicy; #endif using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer; +using Microsoft.AspNetCore.SpaServices.DevelopmentServer; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting;