Jelajahi Sumber

Merge pull request #16599 from flensrocker/issue-16582

Allow the Angular/React-DevServer to run on a given port (#16582)
Ryan Brandenburg 6 tahun lalu
induk
melakukan
7202634cea

+ 1 - 0
src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs

@@ -41,6 +41,7 @@ namespace Microsoft.AspNetCore.SpaServices
         public SpaOptions() { }
         public Microsoft.AspNetCore.Http.PathString DefaultPage { get { throw null; } set { } }
         public Microsoft.AspNetCore.Builder.StaticFileOptions DefaultPageStaticFileOptions { [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 string PackageManagerCommand { get { throw null; } set { } }
         public string SourcePath { [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 { } }

+ 7 - 3
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<AngularCliServerInfo> 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(

+ 7 - 3
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<int> 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<string, string>

+ 6 - 0
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;
         }
 
         /// <summary>
@@ -70,6 +71,11 @@ namespace Microsoft.AspNetCore.SpaServices
         /// </summary>
         public string SourcePath { get; set; }
 
+        /// <summary>
+        /// Controls wether the development server should be used with a dynamic or fixed port.
+        /// </summary>
+        public int DevServerPort { get; set; } = default(int);
+
         /// <summary>
         /// Gets or sets the name of the package manager executible, (e.g npm,
         /// yarn) to run the SPA.