Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Commit f2f67fe

Browse files
Support new config options to launch the Node process with a debug listener. This is compatible with node-inspector.
1 parent 79872c1 commit f2f67fe

File tree

5 files changed

+60
-13
lines changed

5 files changed

+60
-13
lines changed

src/Microsoft.AspNetCore.NodeServices/Configuration/Configuration.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ private static INodeInstance CreateNodeInstance(NodeServicesOptions options)
6868
switch (options.HostingModel)
6969
{
7070
case NodeHostingModel.Http:
71-
return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, logger, /* port */ 0);
71+
return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, logger,
72+
options.LaunchWithDebugging, options.DebuggingPort, /* port */ 0);
7273
case NodeHostingModel.Socket:
7374
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
74-
return new SocketNodeInstance(options.ProjectPath, options.WatchFileExtensions, pipeName, logger);
75+
return new SocketNodeInstance(options.ProjectPath, options.WatchFileExtensions, pipeName, logger,
76+
options.LaunchWithDebugging, options.DebuggingPort);
7577
default:
7678
throw new ArgumentException("Unknown hosting model: " + options.HostingModel);
7779
}

src/Microsoft.AspNetCore.NodeServices/Configuration/NodeServicesOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,7 @@ public NodeServicesOptions()
2121
public string ProjectPath { get; set; }
2222
public string[] WatchFileExtensions { get; set; }
2323
public ILogger NodeInstanceOutputLogger { get; set; }
24+
public bool LaunchWithDebugging { get; set; }
25+
public int? DebuggingPort { get; set; }
2426
}
2527
}

src/Microsoft.AspNetCore.NodeServices/HostingModels/HttpNodeInstance.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,18 @@ internal class HttpNodeInstance : OutOfProcessNodeInstance
3333
private bool _disposed;
3434
private int _portNumber;
3535

36-
public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger, int port = 0)
37-
: base(
36+
public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger,
37+
bool launchWithDebugging, int? debuggingPort, int port = 0)
38+
: base(
3839
EmbeddedResourceReader.Read(
3940
typeof(HttpNodeInstance),
4041
"/Content/Node/entrypoint-http.js"),
4142
projectPath,
4243
watchFileExtensions,
4344
MakeCommandLineOptions(port),
44-
nodeInstanceOutputLogger)
45+
nodeInstanceOutputLogger,
46+
launchWithDebugging,
47+
debuggingPort)
4548
{
4649
_client = new HttpClient();
4750
}

