зеркало из https://github.com/dotnet/razor.git
Add support for launching debugging proxy from UI extension (#3013)
* Adds BlazorWasmCompanion extension * Updates debugging configuration to use companion extension
This commit is contained in:
Родитель
876f90e193
Коммит
f21b320a28
|
@ -0,0 +1,23 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.154.0/containers/dotnet/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] .NET version: 5.0, 3.1, 2.1
|
||||
ARG VARIANT="5.0"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/dotnetcore:0-${VARIANT}
|
||||
|
||||
# [Option] Install Node.js
|
||||
ARG INSTALL_NODE="true"
|
||||
ARG NODE_VERSION="lts/*"
|
||||
RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
|
||||
|
||||
# [Option] Install Azure CLI
|
||||
ARG INSTALL_AZURE_CLI="false"
|
||||
COPY library-scripts/azcli-debian.sh /tmp/library-scripts/
|
||||
RUN if [ "$INSTALL_AZURE_CLI" = "true" ]; then bash /tmp/library-scripts/azcli-debian.sh; fi \
|
||||
&& apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
||||
|
||||
# [Optional] Uncomment this line to install global node packages.
|
||||
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
|
|
@ -0,0 +1,58 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.154.0/containers/dotnet
|
||||
{
|
||||
"name": "C# (.NET)",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
"args": {
|
||||
// Update 'VARIANT' to pick a .NET Core version: 2.1, 3.1, 5.0
|
||||
"VARIANT": "5.0",
|
||||
// Options
|
||||
"INSTALL_NODE": "true",
|
||||
"NODE_VERSION": "lts/*",
|
||||
"INSTALL_AZURE_CLI": "false"
|
||||
}
|
||||
},
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-dotnettools.csharp"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [5000, 5001],
|
||||
|
||||
// [Optional] To reuse of your local HTTPS dev cert:
|
||||
//
|
||||
// 1. Export it locally using this command:
|
||||
// * Windows PowerShell:
|
||||
// dotnet dev-certs https --trust; dotnet dev-certs https -ep "$env:USERPROFILE/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere"
|
||||
// * macOS/Linux terminal:
|
||||
// dotnet dev-certs https --trust; dotnet dev-certs https -ep "${HOME}/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere"
|
||||
//
|
||||
// 2. Uncomment these 'remoteEnv' lines:
|
||||
// "remoteEnv": {
|
||||
// "ASPNETCORE_Kestrel__Certificates__Default__Password": "SecurePwdGoesHere",
|
||||
// "ASPNETCORE_Kestrel__Certificates__Default__Path": "/home/vscode/.aspnet/https/aspnetapp.pfx",
|
||||
// },
|
||||
//
|
||||
// 3. Do one of the following depending on your scenario:
|
||||
// * When using GitHub Codespaces and/or Remote - Containers:
|
||||
// 1. Start the container
|
||||
// 2. Drag ~/.aspnet/https/aspnetapp.pfx into the root of the file explorer
|
||||
// 3. Open a terminal in VS Code and run "mkdir -p /home/vscode/.aspnet/https && mv aspnetapp.pfx /home/vscode/.aspnet/https"
|
||||
//
|
||||
// * If only using Remote - Containers with a local container, uncomment this line instead:
|
||||
// "mounts": [ "source=${env:HOME}${env:USERPROFILE}/.aspnet/https,target=/home/vscode/.aspnet/https,type=bind" ],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "dotnet restore",
|
||||
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode"
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env bash
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/master/script-library/docs/azcli.md
|
||||
#
|
||||
# Syntax: ./azcli-debian.sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install curl, apt-transport-https, lsb-release, or gpg if missing
|
||||
if ! dpkg -s apt-transport-https curl ca-certificates lsb-release > /dev/null 2>&1 || ! type gpg > /dev/null 2>&1; then
|
||||
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
||||
apt-get update
|
||||
fi
|
||||
apt-get -y install --no-install-recommends apt-transport-https curl ca-certificates lsb-release gnupg2
|
||||
fi
|
||||
|
||||
# Install the Azure CLI
|
||||
echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list
|
||||
curl -sL https://packages.microsoft.com/keys/microsoft.asc | (OUT=$(apt-key add - 2>&1) || echo $OUT)
|
||||
apt-get update
|
||||
apt-get install -y azure-cli
|
||||
echo "Done!"
|
|
@ -152,3 +152,7 @@ src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Performance/BenchmarkDotNet.Arti
|
|||
yarn-*.log
|
||||
|
||||
*.svclog
|
||||
|
||||
# Bundled extension assets
|
||||
src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.BlazorWasmCompanionExtension/BlazorDebugProxy/*.dll
|
||||
src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.BlazorWasmCompanionExtension/BlazorDebugProxy/*.json
|
||||
|
|
|
@ -26,10 +26,12 @@
|
|||
"args": [
|
||||
"${workspaceFolder}/src/Razor/test/testapps/",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.Extension",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.BlazorWasmCompanionExtension",
|
||||
"--enable-proposed-api razor-vscode",
|
||||
"--enable-proposed-api ms-dotnettools.csharp"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.BlazorWasmCompanionExtension/dist/**/*.js",
|
||||
"${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.Extension/dist/**/*.js",
|
||||
"${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/dist/**/*.js",
|
||||
],
|
||||
|
|
|
@ -1,120 +1,137 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "CompileTextMate",
|
||||
"type": "npm",
|
||||
"script": "compile:TextMate",
|
||||
"problemMatcher": ["$eslint-stylish"],
|
||||
"options": {
|
||||
"cwd": "src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.Extension/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompilePackage",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompileLibrary",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "WatchLibraryAndCompileExtension",
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"options": {
|
||||
"cwd": "src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/"
|
||||
},
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"CompileExtension"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "CompileExtension",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.Extension/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"CompileLibrary"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "CompileUnitTests",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "src/Razor/test/Microsoft.AspNetCore.Razor.VSCode.Test/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompileGrammarTests",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "src/Razor/test/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompileFunctionalTest",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "src/Razor/test/VSCode.FunctionalTest/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"CompileExtension"
|
||||
]
|
||||
},
|
||||
]
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "CompileTextMate",
|
||||
"type": "npm",
|
||||
"script": "compile:TextMate",
|
||||
"problemMatcher": ["$eslint-stylish"],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.Extension/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompilePackage",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompileLibrary",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"ActivateDotnet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "ActivateDotnet",
|
||||
"type": "shell",
|
||||
"command": "source",
|
||||
"args": [
|
||||
"activate.sh"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "WatchLibraryAndCompileExtension",
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode/"
|
||||
},
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"CompileExtension"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "CompileExtension",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/src/Microsoft.AspNetCore.Razor.VSCode.Extension/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"CompileLibrary"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "CompileUnitTests",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/test/Microsoft.AspNetCore.Razor.VSCode.Test/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompileGrammarTests",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/test/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CompileFunctionalTest",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/src/Razor/test/VSCode.FunctionalTest/"
|
||||
},
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"CompileExtension"
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
.vscode/**
|
||||
.vscode-test/**
|
||||
out/test/**
|
||||
src/**
|
||||
.gitignore
|
||||
.yarnrc
|
||||
vsc-extension-quickstart.md
|
||||
**/tsconfig.json
|
||||
**/.eslintrc.json
|
||||
**/*.map
|
||||
**/*.ts
|
|
@ -0,0 +1 @@
|
|||
--ignore-engines true
|
|
@ -0,0 +1 @@
|
|||
This directory contains the assets for the BlazorDebugProxy that needs to be launched on a users machine.
|
|
@ -0,0 +1,29 @@
|
|||
# Microsoft.AspNetCore.Razor.VSCode.BlazorWasmCompanionExtension
|
||||
|
||||
**Warning:** This extension is indeed for use alongside the C# extension.
|
||||
|
||||
This directory contains the code for the Blazor WASM companion extension. This extension is designed to support remote debugging scenarios for Blazor WebAssembly.
|
||||
|
||||
Blazor WebAssembly runs in the browser via a .NET runtime running on WebAssembly. As a result, the traditional infrastructure that is used to debug .NET applications cannot be used for Blazor WASM. Instead, Blazor WASM leverages a debugging proxy that communicates with a web browser and IDE over the Chrome DevTools Protocol.
|
||||
|
||||
This debugging proxy is typically launched by the the Blazor development server wherever the Blazor server is running. This experience works fine for "local dev" scenarios where the developer is running their browser, the IDE, and the Blazor development server on the same machine.
|
||||
|
||||
In remote debugging scenarios, the browser, IDE, and Blazor server are running on different machines.
|
||||
|
||||
- The browser runs on the user's host machine.
|
||||
- The Blazor server and debugging proxy runs on the remote environment (Docker container, WSL, Codespaces)
|
||||
- VS Code runs in a dual-mode with some extension (UI extensions) running on the host machine and some extensions running on the remote machine (workspace extensions)
|
||||
|
||||
There's a problem here. The debugging proxy needs to talk to both VS Code and the browser but they run in different places. In particular, the debugging proxy cannot communicate with the browser from inside the remote machine.
|
||||
|
||||
To that end, we need a way to launch the debugging proxy on the user's host machine, where the browser is running. To achieve this, we developed a UI-only extension that runs on the VS Code UI (the same place as the users host) and is responsible for launching and killing a Blazor debugging proxy on the host machine.
|
||||
|
||||
### Publishing the extension
|
||||
|
||||
In order to publish the extension, you will need to have access to the `ms.dotnet-tools` publisher account on the VS Code marketplace. If you don't already have this access, reach out to @captainsafia for info.
|
||||
|
||||
This extension bundles the debugging proxy assets that are needed inside the `BlazorDebugProxy` directory. These assets are not committed to repository so they will need to be included as part of the publish process.
|
||||
|
||||
1. Download the desired version of the [Microsoft.AspNetCore.Components.WebAssembly.DevServer](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.DevServer/) package.
|
||||
2. Copy the contents of `tools/BlazorDebugProxy` into `BlazorDebugProxy/` in this directory.
|
||||
3. Package and publish the extension.
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "blazorwasm-companion",
|
||||
"displayName": "Microsoft.AspNetCore.Razor.VSCode.BlazorWasmCompanionExtension",
|
||||
"description": "A companion extnesion for debugging Blazor WebAssembly applications in VS Code. Must be installed alongside the C# extension.",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"vscode": "^1.52.0"
|
||||
},
|
||||
"dotnetRuntimeVersion": "5.0",
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"extensionKind": [
|
||||
"ui"
|
||||
],
|
||||
"publisher": "ms-dotnettools",
|
||||
"activationEvents": [
|
||||
"onCommand:blazorwasm-companion.launchDebugProxy",
|
||||
"onCommand:blazorwasm-companion.killDebugProxy"
|
||||
],
|
||||
"main": "./dist/extension.js",
|
||||
"extensionDependencies": [
|
||||
"ms-dotnettools.vscode-dotnet-runtime",
|
||||
"ms-dotnettools.csharp"
|
||||
],
|
||||
"files": [
|
||||
"BlazorDebugProxy/"
|
||||
],
|
||||
"contributes": {},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "yarn run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"pretest": "yarn run compile && yarn run lint",
|
||||
"lint": "eslint src --ext ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/glob": "^7.1.3",
|
||||
"@types/mocha": "^8.0.4",
|
||||
"@types/node": "^12.11.7",
|
||||
"@types/vscode": "^1.52.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.9.0",
|
||||
"@typescript-eslint/parser": "^4.9.0",
|
||||
"eslint": "^7.15.0",
|
||||
"glob": "^7.1.6",
|
||||
"mocha": "^8.1.3",
|
||||
"typescript": "^4.1.2",
|
||||
"vscode-test": "^1.4.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
interface IDotnetAcquireResult {
|
||||
dotnetPath: string;
|
||||
}
|
||||
|
||||
export async function acquireDotnetInstall(outputChannel: vscode.OutputChannel): Promise<string> {
|
||||
const extension = vscode.extensions.getExtension("ms-dotnettools.blazorwasm-companion");
|
||||
const version = extension && extension.packageJSON ? extension.packageJSON.dotnetRuntimeVersion : "5.0";
|
||||
const requestingExtensionId = "blazorwasm-companion";
|
||||
|
||||
try {
|
||||
const dotnetResult = await vscode.commands.executeCommand<IDotnetAcquireResult>('dotnet.acquire', { version, requestingExtensionId });
|
||||
const dotnetPath = dotnetResult?.dotnetPath;
|
||||
if (!dotnetPath) {
|
||||
throw new Error("Install step returned an undefined path.");
|
||||
}
|
||||
await vscode.commands.executeCommand('dotnet.ensureDotnetDependencies', { command: dotnetPath, arguments: "--info" });
|
||||
return dotnetPath;
|
||||
} catch (err) {
|
||||
const message = err.msg;
|
||||
outputChannel.appendLine(`This extension requires .NET Core to run but we were unable to install it due to the following error:`);
|
||||
outputChannel.appendLine(message);
|
||||
throw err;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { spawn } from 'child_process';
|
||||
import { acquireDotnetInstall } from './acquireDotnetInstall';
|
||||
import { getAvailablePort } from "./getAvailablePort";
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const outputChannel = vscode.window.createOutputChannel("Blazor WASM Debug Proxy");
|
||||
const pidsByUrl = new Map<string, number>();
|
||||
|
||||
const launchDebugProxy = vscode.commands.registerCommand('blazorwasm-companion.launchDebugProxy', async () => {
|
||||
try {
|
||||
const debuggingPort = await getAvailablePort(9222);
|
||||
const debuggingHost = `http://localhost:${debuggingPort}`;
|
||||
|
||||
const debugProxyLocalPath = `${context.extensionPath}/BlazorDebugProxy/BrowserDebugHost.dll`;
|
||||
const spawnedProxyArgs = [debugProxyLocalPath , '--DevToolsUrl', debuggingHost];
|
||||
|
||||
const dotnet = await acquireDotnetInstall(outputChannel);
|
||||
|
||||
outputChannel.appendLine(`Launching debugging proxy from ${debugProxyLocalPath}`);
|
||||
const spawnedProxy = spawn(dotnet, spawnedProxyArgs);
|
||||
|
||||
let chunksProcessed = 0;
|
||||
for await (const output of spawnedProxy.stdout) {
|
||||
// If we haven't found the URL in the first ten chunks processed
|
||||
// then bail out.
|
||||
if (chunksProcessed++ > 10) {
|
||||
return;
|
||||
}
|
||||
outputChannel.appendLine(output);
|
||||
// The debug proxy server outputs the port it is listening on in the
|
||||
// standard output of the launched application. We need to pass this URL
|
||||
// back to the debugger so we extract the URL from stdout using a regex.
|
||||
// The debug proxy will not exit until killed via the `killDebugProxy`
|
||||
// method so parsing stdout is necessary to extract the URL.
|
||||
const matchExpr = "Now listening on: (?<url>.*)";
|
||||
const found = `${output}`.match(matchExpr);
|
||||
const url = found?.groups?.url;
|
||||
if (url) {
|
||||
outputChannel.appendLine(`Debugging proxy is running at: ${url}`);
|
||||
pidsByUrl.set(url, spawnedProxy.pid);
|
||||
return {
|
||||
url,
|
||||
debuggingPort
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for await (const error of spawnedProxy.stderr) {
|
||||
outputChannel.appendLine(`ERROR: ${error}`);
|
||||
}
|
||||
|
||||
return;
|
||||
} catch (error) {
|
||||
outputChannel.appendLine(`ERROR: ${error}`);
|
||||
}
|
||||
});
|
||||
|
||||
const killDebugProxy = vscode.commands.registerCommand('blazorwasm-companion.killDebugProxy', (url: string) => {
|
||||
const pid = pidsByUrl.get(url);
|
||||
|
||||
if (!pid) {
|
||||
outputChannel.appendLine(`Unable to find PID for server running at ${url}...`);
|
||||
return;
|
||||
}
|
||||
|
||||
outputChannel.appendLine(`Terminating debug proxy server running at ${url} with PID ${pid}`);
|
||||
process.kill(pid);
|
||||
|
||||
});
|
||||
|
||||
context.subscriptions.push(launchDebugProxy, killDebugProxy);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as net from 'net';
|
||||
|
||||
export function getAvailablePort(initialPort: number) {
|
||||
function getNextAvailablePort(currentPort: number, cb: (port: number) => void) {
|
||||
const server = net.createServer();
|
||||
server.listen(currentPort, () => {
|
||||
server.once('close', () => {
|
||||
cb(currentPort);
|
||||
});
|
||||
server.close();
|
||||
});
|
||||
server.on('error', () => {
|
||||
if (currentPort <= 65535 /* total number of ports available */) {
|
||||
getNextAvailablePort(++currentPort, cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return new Promise<number>(resolve => {
|
||||
getNextAvailablePort(initialPort, resolve);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist"
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"extends": "../../tslint.json"
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -23,9 +23,18 @@ export class BlazorDebugConfigurationProvider implements vscode.DebugConfigurati
|
|||
await this.launchApp(folder, configuration);
|
||||
}
|
||||
|
||||
this.vscodeType.debug.onDidStartDebugSession(async event => {
|
||||
if (event.name === SERVER_APP_NAME) {
|
||||
await this.launchBrowser(folder, configuration, event);
|
||||
const result = await vscode.commands.executeCommand<{
|
||||
url: string,
|
||||
debuggingPort: number,
|
||||
} | undefined>('blazorwasm-companion.launchDebugProxy');
|
||||
if (result) {
|
||||
await this.launchBrowser(folder, configuration, result.url, result.debuggingPort);
|
||||
}
|
||||
|
||||
const terminateDebugProxy = this.vscodeType.debug.onDidTerminateDebugSession(async event => {
|
||||
if (event.name === JS_DEBUG_NAME || event.name === SERVER_APP_NAME) {
|
||||
await vscode.commands.executeCommand('blazorwasm-companion.killDebugProxy', result ? result.url : null);
|
||||
terminateDebugProxy.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -78,7 +87,8 @@ export class BlazorDebugConfigurationProvider implements vscode.DebugConfigurati
|
|||
}
|
||||
}
|
||||
|
||||
private async launchBrowser(folder: vscode.WorkspaceFolder | undefined, configuration: vscode.DebugConfiguration, parentSession?: vscode.DebugSession) {
|
||||
private async launchBrowser(folder: vscode.WorkspaceFolder | undefined, configuration: vscode.DebugConfiguration, wsAddress?: string, debuggingPort?: number) {
|
||||
const inspectUri = `${wsAddress}{browserInspectUriPath}`;
|
||||
const browser = {
|
||||
name: JS_DEBUG_NAME,
|
||||
type: configuration.browser === 'edge' ? 'pwa-msedge' : 'pwa-chrome',
|
||||
|
@ -86,9 +96,10 @@ export class BlazorDebugConfigurationProvider implements vscode.DebugConfigurati
|
|||
timeout: configuration.timeout || 30000,
|
||||
url: configuration.url || 'https://localhost:5001',
|
||||
webRoot: configuration.webRoot || '${workspaceFolder}',
|
||||
inspectUri: '{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}',
|
||||
inspectUri,
|
||||
trace: configuration.trace || false,
|
||||
noDebug: configuration.noDebug || false,
|
||||
port: debuggingPort,
|
||||
...configuration.browserConfig,
|
||||
};
|
||||
|
||||
|
@ -102,7 +113,7 @@ export class BlazorDebugConfigurationProvider implements vscode.DebugConfigurati
|
|||
* We do this to provide immediate visual feedback to the user
|
||||
* that their debugger session has started.
|
||||
*/
|
||||
await this.vscodeType.debug.startDebugging(folder, browser, parentSession);
|
||||
await this.vscodeType.debug.startDebugging(folder, browser);
|
||||
} catch (error) {
|
||||
this.logger.logError(
|
||||
'[DEBUGGER] Error when launching browser debugger: ',
|
||||
|
|
Загрузка…
Ссылка в новой задаче