From fa39f489e1cedb1db761ea0a556f4981690c41d1 Mon Sep 17 00:00:00 2001 From: Thomas Hermann Date: Sat, 25 Mar 2017 18:23:27 -0400 Subject: [PATCH] Support V8 Inspector Integration for Node.js Addresses #796 --- .../HostingModels/OutOfProcessNodeInstance.cs | 37 ++++++++++--------- .../README.md | 31 ++++++++-------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs index f58374a5..dac718be 100644 --- a/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs +++ b/src/Microsoft.AspNetCore.NodeServices/HostingModels/OutOfProcessNodeInstance.cs @@ -27,16 +27,6 @@ public abstract class OutOfProcessNodeInstance : INodeInstance protected readonly ILogger OutputLogger; private const string ConnectionEstablishedMessage = "[Microsoft.AspNetCore.NodeServices:Listening]"; - private const string DebuggingStartedMessageFormat = @"----- -*** Node.js debugging is enabled *** -{0} - -To debug, run: - node-inspector{1} - -If you haven't yet installed node-inspector, you can do so as follows: - npm install -g node-inspector ------"; private readonly TaskCompletionSource _connectionIsReadySource = new TaskCompletionSource(); private bool _disposed; private readonly StringAsTempFile _entryPointScript; @@ -215,8 +205,8 @@ protected abstract Task InvokeExportAsync( /// The root path of the project. This is used when locating Node.js modules relative to the project root. /// Command-line arguments to be passed to the Node.js process. /// Environment variables to be set on the Node.js process. - /// If true, passes a flag to the Node.js process telling it to accept V8 debugger connections. - /// If debugging is enabled, the Node.js process should listen for V8 debugger connections on this port. + /// If true, passes a flag to the Node.js process telling it to accept V8 Inspector connections. + /// If debugging is enabled, the Node.js process should listen for V8 Inspector connections on this port. /// protected virtual ProcessStartInfo PrepareNodeProcessStartInfo( string entryPointFilename, string projectPath, string commandLineArguments, @@ -226,7 +216,7 @@ protected virtual ProcessStartInfo PrepareNodeProcessStartInfo( string debuggingArgs; if (launchWithDebugging) { - debuggingArgs = debuggingPort != default(int) ? $"--debug={debuggingPort} " : "--debug "; + debuggingArgs = debuggingPort != default(int) ? $"--inspect={debuggingPort} " : "--inspect "; _nodeDebuggingPort = debuggingPort; } else @@ -389,10 +379,13 @@ private void ConnectToInputOutputStreams() { if (evt.Data != null) { - if (IsDebuggerListeningMessage(evt.Data)) + if (IsDebuggerMessage(evt.Data)) { - var debugPortArg = _nodeDebuggingPort.HasValue ? $" --debug-port={_nodeDebuggingPort.Value}" : string.Empty; - OutputLogger.LogWarning(string.Format(DebuggingStartedMessageFormat, evt.Data, debugPortArg)); + OutputLogger.LogWarning(evt.Data); + } + else if (IsWarning(evt.Data)) + { + OutputLogger.LogWarning(evt.Data); } else if (!initializationIsCompleted) { @@ -411,9 +404,17 @@ private void ConnectToInputOutputStreams() _nodeProcess.BeginErrorReadLine(); } - private static bool IsDebuggerListeningMessage(string message) + private static bool IsDebuggerMessage(string message) + { + return message.StartsWith("Debugger attached", StringComparison.OrdinalIgnoreCase) || + message.StartsWith("Debugger listening ", StringComparison.OrdinalIgnoreCase) || + message.StartsWith("To start debugging", StringComparison.OrdinalIgnoreCase) || + message.Contains("chrome-devtools:"); + } + + private static bool IsWarning(string message) { - return message.StartsWith("Debugger listening ", StringComparison.OrdinalIgnoreCase); + return message.StartsWith("Warning:", StringComparison.OrdinalIgnoreCase); } private FileSystemWatcher BeginFileWatcher(string rootDir) diff --git a/src/Microsoft.AspNetCore.SpaServices/README.md b/src/Microsoft.AspNetCore.SpaServices/README.md index 43ffca21..df81509d 100644 --- a/src/Microsoft.AspNetCore.SpaServices/README.md +++ b/src/Microsoft.AspNetCore.SpaServices/README.md @@ -771,14 +771,14 @@ Caveats: ## Debugging your JavaScript/TypeScript code when it runs on the server -When you're using NodeServices or the server-side prerendering feature included in the project templates in this repo, your JavaScript/TypeScript code will execute on the server in a background instance of Node.js. You can enable debugging on that Node.js instance. Here's how to do it. +When you're using NodeServices or the server-side prerendering feature included in the project templates in this repo, your JavaScript/TypeScript code will execute on the server in a background instance of Node.js. You can enable debugging via [V8 Inspector Integration](https://nodejs.org/api/debugger.html#debugger_v8_inspector_integration_for_node_js) on that Node.js instance. Here's how to do it. First, in your `Startup.cs` file, in the `ConfigureServices` method, add the following: ``` services.AddNodeServices(options => { options.LaunchWithDebugging = true; - options.DebuggingPort = 5858; + options.DebuggingPort = 9229; }); ``` @@ -786,21 +786,20 @@ Now, run your application from that command line (e.g., `dotnet run`). Then in a In the console, you should see all the normal trace messages appear, plus among them will be: - ----- - *** Node.js debugging is enabled *** - Debugger listening on port 5858 - - To debug, run: - node-inspector - - If you haven't yet installed node-inspector, you can do so as follows: - npm install -g node-inspector - ----- +``` +warn: Microsoft.AspNetCore.NodeServices[0] + Debugger listening on port 9229. +warn: Microsoft.AspNetCore.NodeServices[0] + Warning: This is an experimental feature and could change at any time. +warn: Microsoft.AspNetCore.NodeServices[0] + To start debugging, open the following URL in Chrome: +warn: Microsoft.AspNetCore.NodeServices[0] + chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +``` -In some other command line window, follow those instructions (i.e., install `node-inspector` as it describes, then run `node-inspector`). Then you can open a browser at `http://127.0.0.1:8080/?port=5858` and you'll see the debugger UI. +As per instructions open the URL in Chrome. Alternatively you can go to the `Sources` tab of the Dev Tools (at http://localhost:5000) and connect to the Node instance under `Threads` in the right sidebar. -By expanding the `webpack://` entry in the sidebar, you'll be able to find your original TypeScript code (it's using source maps), and then set breakpoints in it. When you re-run your app in another browser window, your breakpoints will be hit, then you can debug the server-side execution just like you'd debug client-side execution. It looks like this: +By expanding the `webpack://` entry in the sidebar, you'll be able to find your original source code (it's using source maps), and then set breakpoints in it. When you re-run your app in another browser window, your breakpoints will be hit, then you can debug the server-side execution just like you'd debug client-side execution. It looks like this: -![screen shot 2016-07-26 at 18 56 12](https://cloud.githubusercontent.com/assets/1101362/17149317/a6f7d00c-5362-11e6-969c-4c3a9bbc33f7.png) +![screenshot from 2017-03-25 13-33-26](https://cloud.githubusercontent.com/assets/1596280/24324604/ab888a7e-115f-11e7-89d1-1586acf5e35c.png) -(Note: although this looks like Chrome's native debugger for client-side code, it is actually a JavaScript-powered debugger UI that's connected to the server-side runtime)