Skip to content
This repository has been archived by the owner on Feb 25, 2021. It is now read-only.

Live reloading #193

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a1921de
Initial rough implementation, hardcoded always to be on, and at a fix…
SteveSandersonMS Mar 1, 2018
dba8437
Enable live reloading only for debug builds.
SteveSandersonMS Mar 1, 2018
381ac3d
Fix tests
SteveSandersonMS Mar 1, 2018
9ebdc1a
Add E2E tests
SteveSandersonMS Mar 1, 2018
f395114
E2E fixes
SteveSandersonMS Mar 1, 2018
c55c19a
Keep reload signals within the context of an individual UseBlazorLive…
SteveSandersonMS Mar 1, 2018
c818cd9
Remove unnecessary reload delay
SteveSandersonMS Mar 1, 2018
df12cfb
Revert "Remove unnecessary reload delay"
SteveSandersonMS Mar 1, 2018
096aecb
Avoid spurious error message in Firefox
SteveSandersonMS Mar 1, 2018
e791265
Post-rebase fixes
SteveSandersonMS Mar 16, 2018
a508168
Update build-completed signal to match new build mechanism
SteveSandersonMS Mar 16, 2018
cbf44cc
Add missing assertion that was lost during rebase
SteveSandersonMS Mar 16, 2018
a1d3258
Fix live reloading E2E test following build mechanism changes
SteveSandersonMS Mar 16, 2018
a3def66
Make live reloading easier to turn on/off
SteveSandersonMS Mar 16, 2018
37ab3cd
Enable live reloading on test app when running in CI
SteveSandersonMS Mar 16, 2018
d38e085
Make reload URI less likely to clash with an application path
SteveSandersonMS Mar 16, 2018
0984189
Don't issue the reload notification until the build is really finished
SteveSandersonMS Mar 16, 2018
0afe9dd
Post-rebase fixes
SteveSandersonMS Mar 30, 2018
6c7ee54
Allow longer for E2E test to complete
SteveSandersonMS Mar 30, 2018
ed4fa10
Remove unnecessary "reload on server disconnection" feature, since we…
SteveSandersonMS Mar 30, 2018
6223599
Clean up
SteveSandersonMS Mar 30, 2018
cef1d9f
Cause 'dotnet watch' to respond to .cshtml file changes
SteveSandersonMS Mar 30, 2018
d00b9ae
Don't issue reload notifications when building inside VS. This needs …
SteveSandersonMS Mar 30, 2018
8c876d6
Switch from EventSource to WebSocket for live reloading notifications
SteveSandersonMS Mar 30, 2018
f18e396
On the server, ensure live reloading is never enabled in the Producti…
SteveSandersonMS Apr 2, 2018
7893896
Always run Live Reloading E2E tests in Development environment
SteveSandersonMS Apr 2, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Blazor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.Blaz
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestContentPackage", "test\testapps\TestContentPackage\TestContentPackage.csproj", "{C57382BC-EE93-49D5-BC40-5C98AF8AA048}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiveReloadTestApp", "test\testapps\LiveReloadTestApp\LiveReloadTestApp.csproj", "{0246AA77-1A27-4A67-874B-6EF6F99E414E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -281,6 +283,7 @@ Global
{F3E02B21-1127-431A-B832-0E53CB72097B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3E02B21-1127-431A-B832-0E53CB72097B}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{F3E02B21-1127-431A-B832-0E53CB72097B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3E02B21-1127-431A-B832-0E53CB72097B}.Release|Any CPU.Build.0 = Release|Any CPU
{F3E02B21-1127-431A-B832-0E53CB72097B}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{FF25111E-5A3E-48A3-96D8-08A2C5A2A91C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF25111E-5A3E-48A3-96D8-08A2C5A2A91C}.Debug|Any CPU.Build.0 = Debug|Any CPU
Expand Down Expand Up @@ -312,6 +315,14 @@ Global
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.Release|Any CPU.Build.0 = Release|Any CPU
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.Release|Any CPU.Build.0 = Release|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
{0246AA77-1A27-4A67-874B-6EF6F99E414E}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -352,6 +363,7 @@ Global
{43E39257-7DC1-46BD-9BD9-2319A1313D07} = {F563ABB6-85FB-4CFC-B0D2-1D5130E8246D}
{9088E4E4-B855-457F-AE9E-D86709A5E1F4} = {F563ABB6-85FB-4CFC-B0D2-1D5130E8246D}
{C57382BC-EE93-49D5-BC40-5C98AF8AA048} = {4AE0D35B-D97A-44D0-8392-C9240377DCCE}
{0246AA77-1A27-4A67-874B-6EF6F99E414E} = {4AE0D35B-D97A-44D0-8392-C9240377DCCE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {504DA352-6788-4DC0-8705-82167E72A4D3}
Expand Down
8 changes: 8 additions & 0 deletions src/Microsoft.AspNetCore.Blazor.Browser.JS/src/Boot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { platform } from './Environment';
import { getAssemblyNameFromUrl } from './Platform/DotNet';
import { enableLiveReloading } from './LiveReloading';
import './Rendering/Renderer';
import './Services/Http';
import './Services/UriHelper';
Expand Down Expand Up @@ -36,6 +37,13 @@ async function boot() {

// Start up the application
platform.callEntryPoint(entryPointAssemblyName, entryPointMethod, []);

// Enable live reloading only if there's a "reload" attribute on the <script> tag.
// In production, this should not be the case.
const reloadUri = thisScriptElem.getAttribute('reload');
if (reloadUri) {
enableLiveReloading(reloadUri);
}
}

function getRequiredBootScriptAttribute(elem: HTMLScriptElement, attributeName: string): string {
Expand Down
50 changes: 50 additions & 0 deletions src/Microsoft.AspNetCore.Blazor.Browser.JS/src/LiveReloading.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const reconnectionPollIntervalMs = 250;

export function enableLiveReloading(endpointUri: string) {
listenForReloadEvent(endpointUri);
}

function listenForReloadEvent(endpointUri: string) {
if (!WebSocket) {
console.log('Browser does not support WebSocket, so live reloading will be disabled.');
return;
}

// First, connect to the endpoint
const websocketUri = toAbsoluteWebSocketUri(endpointUri);
const source = new WebSocket(websocketUri);
let allowConnectionFailedErrorReporting = true;

source.onopen = e => {
allowConnectionFailedErrorReporting = false;
};

source.onerror = e => {
if (allowConnectionFailedErrorReporting) {
allowConnectionFailedErrorReporting = false;
console.error(`The client app was compiled with live reloading enabled, but could not open `
+ ` a WebSocket connection to the server at ${websocketUri}\n`
+ `To fix this inconsistency, either run the server in development mode, or compile the `
+ `client app in Release configuration.`);
}
};

// If we're notified that we should reload, then do so
source.onmessage = e => {
if (e.data === 'reload') {
location.reload();
}
};
}

function toAbsoluteWebSocketUri(uri: string) {
const baseUri = document.baseURI;
if (baseUri) {
const lastSlashPos = baseUri.lastIndexOf('/');
const prefix = baseUri.substr(0, lastSlashPos);
uri = prefix + uri;
}

// Scheme must be ws: or wss:
return uri.replace(/^http/, 'ws');
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public static void Command(CommandLineApplication command)
"Adds a <link rel=stylesheet> tag with the specified 'href' value",
CommandOptionType.MultipleValue);

var reloadUri = command.Option("--reload-uri",
"If specified, enables live reloading and specifies the URI of the notification endpoint.",
CommandOptionType.SingleValue);

var outputPath = command.Option("--output",
"Path to the output file",
CommandOptionType.SingleValue);
Expand Down Expand Up @@ -55,6 +59,7 @@ public static void Command(CommandLineApplication command)
jsReferences.Values.ToArray(),
cssReferences.Values.ToArray(),
linkerEnabledFlag.HasValue(),
reloadUri.Value(),
outputPath.Value());
return 0;
}
Expand Down
23 changes: 18 additions & 5 deletions src/Microsoft.AspNetCore.Blazor.Build/Core/IndexHtmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public static void UpdateIndex(
IEnumerable<string> jsReferences,
IEnumerable<string> cssReferences,
bool linkerEnabled,
string reloadUri,
string outputPath)
{
var template = GetTemplate(path);
Expand All @@ -31,7 +32,7 @@ public static void UpdateIndex(
}
var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
var entryPoint = GetAssemblyEntryPoint(assemblyPath);
var updatedContent = GetIndexHtmlContents(template, assemblyName, entryPoint, assemblyReferences, jsReferences, cssReferences, linkerEnabled);
var updatedContent = GetIndexHtmlContents(template, assemblyName, entryPoint, assemblyReferences, jsReferences, cssReferences, linkerEnabled, reloadUri);
var normalizedOutputPath = Normalize(outputPath);
Console.WriteLine("Writing index to: " + normalizedOutputPath);
File.WriteAllText(normalizedOutputPath, updatedContent);
Expand Down Expand Up @@ -103,7 +104,8 @@ public static string GetIndexHtmlContents(
IEnumerable<string> assemblyReferences,
IEnumerable<string> jsReferences,
IEnumerable<string> cssReferences,
bool linkerEnabled)
bool linkerEnabled,
string reloadUri)
{
var resultBuilder = new StringBuilder();

Expand Down Expand Up @@ -144,7 +146,8 @@ public static string GetIndexHtmlContents(
assemblyEntryPoint,
assemblyReferences,
linkerEnabled,
tag.Attributes);
tag.Attributes,
reloadUri);

// Emit tags to reference any specified JS/CSS files
AppendReferenceTags(
Expand Down Expand Up @@ -175,7 +178,11 @@ public static string GetIndexHtmlContents(

case HtmlTokenType.EndOfFile:
// Finally, emit any remaining text from the original source file
resultBuilder.Append(htmlTemplate, currentRangeStartPos, htmlTemplate.Length - currentRangeStartPos);
var remainingLength = htmlTemplate.Length - currentRangeStartPos;
if (remainingLength > 0)
{
resultBuilder.Append(htmlTemplate, currentRangeStartPos, remainingLength);
}
return resultBuilder.ToString();
}
}
Expand All @@ -202,7 +209,8 @@ private static void AppendScriptTagWithBootConfig(
string assemblyEntryPoint,
IEnumerable<string> binFiles,
bool linkerEnabled,
List<KeyValuePair<string, string>> attributes)
List<KeyValuePair<string, string>> attributes,
string reloadUri)
{
var assemblyNameWithExtension = $"{assemblyName}.dll";

Expand All @@ -224,6 +232,11 @@ private static void AppendScriptTagWithBootConfig(
attributesDict.Remove("linker-enabled");
}

if (!string.IsNullOrEmpty(reloadUri))
{
attributesDict["reload"] = reloadUri;
}

resultBuilder.Append("<script");
foreach (var attributePair in attributesDict)
{
Expand Down
9 changes: 9 additions & 0 deletions src/Microsoft.AspNetCore.Blazor.Build/targets/All.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@
<PropertyGroup>
<DefaultWebContentItemExcludes>$(DefaultWebContentItemExcludes);wwwroot\**</DefaultWebContentItemExcludes>

<!-- By default, live reloading is on for debug builds -->
<UseBlazorLiveReloading Condition="'$(Configuration)' == 'Debug'">true</UseBlazorLiveReloading>
<BlazorLiveReloadUri>/_reload</BlazorLiveReloadUri>

<!-- We can remove this after updating to newer Razor tooling, where it's enabled by default -->
<UseRazorBuildServer>true</UseRazorBuildServer>
</PropertyGroup>

<ItemGroup>
<!-- In case you're using 'dotnet watch', enable reloading when editing .cshtml files -->
<Watch Include="$(ProjectDir)**\*.cshtml" />
</ItemGroup>
</Project>
3 changes: 2 additions & 1 deletion src/Microsoft.AspNetCore.Blazor.Build/targets/All.targets
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<PropertyGroup>
<BlazorBuildExe>dotnet &quot;$(MSBuildThisFileDirectory)../tools/Microsoft.AspNetCore.Blazor.Build.dll&quot;</BlazorBuildExe>

<!-- The Blazor build code can only find your referenced assemblies if they are in the output directory -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
Expand All @@ -23,6 +23,7 @@
</PropertyGroup>
<WriteLinesToFile File="$(BlazorMetadataFilePath)" Lines="$(MSBuildProjectFullPath)" Overwrite="true" Encoding="Unicode"/>
<WriteLinesToFile File="$(BlazorMetadataFilePath)" Lines="$(OutDir)$(AssemblyName).dll" Overwrite="false" Encoding="Unicode"/>
<WriteLinesToFile File="$(BlazorMetadataFilePath)" Condition="'$(UseBlazorLiveReloading)'=='true'" Lines="reload:$(BlazorLiveReloadUri)" Overwrite="false" Encoding="Unicode"/>
<ItemGroup>
<ContentWithTargetPath Include="$(BlazorMetadataFilePath)" TargetPath="$(BlazorMetadataFileName)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@

<PropertyGroup Label="Blazor build outputs">
<AdditionalMonoLinkerOptions>-c link -u link -t --verbose </AdditionalMonoLinkerOptions>
<BaseBlazorPackageContentOutputPath>dist/_content/</BaseBlazorPackageContentOutputPath>
<BaseBlazorRuntimeOutputPath>dist/_framework/</BaseBlazorRuntimeOutputPath>
<BaseBlazorDistPath>dist/</BaseBlazorDistPath>
<BaseBlazorPackageContentOutputPath>$(BaseBlazorDistPath)_content/</BaseBlazorPackageContentOutputPath>
<BaseBlazorRuntimeOutputPath>$(BaseBlazorDistPath)_framework/</BaseBlazorRuntimeOutputPath>
<BaseBlazorRuntimeBinOutputPath>$(BaseBlazorRuntimeOutputPath)_bin/</BaseBlazorRuntimeBinOutputPath>
<BaseBlazorRuntimeAsmjsOutputPath>$(BaseBlazorRuntimeOutputPath)asmjs/</BaseBlazorRuntimeAsmjsOutputPath>
<BaseBlazorRuntimeWasmOutputPath>$(BaseBlazorRuntimeOutputPath)wasm/</BaseBlazorRuntimeWasmOutputPath>
Expand All @@ -21,6 +22,7 @@
<BlazorWebRootName>wwwroot/</BlazorWebRootName>
<BlazorIndexHtmlName>Index.html</BlazorIndexHtmlName>
<BlazorOutputIndexHtmlName>$(BlazorIndexHtmlName.ToLowerInvariant())</BlazorOutputIndexHtmlName>
<BlazorBuildCompletedSignalPath>$(BaseBlazorDistPath)__blazorBuildCompleted</BlazorBuildCompletedSignalPath>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
<ItemGroup>
<FileWrites Include="@(BlazorItemOutput->'%(TargetOutputPath)')" />
</ItemGroup>
<PropertyGroup>
<_BlazorDidCopyFilesToOutputDirectory>true</_BlazorDidCopyFilesToOutputDirectory>
</PropertyGroup>
</Target>

<Target Name="_BlazorTrackResolveReferencesDidRun" AfterTargets="ResolveReferences">
Expand All @@ -47,6 +50,21 @@
<Message Importance="$(_BlazorStatisticsReportImportance)" Text="%(_BlazorStatisticsOutput.Identity)" />
</Target>

<!--
We only issue the reload notification from here if you're *not* building inside VS.
If you are building inside VS, then it's possible you're building an arbitrary collection
of projects of which this is just one, and it's important to wait until all projects in
the build are completed before reloading, so the notification is instead triggered by the
VS extension that can see when a complete build process is finished.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the work that billhie is going for us? Or will we need to add something ourselves?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bill is doing some work to avoid the unwanted IISExpress recycles - it's related to this work item, but not to this comment.

We will have to do some work in our VS extension ourselves to detect when a build completes and write the signal file. I was expecting to do that, though I may have to ask for your advice on it since I have no experience of writing any VS extension code.

-->
<Target Name="_BlazorIssueLiveReloadNotification"
AfterTargets="Build"
Condition="'$(UseBlazorLiveReloading)'=='true' AND '$(_BlazorDidCopyFilesToOutputDirectory)'=='true' AND '$(BuildingInsideVisualStudio)'!='true'">
<!-- Touch the signal file to trigger a reload -->
<WriteLinesToFile File="$(ProjectDir)$(OutputPath)$(BlazorBuildCompletedSignalPath)" Lines="_" />
<Delete Files="$(ProjectDir)$(OutputPath)$(BlazorBuildCompletedSignalPath)" />
</Target>

<!-- Preparing blazor files for output:
PrepareBlazorOutputs
_PrepareBlazorOutputConfiguration
Expand All @@ -65,6 +83,7 @@
_TouchBlazorApplicationAssemblies
_GenerateBlazorIndexHtml
_BlazorCopyFilesToOutputDirectory
_BlazorIssueLiveReloadNotification

The process for doing builds goes as follows:
Produce a hash file with the Hash SDK task and write that hash to a marker file.
Expand Down Expand Up @@ -571,6 +590,7 @@
<BlazorIndexHtmlInput Include="@(BlazorPackageJsRef->'%(FullPath)')" />
<BlazorIndexHtmlInput Include="@(BlazorPackageCssRef->'%(FullPath)')" />
<BlazorIndexHtmlInput Include="@(_BlazorLinkingOption)" />
<BlazorIndexHtmlInput Include="$(BlazorLiveReloadUri)" Condition="'$(UseBlazorLiveReloading)'=='true'" />
</ItemGroup>

<WriteLinesToFile
Expand All @@ -597,9 +617,10 @@
</ItemGroup>
<PropertyGroup>
<_LinkerEnabledFlag Condition="'$(_BlazorShouldLinkApplicationAssemblies)' != ''">--linker-enabled</_LinkerEnabledFlag>
<_LiveReloadArg Condition="'$(UseBlazorLiveReloading)' == 'true' AND '$(BlazorLiveReloadUri)' != ''">--reload-uri "$(BlazorLiveReloadUri)"</_LiveReloadArg>
</PropertyGroup>

<Exec Command="$(BlazorBuildExe) build @(IntermediateAssembly) --html-page &quot;$(BlazorIndexHtml)&quot; @(_AppReferences->'--reference &quot;%(Identity)&quot;', ' ') @(_JsReferences->'--js &quot;%(Identity)&quot;', ' ') @(_CssReferences->'--css &quot;%(Identity)&quot;', ' ') $(_LinkerEnabledFlag) --output &quot;$(BlazorIndexHtmlOutputPath)&quot;" />
<Exec Command="$(BlazorBuildExe) build @(IntermediateAssembly) --html-page &quot;$(BlazorIndexHtml)&quot; @(_AppReferences->'--reference &quot;%(Identity)&quot;', ' ') @(_JsReferences->'--js &quot;%(Identity)&quot;', ' ') @(_CssReferences->'--css &quot;%(Identity)&quot;', ' ') $(_LinkerEnabledFlag) $(_LiveReloadArg) --output &quot;$(BlazorIndexHtmlOutputPath)&quot;" />

<ItemGroup Condition="Exists('$(BlazorIndexHtmlOutputPath)')">
<_BlazorIndex Include="$(BlazorIndexHtmlOutputPath)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,9 @@ public static void UseBlazor(
// hence all the path manipulation here. We shouldn't be hardcoding 'dist' here either.
var env = (IHostingEnvironment)applicationBuilder.ApplicationServices.GetService(typeof(IHostingEnvironment));
var config = BlazorConfig.Read(options.ClientAssemblyPath);
var clientAppBinDir = Path.GetDirectoryName(config.SourceOutputAssemblyPath);
var clientAppDistDir = Path.Combine(
env.ContentRootPath,
Path.Combine(clientAppBinDir, "dist"));
var distDirStaticFiles = new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(clientAppDistDir),
FileProvider = new PhysicalFileProvider(config.DistPath),
ContentTypeProvider = CreateContentTypeProvider(),
};

Expand All @@ -68,6 +64,15 @@ public static void UseBlazor(
});
}

