mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
Add ability to configure environment variables for Node instances, plus auto-populate NODE_ENV based on IHostingEnvironment when possible. Fixes #230
This commit is contained in:
@@ -20,12 +20,15 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
{
|
{
|
||||||
// Since this instance is being created through DI, we can access the IHostingEnvironment
|
// Since this instance is being created through DI, we can access the IHostingEnvironment
|
||||||
// to populate options.ProjectPath if it wasn't explicitly specified.
|
// to populate options.ProjectPath if it wasn't explicitly specified.
|
||||||
|
var hostEnv = serviceProvider.GetRequiredService<IHostingEnvironment>();
|
||||||
if (string.IsNullOrEmpty(options.ProjectPath))
|
if (string.IsNullOrEmpty(options.ProjectPath))
|
||||||
{
|
{
|
||||||
var hostEnv = serviceProvider.GetRequiredService<IHostingEnvironment>();
|
|
||||||
options.ProjectPath = hostEnv.ContentRootPath;
|
options.ProjectPath = hostEnv.ContentRootPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Similarly, we can determine the 'is development' value from the hosting environment
|
||||||
|
options.AddDefaultEnvironmentVariables(hostEnv.IsDevelopment());
|
||||||
|
|
||||||
// Likewise, if no logger was specified explicitly, we should use the one from DI.
|
// Likewise, if no logger was specified explicitly, we should use the one from DI.
|
||||||
// If it doesn't provide one, CreateNodeInstance will set up a default.
|
// If it doesn't provide one, CreateNodeInstance will set up a default.
|
||||||
if (options.NodeInstanceOutputLogger == null)
|
if (options.NodeInstanceOutputLogger == null)
|
||||||
@@ -69,11 +72,11 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
{
|
{
|
||||||
case NodeHostingModel.Http:
|
case NodeHostingModel.Http:
|
||||||
return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, logger,
|
return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, logger,
|
||||||
options.LaunchWithDebugging, options.DebuggingPort, /* port */ 0);
|
options.EnvironmentVariables, options.LaunchWithDebugging, options.DebuggingPort, /* port */ 0);
|
||||||
case NodeHostingModel.Socket:
|
case NodeHostingModel.Socket:
|
||||||
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
|
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);
|
options.EnvironmentVariables, options.LaunchWithDebugging, options.DebuggingPort);
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unknown hosting model: " + options.HostingModel);
|
throw new ArgumentException("Unknown hosting model: " + options.HostingModel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -22,6 +23,23 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
public string[] WatchFileExtensions { get; set; }
|
public string[] WatchFileExtensions { get; set; }
|
||||||
public ILogger NodeInstanceOutputLogger { get; set; }
|
public ILogger NodeInstanceOutputLogger { get; set; }
|
||||||
public bool LaunchWithDebugging { get; set; }
|
public bool LaunchWithDebugging { get; set; }
|
||||||
|
public IDictionary<string, string> EnvironmentVariables { get; set; }
|
||||||
public int? DebuggingPort { get; set; }
|
public int? DebuggingPort { get; set; }
|
||||||
|
|
||||||
|
public NodeServicesOptions AddDefaultEnvironmentVariables(bool isDevelopmentMode)
|
||||||
|
{
|
||||||
|
if (EnvironmentVariables == null)
|
||||||
|
{
|
||||||
|
EnvironmentVariables = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EnvironmentVariables.ContainsKey("NODE_ENV"))
|
||||||
|
{
|
||||||
|
// These strings are a de-facto standard in Node
|
||||||
|
EnvironmentVariables["NODE_ENV"] = isDevelopmentMode ? "development" : "production";
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -34,7 +35,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
private int _portNumber;
|
private int _portNumber;
|
||||||
|
|
||||||
public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger,
|
public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger,
|
||||||
bool launchWithDebugging, int? debuggingPort, int port = 0)
|
IDictionary<string, string> environmentVars, bool launchWithDebugging, int? debuggingPort, int port = 0)
|
||||||
: base(
|
: base(
|
||||||
EmbeddedResourceReader.Read(
|
EmbeddedResourceReader.Read(
|
||||||
typeof(HttpNodeInstance),
|
typeof(HttpNodeInstance),
|
||||||
@@ -43,6 +44,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
watchFileExtensions,
|
watchFileExtensions,
|
||||||
MakeCommandLineOptions(port),
|
MakeCommandLineOptions(port),
|
||||||
nodeInstanceOutputLogger,
|
nodeInstanceOutputLogger,
|
||||||
|
environmentVars,
|
||||||
launchWithDebugging,
|
launchWithDebugging,
|
||||||
debuggingPort)
|
debuggingPort)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -46,6 +47,7 @@ If you haven't yet installed node-inspector, you can do so as follows:
|
|||||||
string[] watchFileExtensions,
|
string[] watchFileExtensions,
|
||||||
string commandLineArguments,
|
string commandLineArguments,
|
||||||
ILogger nodeOutputLogger,
|
ILogger nodeOutputLogger,
|
||||||
|
IDictionary<string, string> environmentVars,
|
||||||
bool launchWithDebugging,
|
bool launchWithDebugging,
|
||||||
int? debuggingPort)
|
int? debuggingPort)
|
||||||
{
|
{
|
||||||
@@ -58,7 +60,7 @@ If you haven't yet installed node-inspector, you can do so as follows:
|
|||||||
_entryPointScript = new StringAsTempFile(entryPointScript);
|
_entryPointScript = new StringAsTempFile(entryPointScript);
|
||||||
|
|
||||||
var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments,
|
var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments,
|
||||||
launchWithDebugging, debuggingPort);
|
environmentVars, launchWithDebugging, debuggingPort);
|
||||||
_nodeProcess = LaunchNodeProcess(startInfo);
|
_nodeProcess = LaunchNodeProcess(startInfo);
|
||||||
_watchFileExtensions = watchFileExtensions;
|
_watchFileExtensions = watchFileExtensions;
|
||||||
_fileSystemWatcher = BeginFileWatcher(projectPath);
|
_fileSystemWatcher = BeginFileWatcher(projectPath);
|
||||||
@@ -99,7 +101,7 @@ If you haven't yet installed node-inspector, you can do so as follows:
|
|||||||
// This method is virtual, as it provides a way to override the NODE_PATH or the path to node.exe
|
// This method is virtual, as it provides a way to override the NODE_PATH or the path to node.exe
|
||||||
protected virtual ProcessStartInfo PrepareNodeProcessStartInfo(
|
protected virtual ProcessStartInfo PrepareNodeProcessStartInfo(
|
||||||
string entryPointFilename, string projectPath, string commandLineArguments,
|
string entryPointFilename, string projectPath, string commandLineArguments,
|
||||||
bool launchWithDebugging, int? debuggingPort)
|
IDictionary<string, string> environmentVars, bool launchWithDebugging, int? debuggingPort)
|
||||||
{
|
{
|
||||||
string debuggingArgs;
|
string debuggingArgs;
|
||||||
if (launchWithDebugging)
|
if (launchWithDebugging)
|
||||||
@@ -122,6 +124,19 @@ If you haven't yet installed node-inspector, you can do so as follows:
|
|||||||
WorkingDirectory = projectPath
|
WorkingDirectory = projectPath
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Append environment vars
|
||||||
|
if (environmentVars != null)
|
||||||
|
{
|
||||||
|
foreach (var envVarKey in environmentVars.Keys)
|
||||||
|
{
|
||||||
|
var envVarValue = environmentVars[envVarKey];
|
||||||
|
if (envVarValue != null)
|
||||||
|
{
|
||||||
|
SetEnvironmentVariable(startInfo, envVarKey, envVarValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Append projectPath to NODE_PATH so it can locate node_modules
|
// Append projectPath to NODE_PATH so it can locate node_modules
|
||||||
var existingNodePath = Environment.GetEnvironmentVariable("NODE_PATH") ?? string.Empty;
|
var existingNodePath = Environment.GetEnvironmentVariable("NODE_PATH") ?? string.Empty;
|
||||||
if (existingNodePath != string.Empty)
|
if (existingNodePath != string.Empty)
|
||||||
@@ -130,11 +145,7 @@ If you haven't yet installed node-inspector, you can do so as follows:
|
|||||||
}
|
}
|
||||||
|
|
||||||
var nodePathValue = existingNodePath + Path.Combine(projectPath, "node_modules");
|
var nodePathValue = existingNodePath + Path.Combine(projectPath, "node_modules");
|
||||||
#if NET451
|
SetEnvironmentVariable(startInfo, "NODE_PATH", nodePathValue);
|
||||||
startInfo.EnvironmentVariables["NODE_PATH"] = nodePathValue;
|
|
||||||
#else
|
|
||||||
startInfo.Environment["NODE_PATH"] = nodePathValue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return startInfo;
|
return startInfo;
|
||||||
}
|
}
|
||||||
@@ -179,6 +190,15 @@ If you haven't yet installed node-inspector, you can do so as follows:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void SetEnvironmentVariable(ProcessStartInfo startInfo, string name, string value)
|
||||||
|
{
|
||||||
|
#if NET451
|
||||||
|
startInfo.EnvironmentVariables[name] = value;
|
||||||
|
#else
|
||||||
|
startInfo.Environment[name] = value;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
private static Process LaunchNodeProcess(ProcessStartInfo startInfo)
|
private static Process LaunchNodeProcess(ProcessStartInfo startInfo)
|
||||||
{
|
{
|
||||||
var process = Process.Start(startInfo);
|
var process = Process.Start(startInfo);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -38,7 +39,8 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
private VirtualConnectionClient _virtualConnectionClient;
|
private VirtualConnectionClient _virtualConnectionClient;
|
||||||
|
|
||||||
public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress,
|
public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress,
|
||||||
ILogger nodeInstanceOutputLogger, bool launchWithDebugging, int? debuggingPort)
|
ILogger nodeInstanceOutputLogger, IDictionary<string, string> environmentVars,
|
||||||
|
bool launchWithDebugging, int? debuggingPort)
|
||||||
: base(
|
: base(
|
||||||
EmbeddedResourceReader.Read(
|
EmbeddedResourceReader.Read(
|
||||||
typeof(SocketNodeInstance),
|
typeof(SocketNodeInstance),
|
||||||
@@ -47,6 +49,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
watchFileExtensions,
|
watchFileExtensions,
|
||||||
MakeNewCommandLineOptions(socketAddress),
|
MakeNewCommandLineOptions(socketAddress),
|
||||||
nodeInstanceOutputLogger,
|
nodeInstanceOutputLogger,
|
||||||
|
environmentVars,
|
||||||
launchWithDebugging,
|
launchWithDebugging,
|
||||||
debuggingPort)
|
debuggingPort)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
|
|||||||
_nodeServices = _fallbackNodeServices = Configuration.CreateNodeServices(new NodeServicesOptions
|
_nodeServices = _fallbackNodeServices = Configuration.CreateNodeServices(new NodeServicesOptions
|
||||||
{
|
{
|
||||||
ProjectPath = _applicationBasePath
|
ProjectPath = _applicationBasePath
|
||||||
});
|
}.AddDefaultEnvironmentVariables(hostEnv.IsDevelopment()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,16 +35,8 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
"To enable ReactHotModuleReplacement, you must also enable HotModuleReplacement.");
|
"To enable ReactHotModuleReplacement, you must also enable HotModuleReplacement.");
|
||||||
}
|
}
|
||||||
|
|
||||||
string projectPath;
|
var hostEnv = (IHostingEnvironment)appBuilder.ApplicationServices.GetService(typeof(IHostingEnvironment));
|
||||||
if (options.ProjectPath == null)
|
var projectPath = options.ProjectPath ?? hostEnv.ContentRootPath;
|
||||||
{
|
|
||||||
var hostEnv = (IHostingEnvironment)appBuilder.ApplicationServices.GetService(typeof(IHostingEnvironment));
|
|
||||||
projectPath = hostEnv.ContentRootPath;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
projectPath = options.ProjectPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlike other consumers of NodeServices, WebpackDevMiddleware dosen't share Node instances, nor does it
|
// Unlike other consumers of NodeServices, WebpackDevMiddleware dosen't share Node instances, nor does it
|
||||||
// use your DI configuration. It's important for WebpackDevMiddleware to have its own private Node instance
|
// use your DI configuration. It's important for WebpackDevMiddleware to have its own private Node instance
|
||||||
@@ -55,7 +47,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
{
|
{
|
||||||
ProjectPath = projectPath,
|
ProjectPath = projectPath,
|
||||||
WatchFileExtensions = new string[] { } // Don't watch anything
|
WatchFileExtensions = new string[] { } // Don't watch anything
|
||||||
});
|
}.AddDefaultEnvironmentVariables(hostEnv.IsDevelopment()));
|
||||||
|
|
||||||
// Get a filename matching the middleware Node script
|
// Get a filename matching the middleware Node script
|
||||||
var script = EmbeddedResourceReader.Read(typeof(WebpackDevMiddleware),
|
var script = EmbeddedResourceReader.Read(typeof(WebpackDevMiddleware),
|
||||||
|
|||||||
Reference in New Issue
Block a user