diff --git a/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs b/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs index a4a747b41f..21b8ee4e9f 100644 --- a/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs +++ b/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs @@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.SpaServices public Microsoft.AspNetCore.Builder.StaticFileOptions DefaultPageStaticFileOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string PackageManagerCommand { get { throw null; } set { } } public string SourcePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int DevServerPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.TimeSpan StartupTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs index a852cc37fa..ede248601d 100644 --- a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs +++ b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs @@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli { var pkgManagerCommand = spaBuilder.Options.PackageManagerCommand; var sourcePath = spaBuilder.Options.SourcePath; + var devServerPort = spaBuilder.Options.DevServerPort; if (string.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("Cannot be null or empty", nameof(sourcePath)); @@ -40,7 +41,7 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli // Start Angular CLI and attach to middleware pipeline var appBuilder = spaBuilder.ApplicationBuilder; var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName); - var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, scriptName, pkgManagerCommand, logger); + var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, scriptName, pkgManagerCommand, devServerPort, logger); // Everything we proxy is hardcoded to target http://localhost because: // - the requests are always from the local machine (we're not accepting remote @@ -63,9 +64,12 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli } private static async Task StartAngularCliServerAsync( - string sourcePath, string scriptName, string pkgManagerCommand, ILogger logger) + string sourcePath, string scriptName, string pkgManagerCommand, int portNumber, ILogger logger) { - var portNumber = TcpPortFinder.FindAvailablePort(); + if (portNumber == default(int)) + { + portNumber = TcpPortFinder.FindAvailablePort(); + } logger.LogInformation($"Starting @angular/cli on port {portNumber}..."); var scriptRunner = new NodeScriptRunner( diff --git a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs index 6566fef706..b4cb361b54 100644 --- a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs +++ b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs @@ -26,6 +26,7 @@ namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer { var pkgManagerCommand = spaBuilder.Options.PackageManagerCommand; var sourcePath = spaBuilder.Options.SourcePath; + var devServerPort = spaBuilder.Options.DevServerPort; if (string.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("Cannot be null or empty", nameof(sourcePath)); @@ -39,7 +40,7 @@ namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer // Start create-react-app and attach to middleware pipeline var appBuilder = spaBuilder.ApplicationBuilder; var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName); - var portTask = StartCreateReactAppServerAsync(sourcePath, scriptName, pkgManagerCommand, logger); + var portTask = StartCreateReactAppServerAsync(sourcePath, scriptName, pkgManagerCommand, devServerPort, logger); // Everything we proxy is hardcoded to target http://localhost because: // - the requests are always from the local machine (we're not accepting remote @@ -62,9 +63,12 @@ namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer } private static async Task StartCreateReactAppServerAsync( - string sourcePath, string scriptName, string pkgManagerCommand, ILogger logger) + string sourcePath, string scriptName, string pkgManagerCommand, int portNumber, ILogger logger) { - var portNumber = TcpPortFinder.FindAvailablePort(); + if (portNumber == default(int)) + { + portNumber = TcpPortFinder.FindAvailablePort(); + } logger.LogInformation($"Starting create-react-app server on port {portNumber}..."); var envVars = new Dictionary diff --git a/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs b/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs index 59ccc1eda4..3b7f4f1a71 100644 --- a/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs +++ b/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs @@ -33,6 +33,7 @@ namespace Microsoft.AspNetCore.SpaServices _packageManagerCommand = copyFromOptions.PackageManagerCommand; DefaultPageStaticFileOptions = copyFromOptions.DefaultPageStaticFileOptions; SourcePath = copyFromOptions.SourcePath; + DevServerPort = copyFromOptions.DevServerPort; } /// @@ -70,6 +71,11 @@ namespace Microsoft.AspNetCore.SpaServices /// public string SourcePath { get; set; } + /// + /// Controls wether the development server should be used with a dynamic or fixed port. + /// + public int DevServerPort { get; set; } = default(int); + /// /// Gets or sets the name of the package manager executible, (e.g npm, /// yarn) to run the SPA.