Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 5.6k
[browser] Integrate DevServer into WasmAppHost#88985
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
54d2152
Copy dev server from blazor
maraf 55cac05
Add target path
maraf b9697d9
Merge remote-tracking branch 'upstream/main' into WasmBrowserHost
maraf af5bfd3
Add debugging. Copy pattern from WebServer
maraf 9901130
Use DevServer when SWA manifest exists
maraf 0c64fb7
Target path is not needed
maraf 8e7d010
Namespace for DevServer classes
maraf 819bd54
Make HTMLPath optional
maraf dd8531e
Merge remote-tracking branch 'upstream/main' into WasmBrowserHost
maraf 5e2ea4b
Runtimeconfig template
maraf 7ae7a4b
WIP
maraf d4b55a2
Merge remote-tracking branch 'upstream/main' into WasmBrowserHost
maraf 56bc2e3
DevServer without MainAssembly by scanning for swa manifest in file s…
maraf df4d5fa
Set run command and arguments in WasmSDK
maraf 38019bb
Include WasmAppHost in Wasm SDK pack
maraf 404797c
Use dotnet run in TestAppScenarios
maraf b66ae38
Workaround for GenerateRuntimeConfigurationFiles
maraf 3d6a3ed
Feedback
maraf 09212f1
Load BrowserDebugHost from "current folder"
maraf 29f442c
Feedback from @radical
maraf d0d85cf
Merge remote-tracking branch 'upstream/main' into WasmBrowserHost
maraf ec957e4
Merge remote-tracking branch 'upstream/main' into WasmBrowserHost
maraf ea68a69
Use separate argument to pick devserver
maraf d142f65
Add message about debugger
maraf 4694490
Remove ForPublish from tests
maraf 0923728
Remove GenerateRuntimeConfigurationFiles=false from SDK and GenerateR…
maraf ea8f894
Unify message for debugger on https
maraf 010cb1f
Merge remote-tracking branch 'upstream/main' into WasmBrowserHost
maraf 659adae
UseStaticWebAssets should default to false
maraf File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12 src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/Microsoft.NET.Sdk.WebAssembly.Pack.pkgproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 13 additions & 1 deletion
14 ...et/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1 src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppSettingsTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 2 additions & 3 deletions
5 src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/AppTestBase.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1 src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DownloadResourceProgressTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 1 addition & 2 deletions
3 src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LazyLoadingTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 1 addition & 2 deletions
3 src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/LibraryInitializerTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 1 addition & 2 deletions
3 src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -4,6 +4,7 @@ | ||
| #nullable enable | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Text.Json; | ||
| using Mono.Options; | ||
| @@ -37,8 +38,8 @@ public void ParseJsonProperties(IDictionary<string, JsonElement>? properties) | ||
| ForwardConsoleOutput = forwardConsoleElement.GetBoolean(); | ||
| } | ||
| [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Needs to validate instance members")] | ||
| public void Validate() | ||
| { | ||
| CommonConfiguration.CheckPathOrInAppPath(CommonConfig.AppPath, HTMLPath, "html-path"); | ||
maraf marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -4,14 +4,17 @@ | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using System.Net.WebSockets; | ||
| using System.Text; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using System.Web; | ||
| using Microsoft.AspNetCore.Hosting; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.WebAssembly.AppHost.DevServer; | ||
| using Microsoft.WebAssembly.Diagnostics; | ||
| #nullable enable | ||
| @@ -44,7 +47,7 @@ public static async Task<int> InvokeAsync(CommonConfiguration commonArgs, | ||
| private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken token) | ||
| { | ||
| if (_args.CommonConfig.Debugging) | ||
| if (_args.CommonConfig.Debugging && !_args.CommonConfig.UseStaticWebAssets) | ||
| { | ||
| ProxyOptions options = _args.CommonConfig.ToProxyOptions(); | ||
| _ = Task.Run(() => DebugProxyHost.RunDebugProxyAsync(options, Array.Empty<string>(), loggerFactory, token), token) | ||
| @@ -75,8 +78,7 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke | ||
| ? aspnetUrls.Split(';', StringSplitOptions.RemoveEmptyEntries) | ||
| : new string[] { $"http://127.0.0.1:{_args.CommonConfig.HostProperties.WebServerPort}", "https://127.0.0.1:0" }; | ||
| (ServerURLs serverURLs, IWebHost host) = await StartWebServerAsync(_args.CommonConfig.AppPath, | ||
| _args.ForwardConsoleOutput ?? false, | ||
| (ServerURLs serverURLs, IWebHost host) = await StartWebServerAsync(_args, | ||
| urls, | ||
| token); | ||
| @@ -85,32 +87,104 @@ private async Task RunAsync(ILoggerFactory loggerFactory, CancellationToken toke | ||
| foreach (string url in fullUrls) | ||
| Console.WriteLine($"App url: {url}"); | ||
| if (serverURLs.DebugPath != null) | ||
| { | ||
| Console.WriteLine($"Debug at url: {BuildUrl(serverURLs.Http, serverURLs.DebugPath, string.Empty)}"); | ||
| if (serverURLs.Https != null) | ||
| Console.WriteLine($"Debug at url: {BuildUrl(serverURLs.Https, serverURLs.DebugPath, string.Empty)}"); | ||
| } | ||
| await host.WaitForShutdownAsync(token); | ||
| } | ||
| private async Task<(ServerURLs, IWebHost)> StartWebServerAsync(string appPath, bool forwardConsole, string[] urls, CancellationToken token) | ||
| private async Task<(ServerURLs, IWebHost)> StartWebServerAsync(BrowserArguments args, string[] urls, CancellationToken token) | ||
| { | ||
| WasmTestMessagesProcessor? logProcessor = null; | ||
| if (forwardConsole) | ||
| Func<WebSocket, Task>? onConsoleConnected = null; | ||
| if (args.ForwardConsoleOutput ?? false) | ||
| { | ||
| logProcessor = new(_logger); | ||
| WasmTestMessagesProcessor logProcessor = new(_logger); | ||
| onConsoleConnected = socket => RunConsoleMessagesPump(socket, logProcessor!, token); | ||
| } | ||
| WebServerOptions options = new | ||
| ( | ||
| OnConsoleConnected: forwardConsole | ||
| ? socket => RunConsoleMessagesPump(socket, logProcessor!, token) | ||
| : null, | ||
| ContentRootPath: Path.GetFullPath(appPath), | ||
| WebServerUseCors: true, | ||
| WebServerUseCrossOriginPolicy: true, | ||
| Urls: urls | ||
| ); | ||
| (ServerURLs serverURLs, IWebHost host) = await WebServer.StartAsync(options, _logger, token); | ||
| return (serverURLs, host); | ||
| // If we are using new browser template, use dev server | ||
| if (args.CommonConfig.UseStaticWebAssets) | ||
| { | ||
| DevServerOptions devServerOptions = CreateDevServerOptions(args, urls, onConsoleConnected); | ||
| return await DevServer.DevServer.StartAsync(devServerOptions, _logger, token); | ||
| } | ||
| // Otherwise for old template, use web server | ||
| WebServerOptions webServerOptions = CreateWebServerOptions(urls, args.CommonConfig.AppPath, onConsoleConnected); | ||
| return await WebServer.StartAsync(webServerOptions, _logger, token); | ||
| } | ||
| private static WebServerOptions CreateWebServerOptions(string[] urls, string appPath, Func<WebSocket, Task>? onConsoleConnected) => new | ||
| ( | ||
| OnConsoleConnected: onConsoleConnected, | ||
| ContentRootPath: Path.GetFullPath(appPath), | ||
| WebServerUseCors: true, | ||
| WebServerUseCrossOriginPolicy: true, | ||
| Urls: urls | ||
| ); | ||
| private static DevServerOptions CreateDevServerOptions(BrowserArguments args, string[] urls, Func<WebSocket, Task>? onConsoleConnected) | ||
| { | ||
| const string staticWebAssetsV1Extension = ".StaticWebAssets.xml"; | ||
| const string staticWebAssetsV2Extension = ".staticwebassets.runtime.json"; | ||
| DevServerOptions? devServerOptions = null; | ||
| string appPath = args.CommonConfig.AppPath; | ||
| if (args.CommonConfig.HostProperties.MainAssembly != null) | ||
| { | ||
| // If we have main assembly name, try to find static web assets manifest by precise name. | ||
| var mainAssemblyPath = Path.Combine(appPath, args.CommonConfig.HostProperties.MainAssembly); | ||
| var staticWebAssetsPath = Path.ChangeExtension(mainAssemblyPath, staticWebAssetsV2Extension); | ||
| if (File.Exists(staticWebAssetsPath)) | ||
| { | ||
| devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, onConsoleConnected); | ||
| } | ||
| else | ||
| { | ||
| staticWebAssetsPath = Path.ChangeExtension(mainAssemblyPath, staticWebAssetsV1Extension); | ||
| if (File.Exists(staticWebAssetsPath)) | ||
| devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, onConsoleConnected); | ||
| } | ||
| if (devServerOptions == null) | ||
| devServerOptions = CreateDevServerOptions(urls, mainAssemblyPath, onConsoleConnected); | ||
| } | ||
| else | ||
| { | ||
| // If we don't have main assembly name, try to find static web assets manifest by search in the directory. | ||
| var staticWebAssetsPath = FindFirstFileWithExtension(appPath, staticWebAssetsV2Extension) | ||
| ?? FindFirstFileWithExtension(appPath, staticWebAssetsV1Extension); | ||
| if (staticWebAssetsPath != null) | ||
| devServerOptions = CreateDevServerOptions(urls, staticWebAssetsPath, onConsoleConnected); | ||
| if (devServerOptions == null) | ||
| throw new CommandLineException("Please, provide mainAssembly in hostProperties of runtimeconfig"); | ||
| } | ||
| return devServerOptions; | ||
| } | ||
| private static DevServerOptions CreateDevServerOptions(string[] urls, string staticWebAssetsPath, Func<WebSocket, Task>? onConsoleConnected) => new | ||
| ( | ||
| OnConsoleConnected: onConsoleConnected, | ||
| StaticWebAssetsPath: staticWebAssetsPath, | ||
| WebServerUseCors: true, | ||
| WebServerUseCrossOriginPolicy: true, | ||
| Urls: urls | ||
| ); | ||
| private static string? FindFirstFileWithExtension(string directory, string extension) | ||
| => Directory.EnumerateFiles(directory, "*" + extension).First(); | ||
maraf marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| private async Task RunConsoleMessagesPump(WebSocket socket, WasmTestMessagesProcessor messagesProcessor, CancellationToken token) | ||
| { | ||
| byte[] buff = new byte[4000]; | ||
| @@ -169,7 +243,7 @@ private string[] BuildUrls(ServerURLs serverURLs, IEnumerable<string> passThroug | ||
| } | ||
| string query = sb.ToString(); | ||
| string filename = Path.GetFileName(_args.HTMLPath!); | ||
| string? filename = _args.HTMLPath != null ? Path.GetFileName(_args.HTMLPath) : null; | ||
| string httpUrl = BuildUrl(serverURLs.Http, filename, query); | ||
| return string.IsNullOrEmpty(serverURLs.Https) | ||
| @@ -179,12 +253,18 @@ private string[] BuildUrls(ServerURLs serverURLs, IEnumerable<string> passThroug | ||
| httpUrl, | ||
| BuildUrl(serverURLs.Https!, filename, query) | ||
| }); | ||
| } | ||
| static string BuildUrl(string baseUrl, string htmlFileName, string query) | ||
| => new UriBuilder(baseUrl) | ||
| { | ||
| Query = query, | ||
| Path = htmlFileName | ||
| }.ToString(); | ||
| private static string BuildUrl(string baseUrl, string? htmlFileName, string query) | ||
| { | ||
| var uriBuilder = new UriBuilder(baseUrl) | ||
| { | ||
| Query = query | ||
| }; | ||
| if (htmlFileName != null) | ||
| uriBuilder.Path = htmlFileName; | ||
| return uriBuilder.ToString(); | ||
| } | ||
| } | ||
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.