// Definitely don't open a listener for live reloading in production, even if the
// client app was compiled with live reloading enabled
if (env.IsDevelopment())
{
// Whether or not live reloading is actually enabled depends on the client config
// For release builds, it won't be (by default)
applicationBuilder.UseBlazorLiveReloading(config);
}

// Finally, use SPA fallback routing (serve default page for anything else,
// excluding /_framework/*)
applicationBuilder.MapWhen(IsNotFrameworkDir, childAppBuilder =>
Expand Down
18 changes: 18 additions & 0 deletions src/Microsoft.AspNetCore.Blazor.Server/BlazorConfig.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;
using System.Linq;

Expand All @@ -11,12 +12,19 @@ internal class BlazorConfig
public string SourceMSBuildPath { get; }
public string SourceOutputAssemblyPath { get; }
public string WebRootPath { get; }
public string ReloadUri { get; }
public string DistPath
=> Path.Combine(Path.GetDirectoryName(SourceOutputAssemblyPath), "dist");

public static BlazorConfig Read(string assemblyPath)
=> new BlazorConfig(assemblyPath);

private BlazorConfig(string assemblyPath)
{
// TODO: Instead of assuming the lines are in a specific order, either JSON-encode
// the whole thing, or at least give the lines key prefixes (e.g., "reload:<someuri>")
// so we're not dependent on order and all lines being present.

var configFilePath = Path.ChangeExtension(assemblyPath, ".blazor.config");
var configLines = File.ReadLines(configFilePath).ToList();
SourceMSBuildPath = configLines[0];
Expand All @@ -29,6 +37,16 @@ private BlazorConfig(string assemblyPath)
{
WebRootPath = webRootPath;
}

const string reloadMarker = "reload:";
var reloadUri = configLines
.Where(line => line.StartsWith(reloadMarker, StringComparison.Ordinal))
.Select(line => line.Substring(reloadMarker.Length))
.FirstOrDefault();
if (!string.IsNullOrEmpty(reloadUri))
{
ReloadUri = reloadUri;
}
}
}
}
Loading