src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,22 @@ public abstract class OutOfProcessNodeInstance : INodeInstance
2121
{
2222
protected readonly ILogger OutputLogger;
2323
private const string ConnectionEstablishedMessage = "[Microsoft.AspNetCore.NodeServices:Listening]";
24+
private const string DebuggingStartedMessageFormat = @"-----
25+
*** Node.js debugging is enabled ***
26+
{0}
27+
28+
To debug, run:
29+
node-inspector{1}
30+
31+
If you haven't yet installed node-inspector, you can do so as follows:
32+
npm install -g node-inspector
33+
-----";
2434
private readonly TaskCompletionSource<object> _connectionIsReadySource = new TaskCompletionSource<object>();
2535
private bool _disposed;
2636
private readonly StringAsTempFile _entryPointScript;
2737
private FileSystemWatcher _fileSystemWatcher;
2838
private readonly Process _nodeProcess;
39+
private int? _nodeDebuggingPort;
2940
private bool _nodeProcessNeedsRestart;
3041
private readonly string[] _watchFileExtensions;
3142

@@ -34,7 +45,9 @@ public OutOfProcessNodeInstance(
3445
string projectPath,
3546
string[] watchFileExtensions,
3647
string commandLineArguments,
37-
ILogger nodeOutputLogger)
48+
ILogger nodeOutputLogger,
49+
bool launchWithDebugging,
50+
int? debuggingPort)
3851
{
3952
if (nodeOutputLogger == null)
4053
{
@@ -43,8 +56,9 @@ public OutOfProcessNodeInstance(
4356

4457
OutputLogger = nodeOutputLogger;
4558
_entryPointScript = new StringAsTempFile(entryPointScript);
46-
47-
var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments);
59+
60+
var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments,
61+
launchWithDebugging, debuggingPort);
4862
_nodeProcess = LaunchNodeProcess(startInfo);
4963
_watchFileExtensions = watchFileExtensions;
5064
_fileSystemWatcher = BeginFileWatcher(projectPath);
@@ -84,11 +98,23 @@ public void Dispose()
8498

8599
// This method is virtual, as it provides a way to override the NODE_PATH or the path to node.exe
86100
protected virtual ProcessStartInfo PrepareNodeProcessStartInfo(
87-
string entryPointFilename, string projectPath, string commandLineArguments)
101+
string entryPointFilename, string projectPath, string commandLineArguments,
102+
bool launchWithDebugging, int? debuggingPort)
88103
{
104+
string debuggingArgs;
105+
if (launchWithDebugging)
106+
{
107+
debuggingArgs = debuggingPort.HasValue ? $"--debug={debuggingPort.Value} " : "--debug ";
108+
_nodeDebuggingPort = debuggingPort;
109+
}
110+
else
111+
{
112+
debuggingArgs = string.Empty;
113+
}
114+
89115
var startInfo = new ProcessStartInfo("node")
90116
{
91-
Arguments = "\"" + entryPointFilename + "\" " + (commandLineArguments ?? string.Empty),
117+
Arguments = debuggingArgs + "\"" + entryPointFilename + "\" " + (commandLineArguments ?? string.Empty),
92118
UseShellExecute = false,
93119
RedirectStandardInput = true,
94120
RedirectStandardOutput = true,
@@ -201,7 +227,12 @@ private void ConnectToInputOutputStreams()
201227
{
202228
if (evt.Data != null)
203229
{
204-
if (!initializationIsCompleted)
230+
if (IsDebuggerListeningMessage(evt.Data))
231+
{
232+
var debugPortArg = _nodeDebuggingPort.HasValue ? $" --debug-port={_nodeDebuggingPort.Value}" : string.Empty;
233+
OutputLogger.LogWarning(string.Format(DebuggingStartedMessageFormat, evt.Data, debugPortArg));
234+
}
235+
else if (!initializationIsCompleted)
205236
{
206237
_connectionIsReadySource.SetException(
207238
new InvalidOperationException("The Node.js process failed to initialize: " + evt.Data));
@@ -218,6 +249,11 @@ private void ConnectToInputOutputStreams()
218249
_nodeProcess.BeginErrorReadLine();
219250
}
220251

252+
private static bool IsDebuggerListeningMessage(string message)
253+
{
254+
return message.StartsWith("Debugger listening on port ", StringComparison.OrdinalIgnoreCase);
255+
}
256+
221257
private FileSystemWatcher BeginFileWatcher(string rootDir)
222258
{
223259
if (_watchFileExtensions == null || _watchFileExtensions.Length == 0)

src/Microsoft.AspNetCore.NodeServices/HostingModels/SocketNodeInstance.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,18 @@ internal class SocketNodeInstance : OutOfProcessNodeInstance
3737
private string _socketAddress;
3838
private VirtualConnectionClient _virtualConnectionClient;
3939

40-
public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress, ILogger nodeInstanceOutputLogger) : base(
40+
public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress,
41+
ILogger nodeInstanceOutputLogger, bool launchWithDebugging, int? debuggingPort)
42+
: base(
4143
EmbeddedResourceReader.Read(
4244
typeof(SocketNodeInstance),
4345
"/Content/Node/entrypoint-socket.js"),
4446
projectPath,
4547
watchFileExtensions,
4648
MakeNewCommandLineOptions(socketAddress),
47-
nodeInstanceOutputLogger)
49+
nodeInstanceOutputLogger,
50+
launchWithDebugging,
51+
debuggingPort)
4852
{
4953
_socketAddress = socketAddress;
5054
}

0 commit comments

Comments
 (0)