jsakamoto / BlazorWasmPreRendering.Build

When you publish your Blazor Wasm app, this package pre-renders and saves the app as static HTML files in your public folder.
https://jsakamoto.github.io/BlazorWasmPreRendering.Build/
Mozilla Public License 2.0
240 stars 14 forks source link

Publish failed #2

Open ElderJames opened 2 years ago

ElderJames commented 2 years ago

Hi there, I tried to install this package to https://github.com/ant-design-blazor/ant-design-blazor, but an exception occurred during the publishing process.

AntDesign.Docs.Wasm -> E:\antd\ant-design-blazor\site\AntDesign.Docs.Wasm\obj\Release\net5\browser-wasm\PubTmp\Out\
dotnet "C:\Users\shunj\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.4.1\build\../tools/net5/blazorwasm-prerendering-server.dll" -a "AntDesign.Docs.Wasm" -t "AntDesign.Docs.Wasm.App" -s "#app" -p "E:\antd\ant-design-blazor\site\AntDesign.Docs.Wasm\bin\Release\net5\publish" -i "E:\antd\ant-design-blazor\site\AntDesign.Docs.Wasm\obj\Release\net5\." -m "" -f "net5"
Could not execute because the specified command or file was not found.
Possible reasons for this include:
  * You misspelled a built-in dotnet command.
  * You intended to execute a .NET program, but dotnet-C:\Users\shunj\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.4.1\build\../tools/net5/blazorwasm-prerendering-server.dll does not exist.
  * You intended to run a global tool, but a dotnet-prefixed executable with this name could not be found on the PATH.
C:\Users\shunj\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.4.1\build\BlazorWasmPreRendering.Build.targets(33,5): Error MSB3073: The command "dotnet "C:\Users\shunj\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.4.1\build\../tools/net5/blazorwasm-prerendering-server.dll" -a "AntDesign.Docs.Wasm" -t "AntDesign.Docs.Wasm.App" -s "#app" -p "E:\antd\ant-design-blazor\site\AntDesign.Docs.Wasm\bin\Release\net5\publish" -i "E:\antd\ant-design-blazor\site\AntDesign.Docs.Wasm\obj\Release\net5\." -m "" -f "net5"" exited with code 1.
jsakamoto commented 2 years ago

Thank you for reporting!

But unfortunately, I found out AntDesign.Docs.Wasm cannot pre-render to static files at this time. I'll explain what's the matter below.

Anyway, we can progress static pre-rendering task of AntDesign.Docs.Wasm.

At first, please update the package reference to this package to v.1.0.0-preview.6. Then, the error you saw and reported to me should be gone. (I could fix the first problem (see also commit 1d5a0aea) with your report. Thanks!)

Second, maybe you already know, the Program.cs in the AntDesign.Docs.Wasm project has to change as below:

Before:

public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("app");

        builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

        builder.Services.AddAntDesignDocs(); // 👈 extract this line to...

        await builder.Build().RunAsync();
    }
}

After:

public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("app");

        builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

        ConfigureServices(builder.Services);

        await builder.Build().RunAsync();
    }

    // 👇 ...to this static method. The method name and signature must be as below.
    private static void ConfigureServices(IServiceCollection services)
    {
        services.AddAntDesignDocs();
    }
}

After doing the above steps, the dotnet publish task on the AntDesign.Docs.Wasm project folder will be complete successfully.

However, the result of static pre-rendering will be empty....!

Because, when the request URL is "/", your ConventionRouter implementation just redirects, doesn't render anything.

And also, when the request URL is "/en-US", the server-side rendering process will crash with an unhandled exception. You can reproduce this behavior on the AntDesign.Docs.Server.

(After initial launched of the AntDesign.Docs.Server app and you are redirected to "/en-US", then please reload it. You will see an error page like below)

image

If you fix the crash of the AntDesign.Docs.Server above, then I might be able to come up with something static pre-rendering be a success, so please let me know.

fingers10 commented 2 years ago

@jsakamoto I appreciate your time in creating this project. I tried this with brand new net6.0 blazor wasm pwa project in windows 11 pro. I'm getting the below error on publish.

Publishing Log: ``` BlazorWasmPreRenderGitDeploy -> C:\Users\Abdul Rahman\source\repos\BlazorWasmPreRenderGitDeploy\BlazorWasmPreRenderGitDeploy\obj\Release\net6.0\browser-wasm\PubTmp\Out\ dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.9.0\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "BlazorWasmPreRenderGitDeploy" -t "BlazorWasmPreRenderGitDeploy.App" --selectorofrootcomponent "#app,app" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\BlazorWasmPreRenderGitDeploy\BlazorWasmPreRenderGitDeploy\bin\Release\net6.0\publish" -i "C:\Users\Abdul Rahman\source\repos\BlazorWasmPreRenderGitDeploy\BlazorWasmPreRenderGitDeploy\obj\Release\net6.0\." -m "" -f "net6.0" Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'BlazorWasmPreRenderGitDeploy, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified. File name: 'BlazorWasmPreRenderGitDeploy, Culture=neutral, PublicKeyToken=null' at System.Reflection.RuntimeAssembly.InternalLoad(ObjectHandleOnStack assemblyName, ObjectHandleOnStack requestingAssembly, StackCrawlMarkHandle stackMark, Boolean throwOnFileNotFound, ObjectHandleOnStack assemblyLoadContext, ObjectHandleOnStack retAssembly) at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName assemblyName, RuntimeAssembly requestingAssembly, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, AssemblyLoadContext assemblyLoadContext) at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyName(AssemblyName assemblyName) at Toolbelt.Blazor.WebAssembly.PrerenderServer.CustomAssemblyLoader.LoadAssembly(String assemblyName) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\CustomAssemblyLoader.cs:line 41 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.BuildPrerenderingOptions(CustomAssemblyLoader assemblyLoader, CommandLineOptions commandLineOptions) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 70 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.Main(String[] args) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 24 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.
(String[] args) C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.9.0\build\BlazorWasmPreRendering.Build.targets(36,5): Error MSB3073: The command "dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.9.0\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "BlazorWasmPreRenderGitDeploy" -t "BlazorWasmPreRenderGitDeploy.App" --selectorofrootcomponent "#app,app" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\BlazorWasmPreRenderGitDeploy\BlazorWasmPreRenderGitDeploy\bin\Release\net6.0\publish" -i "C:\Users\Abdul Rahman\source\repos\BlazorWasmPreRenderGitDeploy\BlazorWasmPreRenderGitDeploy\obj\Release\net6.0\." -m "" -f "net6.0"" exited with code -532462766. ```
Output log: ``` [1D00:071C][2021-11-21T14:21:06]i001: Burn v3.10.4.4718, Windows v10.0 (Build 22000: Service Pack 0), path: C:\Windows\Temp\{AA2CFFB3-2680-45AB-89E0-7D3A9DF09CBD}\.cr\VC_redist.x64.exe [1D00:071C][2021-11-21T14:21:06]i009: Command Line: '-burn.clean.room=C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.VisualCpp.Redist.14.Latest,version=14.30.30704,chip=x64\VC_redist.x64.exe -burn.filehandle.attached=696 -burn.filehandle.self=540 /q /norestart /log C:\Users\Abdul Rahman\AppData\Local\Temp\dd_setup_20211121142023_019_Microsoft.VisualCpp.Redist.14.Latest.log' [1D00:071C][2021-11-21T14:21:06]i000: Setting string variable 'WixBundleOriginalSource' to value 'C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.VisualCpp.Redist.14.Latest,version=14.30.30704,chip=x64\VC_redist.x64.exe' [1D00:071C][2021-11-21T14:21:06]i000: Setting string variable 'WixBundleOriginalSourceFolder' to value 'C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.VisualCpp.Redist.14.Latest,version=14.30.30704,chip=x64\' [1D00:071C][2021-11-21T14:21:06]i000: Setting string variable 'WixBundleLog' to value 'C:\Users\Abdul' [1D00:071C][2021-11-21T14:21:06]i000: Setting string variable 'WixBundleManufacturer' to value 'Microsoft Corporation' [1D00:2CC4][2021-11-21T14:21:06]i000: Setting version variable 'WixBundleFileVersion' to value '14.30.30704.0' [1D00:071C][2021-11-21T14:21:06]i100: Detect begin, 11 packages [1D00:071C][2021-11-21T14:21:06]i000: Setting string variable 'Arm64_Check' to value 'AMD64' [1D00:071C][2021-11-21T14:21:06]i000: Setting version variable 'windows_uCRT_DetectKey' to value '10.0.22000.1' [1D00:071C][2021-11-21T14:21:06]i000: Setting numeric variable 'windows_uCRT_DetectKeyExists' to value 1 [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.3 AND NOT VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.3 AND VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.2 AND NOT VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.2 AND VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.1 AND NOT VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.1 AND VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.0 AND NOT VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT = v6.0 AND VersionNT64) AND (windows_uCRT_DetectKeyExists AND windows_uCRT_DetectKey >= v10.0.10240.0)' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i101: Detected package: Windows81_x86, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: Windows81_x64, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: Windows8_x86, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: Windows8_x64, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: Windows7_MSU_x86, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: Windows7_MSU_x64, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: WindowsVista_MSU_x86, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: WindowsVista_MSU_x64, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i101: Detected package: vcRuntimeMinimum_x64, state: Present, cached: Complete [1D00:071C][2021-11-21T14:21:06]i101: Detected package: vcRuntimeAdditional_x64, state: Present, cached: Complete [1D00:071C][2021-11-21T14:21:06]i101: Detected package: vcRuntime_arm64, state: Absent, cached: None [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT >= v6.1 OR (VersionNT = v6.0 AND ServicePackLevel >= 2)' evaluates to true. [1D00:071C][2021-11-21T14:21:06]i199: Detect complete, result: 0x0 [1D00:071C][2021-11-21T14:21:06]i200: Plan begin, 11 packages, action: Modify [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.3 AND NOT VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: Windows81_x86 [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.3 AND VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: Windows81_x64 [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.2 AND NOT VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: Windows8_x86 [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.2 AND VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: Windows8_x64 [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.1 AND NOT VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: Windows7_MSU_x86 [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.1 AND VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: Windows7_MSU_x64 [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.0 AND NOT VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: WindowsVista_MSU_x86 [1D00:071C][2021-11-21T14:21:06]i052: Condition 'VersionNT = v6.0 AND VersionNT64' evaluates to false. [1D00:071C][2021-11-21T14:21:06]w321: Skipping dependency registration on package with no dependency providers: WindowsVista_MSU_x64 [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT64) AND NOT (Arm64_Check = "ARM64")' evaluates to true. [1D00:071C][2021-11-21T14:21:06]i052: Condition '(VersionNT64) AND NOT (Arm64_Check = "ARM64")' evaluates to true. [1D00:071C][2021-11-21T14:21:06]i052: Condition 'Arm64_Check = "ARM64"' evaluates to false. [1D00:071C][2021-11-21T14:21:06]i201: Planned package: Windows81_x86, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: Windows81_x64, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: Windows8_x86, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: Windows8_x64, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: Windows7_MSU_x86, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: Windows7_MSU_x64, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: WindowsVista_MSU_x86, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: WindowsVista_MSU_x64, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i201: Planned package: vcRuntimeMinimum_x64, state: Present, default requested: Present, ba requested: Present, execute: None, rollback: None, cache: No, uncache: No, dependency: Register [1D00:071C][2021-11-21T14:21:06]i201: Planned package: vcRuntimeAdditional_x64, state: Present, default requested: Present, ba requested: Present, execute: None, rollback: None, cache: No, uncache: No, dependency: Register [1D00:071C][2021-11-21T14:21:06]i201: Planned package: vcRuntime_arm64, state: Absent, default requested: Absent, ba requested: Absent, execute: None, rollback: None, cache: No, uncache: No, dependency: None [1D00:071C][2021-11-21T14:21:06]i299: Plan complete, result: 0x0 [1D00:071C][2021-11-21T14:21:06]i300: Apply begin [1D00:071C][2021-11-21T14:21:06]i010: Launching elevated engine process. [1D00:071C][2021-11-21T14:21:06]i011: Launched elevated engine process. [1D00:071C][2021-11-21T14:21:06]i012: Connected to elevated engine. [2D10:1F98][2021-11-21T14:21:06]i358: Pausing automatic updates. [2D10:1F98][2021-11-21T14:21:06]i359: Paused automatic updates. [2D10:1F98][2021-11-21T14:21:06]i360: Creating a system restore point. [2D10:1F98][2021-11-21T14:21:06]w363: Could not create system restore point, error: 0x80070422. Continuing... [2D10:1F98][2021-11-21T14:21:06]i371: Updating session, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{57a73df6-4ba9-4c1d-bbbb-517289ff6c13}, resume: Active, restart initiated: No, disable resume: No [2D10:1F98][2021-11-21T14:21:06]i325: Registering dependency: {57a73df6-4ba9-4c1d-bbbb-517289ff6c13} on package provider: Microsoft.VS.VC_RuntimeMinimumVSU_amd64,v14, package: vcRuntimeMinimum_x64 [2D10:1F98][2021-11-21T14:21:06]i325: Registering dependency: {57a73df6-4ba9-4c1d-bbbb-517289ff6c13} on package provider: Microsoft.VS.VC_RuntimeAdditionalVSU_amd64,v14, package: vcRuntimeAdditional_x64 [2D10:1F98][2021-11-21T14:21:06]i372: Session end, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{57a73df6-4ba9-4c1d-bbbb-517289ff6c13}, resume: ARP, restart: None, disable resume: No [2D10:1F98][2021-11-21T14:21:06]i371: Updating session, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{57a73df6-4ba9-4c1d-bbbb-517289ff6c13}, resume: ARP, restart initiated: No, disable resume: No [1D00:071C][2021-11-21T14:21:06]i399: Apply complete, result: 0x0, restart: None, ba requested restart: No [1D00:071C][2021-11-21T14:21:06]i500: Shutting down, exit code: 0x0 [1D00:071C][2021-11-21T14:21:06]i410: Variable: Arm64_Check = AMD64 [1D00:071C][2021-11-21T14:21:06]i410: Variable: SystemFolder = C:\Windows\system32\ [1D00:071C][2021-11-21T14:21:06]i410: Variable: VersionNT = 10.0.0.0 [1D00:071C][2021-11-21T14:21:06]i410: Variable: VersionNT64 = 10.0.0.0 [1D00:071C][2021-11-21T14:21:06]i410: Variable: windows_uCRT_DetectKey = 10.0.22000.1 [1D00:071C][2021-11-21T14:21:06]i410: Variable: windows_uCRT_DetectKeyExists = 1 [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleAction = 6 [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleElevated = 1 [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleFileVersion = 14.30.30704.0 [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleInstalled = 1 [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleLog = C:\Users\Abdul [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleManufacturer = Microsoft Corporation [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleName = Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.30.30704 [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleOriginalSource = C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.VisualCpp.Redist.14,version=14.30.30704,chip=x64\VC_redist.x64.exe [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleOriginalSourceFolder = C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.VisualCpp.Redist.14,version=14.30.30704,chip=x64\ [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleProviderKey = VC,redist.x64,amd64,14.30,bundle [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleSourceProcessFolder = C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.VisualCpp.Redist.14.Latest,version=14.30.30704,chip=x64\ [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleSourceProcessPath = C:\ProgramData\Microsoft\VisualStudio\Packages\Microsoft.VisualCpp.Redist.14.Latest,version=14.30.30704,chip=x64\VC_redist.x64.exe [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleTag = [1D00:071C][2021-11-21T14:21:06]i410: Variable: WixBundleVersion = 14.30.30704.0 [1D00:071C][2021-11-21T14:21:06]i007: Exit code: 0x0, restarting: No ```

Project Repo Link - https://github.com/fingers10/BlazorWasmPreRenderGitDeploy

Please can you assist me on this?

jsakamoto commented 2 years ago

@fingers10 Thank you for your feedback!

I want to make the "BlazorWasmPreRendering.Build" work well on your scenario. But I think it is not so easy.

I appreciate you if you will be patiently waiting to finish my work.

fingers10 commented 2 years ago

@jsakamoto thanks for the inputs. I'll wait for the solution. Please could you let me know what is the issue here?

jsakamoto commented 2 years ago

@fingers10

Please could you let me know what is the issue here?

Yes, of course, but I have no idea at this time. So I have to investigate it from the start.

However, you have disclosed your repository to me that can reproduce failing. It is much helpful to resolve this issue!

jsakamoto commented 2 years ago

[Progress Report]

Sorry too late but recently I've been able to try to resolve your problem.

And I found the problem can be reproduced when I execute publishing the project with Visual Studio 2022.

I'm currently working on this issue, and I think I can finally resolve that unhandled exception error.

jsakamoto commented 2 years ago

@fingers10

I did it!

Could you try the latest version of the "BlazorWasmPreRendering.Build" out?

fingers10 commented 2 years ago

@jsakamoto

Many thanks for your time and response. This works for simple project. But If we have a parameter of Type WebAssemblyHostConfiguration in ConfigureServices. This fails with below error.

Error: ``` PrerenderTest -> C:\Users\Abdul Rahman\source\repos\PrerenderTest\PrerenderTest\obj\Release\net6.0\browser-wasm\PubTmp\Out\ dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.10.1\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "PrerenderTest" -t "PrerenderTest.App" --selectorofrootcomponent "#body" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\PrerenderTest\PrerenderTest\obj\Release\net6.0\browser-wasm\PubTmp\Out" -i "C:\Users\Abdul Rahman\source\repos\PrerenderTest\PrerenderTest\obj\Release\net6.0\." -m "" -f "net6.0" Unhandled exception. System.TypeLoadException: Method 'get_Item' in type 'Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHostConfiguration' from assembly 'Microsoft.AspNetCore.Components.WebAssembly, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' does not have an implementation. at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType) at System.Reflection.RuntimeMethodInfo.g__LazyCreateSignature|24_0() at System.Reflection.RuntimeMethodInfo.FetchNonReturnParameters() at System.Reflection.RuntimeMethodInfo.GetParameters() at Toolbelt.Blazor.WebAssembly.PrerenderServer.Startup.ConfigureApplicationServices(IServiceCollection services, String baseAddress) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Startup.cs:line 54 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Startup.ConfigureServices(IServiceCollection services) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Startup.cs:line 33 at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance, IServiceCollection services) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass9_0.g__Startup|0(IServiceCollection serviceCollection) at Microsoft.AspNetCore.Hosting.StartupLoader.ConfigureServicesDelegateBuilder`1.<>c__DisplayClass15_0.g__RunPipeline|0(IServiceCollection services) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services) at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass8_0.b__0(IServiceCollection services) at Microsoft.AspNetCore.Hosting.StartupLoader.ConfigureServicesDelegateBuilder`1.<>c__DisplayClass14_0.g__ConfigureServicesWithContainerConfiguration|0(IServiceCollection services) at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services) at Microsoft.AspNetCore.Hosting.WebHost.EnsureApplicationServices() at Microsoft.AspNetCore.Hosting.WebHost.Initialize() at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build() at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.StartWebHostAsync(BlazorWasmPrerenderingOptions prerenderingOptions) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 218 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.Main(String[] args) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 28 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.
(String[] args) C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.10.1\build\BlazorWasmPreRendering.Build.targets(44,5): Error MSB3073: The command "dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.10.1\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "PrerenderTest" -t "PrerenderTest.App" --selectorofrootcomponent "#body" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\PrerenderTest\PrerenderTest\obj\Release\net6.0\browser-wasm\PubTmp\Out" -i "C:\Users\Abdul Rahman\source\repos\PrerenderTest\PrerenderTest\obj\Release\net6.0\." -m "" -f "net6.0"" exited with code -532462766. ```

Project Repo Link - https://github.com/fingers10/PrerenderTest

jsakamoto commented 2 years ago

@fingers10

The pre-rendering process invokes your ConfigurationServices static method, but the process can't treat the type for the WebAssembly platform because the pre-rendering process and your code runs on a normal ASP.NET Core server process, not on the web browser!

image

In this case, if you simply remove the 3rd argument from the ConfigurationServices static method, the publishing process should be done successfully.

But, I've guessed that you want to do something by using the 3rd WebAssemblyHostConfiguration argument. What do you want to do by using WebAssemblyHostConfiguration? Do you want to access the IConfiguration application configuration?

The current version of "BlazorWasmPreRendering.Build" has no that ability, but I'll consider improving this library to be able to provide IConfiguration to the user's ConfigureServices static method if you hope it.

fingers10 commented 2 years ago

@jsakamoto

I have appsettings.json in my wwwroot and I'm binding some configuration from that and hence I need acces to configuration.

I tried with IConfiguration instead of WebAssemblyHostConfiguration. The code compiles without any error but fails on publish.

Please can you assist?

jsakamoto commented 2 years ago

@fingers10

I tried with IConfiguration instead of WebAssemblyHostConfiguration. The code compiles without any error but fails on publish.

Yeah, the current version of "BlazorWasmPreRendering.Build" cannot provide the IConfiguration to any ConfigureService() static method during the publishing process.

So, I'll improve "BlazorWasmPreRendering.Build" and make it be able to provide the IConfiguration to any ConfigureService() static method during the publishing process.

Would you please give me more days to improve it if you hope it?

Anyway, thank you for letting me know your scenario! 👍

fingers10 commented 2 years ago

Sure. I'll wait for it. Happy to hear back.

jsakamoto commented 2 years ago

@fingers10

I published the new version of "BlazorWasmPreRendering.Build".

This version will provide an IConfiguration object to the application's "ConfigureServices()" method as an argument.

Please update the package version, and please rewrite your ConfigureServices method code like this:

From:

static void ConfigureServices(..., WebAssemblyHostConfiguration configuration)
{
    ...

To:

static void ConfigureServices(..., IConfiguration configuration)
{
    ...

By the way, please remember that the pre-rendering process is a normal ASP.NET Core server-side process.

Your code runs on an ASP.NET Core server during the publishing and pre-rendering, not on a Web browser.

That means, if your code access any kind of web browser-specific objects or services at the "OnInitilized", such as invoking JavaScript, it crushes the pre-rendering process again. So you have to place that kind of code in the "OnAfterRender".

fingers10 commented 2 years ago

@jsakamoto This now worked for simple project. Howerver this fails in my production blazor project.

Web.csproj: ```xml net6.0 latest enable enable service-worker-assets.js true #body ```
Program.cs: ```cs var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging")); builder.RootComponents.Add("#body"); builder.RootComponents.Add("head::after"); ConfigureServices(builder.Services, builder.Configuration); await builder.Build().RunAsync(); static void ConfigureServices(IServiceCollection services, IConfiguration configuration) { ```
Index.razor.cs: ```cs public class IndexBase : ComponentBase, IDisposable { private readonly CancellationTokenSource _cancellationTokenSource = new(); [Inject] private IDashboardDataService DashboardDataService { get; set; } //protected override async Task OnInitializedAsync() //{ // var result = await DashboardDataService._(_cancellationTokenSource.Token); // await _(); //} protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { var result = await DashboardDataService._(_cancellationTokenSource.Token); await _(); await __(); } } ```
Error Logs: ``` Web -> C:\Users\Abdul Rahman\source\repos\fingers10\xxxx\Web\obj\Release\net6.0\browser-wasm\PubTmp\Out\ dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.11.0\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "Web" -t "Web.App" --selectorofrootcomponent "#body" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\fingers10\xxxx\Web\obj\Release\net6.0\browser-wasm\PubTmp\Out" -i "C:\Users\Abdul Rahman\source\repos\fingers10\xxxx\Web\obj\Release\net6.0\." -m "" -f "net6.0" Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object. at Toolbelt.Blazor.WebAssembly.PrerenderServer.IndexHtmlFragments.Load(String indexHtmlPath, String selectorOfRootComponent, String selectorOfHeadOutletComponent) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\IndexHtmlFragments.cs:line 65 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.BuildPrerenderingOptions(CustomAssemblyLoader assemblyLoader, CommandLineOptions commandLineOptions) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 90 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.Main(String[] args) in C:\Project\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 25 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.
(String[] args) C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.11.0\build\BlazorWasmPreRendering.Build.targets(44,5): Error MSB3073: The command "dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.11.0\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "Web" -t "Web.App" --selectorofrootcomponent "#body" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\fingers10\xxxx\Web\obj\Release\net6.0\browser-wasm\PubTmp\Out" -i "C:\Users\Abdul Rahman\source\repos\fingers10\xxxx\Web\obj\Release\net6.0\." -m "" -f "net6.0"" exited with code -532462766. ```

Am I doing anything wrong here?

fingers10 commented 2 years ago

@jsakamoto never mind. I figured out the build error issue. I apologise. I forgot to add id="body" in my <body> tag in index.html. After changing to <body id="body" .. publish succeeded. But here comes the new surprise. The index.html has no prerendered content.

Index.html after publish:

index.html ```html Galla | The Shopkeeper App

Loading...

```

index.html is same before and after publish.

Now please can you further assist me on this?

jsakamoto commented 2 years ago

@fingers10 I'm sorry I had mistaken too.

(see also the commit message of: 105bc7cacb5abb6910407efc076633b50927e973)

I've never tried your scenario yet, but anyway please consider try to the latest version if you can.

fingers10 commented 2 years ago

Sure I'll check and get back.

fingers10 commented 2 years ago

@jsakamoto still the same. No prerendering content in index.html after publish

jsakamoto commented 2 years ago

Could you execute the dotnet publish command below on your project folder?

dotnet publish -c:Release -v:n

I'm guessing the error message "The HTTP status code was not OK. (it was InternalServerError.)" would be shown in the build process output.

image

If so, you should be able also to see the prerendering command line text in the build process output.

image

Then please copy that prerendering command line text, paste it in the terminal console, append the "-k" switch, and press the Enter key. The prerendering server will be launched and never exit until you enter the Ctrl+C key combination in the terminal console by the "-k" switch effect.

image

After doing that, please open the URL http://127.0.0.1:5050/ on your web browser. Then you will see the details of errors on the browser, like below.

image

I appreciate it if you report the details of the errors.

fingers10 commented 2 years ago

@jsakamoto Sorry for the delayed response.

Here are the requested details.

image

Error: > FileLoadException: Could not load file or assembly 'Microsoft.AspNetCore.Components.WebAssembly, Version=6.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
Stack Trace:: ``` System.IO.FileLoadException: Could not load file or assembly 'Microsoft.AspNetCore.Components.WebAssembly, Version=6.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. at System.Runtime.Loader.AssemblyLoadContext.InternalLoad(ReadOnlySpan`1 arrAssembly, ReadOnlySpan`1 arrSymbols) at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream(Stream assembly, Stream assemblySymbols) at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream(Stream assembly) at Toolbelt.Blazor.WebAssembly.PrerenderServer.CustomAssemblyLoader.LoadAssemblyFrom(String assemblyDir, String assemblyName) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\CustomAssemblyLoader.cs:line 31 at Toolbelt.Blazor.WebAssembly.PrerenderServer.CustomAssemblyLoader.<>c__DisplayClass1_0.<.ctor>b__1(String dir) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\CustomAssemblyLoader.cs:line 20 at System.Linq.Enumerable.SelectListIterator`2.MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext() at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found) at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Toolbelt.Blazor.WebAssembly.PrerenderServer.CustomAssemblyLoader.<.ctor>b__1_0(AssemblyLoadContext context, AssemblyName name) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\CustomAssemblyLoader.cs:line 19 at System.Runtime.Loader.AssemblyLoadContext.GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName) at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingEvent(AssemblyName assemblyName) at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) ```
Error: >FileLoadException: Could not load file or assembly 'Microsoft.AspNetCore.Components.WebAssembly, Version=6.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (0x80131621)
Stack Trace: ``` System.IO.FileLoadException: Could not load file or assembly 'Microsoft.AspNetCore.Components.WebAssembly, Version=6.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (0x80131621) File name: 'Microsoft.AspNetCore.Components.WebAssembly, Version=6.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.IO.FileLoadException: Could not load file or assembly 'Microsoft.AspNetCore.Components.WebAssembly, Version=6.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. at System.Runtime.Loader.AssemblyLoadContext.InternalLoad(ReadOnlySpan`1 arrAssembly, ReadOnlySpan`1 arrSymbols) at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream(Stream assembly, Stream assemblySymbols) at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream(Stream assembly) at Toolbelt.Blazor.WebAssembly.PrerenderServer.CustomAssemblyLoader.LoadAssemblyFrom(String assemblyDir, String assemblyName) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\CustomAssemblyLoader.cs:line 31 at Toolbelt.Blazor.WebAssembly.PrerenderServer.CustomAssemblyLoader.<>c__DisplayClass1_0.<.ctor>b__1(String dir) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\CustomAssemblyLoader.cs:line 20 at System.Linq.Enumerable.SelectListIterator`2.MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext() at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found) at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Toolbelt.Blazor.WebAssembly.PrerenderServer.CustomAssemblyLoader.<.ctor>b__1_0(AssemblyLoadContext context, AssemblyName name) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\CustomAssemblyLoader.cs:line 19 at System.Runtime.Loader.AssemblyLoadContext.GetFirstResolvedAssemblyFromResolvingEvent(AssemblyName assemblyName) at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingEvent(AssemblyName assemblyName) at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName) at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType) at System.Signature..ctor(Void* pCorSig, Int32 cCorSig, RuntimeType declaringType) at System.Reflection.RuntimePropertyInfo.get_Signature() at System.Reflection.RuntimePropertyInfo.get_PropertyType() at Microsoft.AspNetCore.Components.ComponentFactory.CreateInitializer(Type type) at Microsoft.AspNetCore.Components.ComponentFactory.PerformPropertyInjection(IServiceProvider serviceProvider, IComponent instance) at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider serviceProvider, Type componentType) at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateComponent(Type componentType) at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.CreateInitialRenderAsync(Type componentType, ParameterView initialParameters) at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.RenderComponentAsync(Type componentType, ParameterView initialParameters) at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c__11`1.<b__11_0>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.ViewFeatures.StaticComponentRenderer.PrerenderComponentAsync(ParameterView parameters, HttpContext httpContext, Type componentType) at Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.StaticComponentAsync(HttpContext context, Type type, ParameterView parametersCollection) at Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.RenderComponentAsync(ViewContext viewContext, Type componentType, RenderMode renderMode, Object parameters) at AspNetCoreGeneratedDocument.Pages__Host.ExecuteAsync() in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Pages\_Host.cshtml:line 5 at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context) at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts) at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context) ```

Prerendering-InternalServerError.zip

I have attached the complete HTML file for your reference.

jsakamoto commented 2 years ago

@fingers10 Thank you for letting me know!

I fixed this problem and published the new version.

Would you try it out?

Again, thank you for your contributions! 👍

fingers10 commented 2 years ago

@jsakamoto Sure I'll check and get back. I have one more question. This package supports PWA apps and also fixed integrity issues?

jsakamoto commented 2 years ago

@fingers10

This package supports PWA apps and also fixed integrity issues?

Yes, this package has been supported PWA apps correctly since the v.1.0.0-preview.12.0.

Of course, it has not been experienced a lot of real-world tests, but in my few cases, it looks to be working fine for PWA offline support.

fingers10 commented 2 years ago

@jsakamoto This time I'm getting new error related to URI.

Console output: ``` Start fetching...[http://127.0.0.1:5050] Getting http://127.0.0.1:5050/... Getting http://127.0.0.1:5050/blogs/blazor-wasm-lazy-loading... The HTTP status code was not OK. (it was InternalServerError.) Getting http://127.0.0.1:5050/blogs/blazor-wasm-styles-and-css-isolation... The HTTP status code was not OK. (it was InternalServerError.) Getting http://127.0.0.1:5050/blogs/blazor-wasm-javascript-interop-and-isolation... The HTTP status code was not OK. (it was InternalServerError.) Getting http://127.0.0.1:5050/blogs/blazor-wasm-dark-theme-and-light-theme... Getting http://127.0.0.1:5050/blogs/blazor-wasm-exception-handling-and-error-boundary... The HTTP status code was not OK. (it was InternalServerError.) Getting http://127.0.0.1:5050/blogs/blazor-wasm-error-logging... Getting http://127.0.0.1:5050 void(0)... Unhandled exception. System.UriFormatException: Invalid URI: Invalid port specified. at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions) at System.Uri..ctor(String uriString, UriKind uriKind) at System.Net.Http.HttpClient.CreateUri(String uri) at Toolbelt.Blazor.WebAssembly.PrerenderServer.StaticlizeCrawler.SaveToStaticFileAsync(String path) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\StaticlizeCrawler.cs:line 0 at Toolbelt.Blazor.WebAssembly.PrerenderServer.StaticlizeCrawler.SaveToStaticFileAsync(String path) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\StaticlizeCrawler.cs:line 86 at Toolbelt.Blazor.WebAssembly.PrerenderServer.StaticlizeCrawler.SaveToStaticFileAsync(String path) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\StaticlizeCrawler.cs:line 86 at Toolbelt.Blazor.WebAssembly.PrerenderServer.StaticlizeCrawler.SaveToStaticFileAsync(String path) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\StaticlizeCrawler.cs:line 86 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.PreRenderToStaticFilesAsync(CommandLineOptions commandLineOptions, CustomAssemblyLoader assemblyLoader, BlazorWasmPrerenderingOptions prerenderingOptions) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 50 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.Main(String[] args) in C:\Projects\Blazor\BlazorWasmPreRendering.Build\BlazorWasmPreRendering.Build\Program.cs:line 28 at Toolbelt.Blazor.WebAssembly.PrerenderServer.Program.
(String[] args) C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.17.0\build\BlazorWasmPreRendering.Build.targets(47,5): Error MSB3073: The command "dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.17.0\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "Web" -t "Web.App" --selectorofrootcomponent "#app,app" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\ilovedotnet\Web\obj\Release\net6.0\browser-wasm\PubTmp\Out" -i "C:\Users\Abdul Rahman\source\repos\ilovedotnet\Web\obj\Release\net6.0\." -m "" -f "net6.0" --serviceworkerassetsmanifest "service-worker-assets.js" -e "Production" -o "AppendHtmlExtension"" exited with code -532462766. ```

I'll develop a minimal repro sample and get back

fingers10 commented 2 years ago

@jsakamoto , I figured out. If any page has link with url fragment, then prerendering of that page fails.

<NavLink href="blogs/blazor-wasm-exception-handling-and-error-boundary#global-exception-handling" Match="NavLinkMatch.All">
    Global Exception Handling
</NavLink>

Parsing of URL with fragment fails?

jsakamoto commented 2 years ago

@fingers10 Thank you for a lot of reporting!

I improved this package and released the new version.

https://www.nuget.org/packages/BlazorWasmPreRendering.Build/1.0.0-preview.18.0

In this version, this package shows the response content string when the HTTP status code does not represent success.

image

I expect that improvement will be helpful to investigate and resolve server errors during the pre-rendering process.

And, this version has been supported the "BlazorWasmPrerenderingKeepServer" MSBuild property option.

Usually, the pre-rendering server is stopped automatically after the fetching process is completed. Instead, if you specified the "BlazorWasmPrerenderingKeepServer" MSBuild property to "true", the pre-rendering server keeps running.

dotnet publish -c:Release -p:BlazorWasmPrerenderingKeepServer=true

During the pre-rendering server is running, you can investigate the Blazor apps running on the pre-rendering server.

image

Sorry to bother you, I appreciate it if you try the latest version of this package again.

fingers10 commented 2 years ago

@jsakamoto, Prerendering and Publish is successful now.

  1. I noticed that prerendering is not replacing Loading... text in #app element. Instead it's appending with #app element content.

image

Is this the expected behavior?

  1. Inside <head> Tag, I noticed that a script tag is getting appeneded after all content inside <head>
<!-- %%-PRERENDERING-HEADOUTLET-END-%% -->
<script src="data:text/javascript;base64,KGZ1bmN0aW9uKG4sdCxpKXtmb3IodmFyIGY9bi5jcmVhdGVOb2RlSXRlcmF0b3IobiwxMjgpLHIsZSx1O2YubmV4dE5vZGUoKTspaWYocj1mLnJlZmVyZW5jZU5vZGUsdC50ZXN0KHIudGV4dENvbnRlbnQudHJpbSgpKSl7d2hpbGUoaT1yLm5leHRTaWJsaW5nKWlmKGU9aS50ZXh0Q29udGVudC50cmltKCksaS5yZW1vdmUoKSx0LnRlc3QoZSkpYnJlYWs7ci5yZW1vdmUoKTticmVha311PUFycmF5LmZyb20obi5xdWVyeVNlbGVjdG9yQWxsKCJzY3JpcHQiKSkucG9wKCk7dSYmdS5yZW1vdmUoKX0pKGRvY3VtZW50LC9eJSUtUFJFUkVOREVSSU5HLUhFQURPVVRMRVQtKEJFR0lOfEVORCktJSUkLyk7"></script>
</head>

Please can you explain on why this is getting added? My content-security-policy is not allowing this script to be executed.

  1. I also noticed that the respective index.hml pages are not stored inside correct folder path. For example,
blogs/article-1
blogs/article-2

Both the above urls get's saved inside blogs folder as article-1.html and article-2.html but it has to be saved in the below structure. I have previously worked with react-snap which will prerender and follow the below structure.

wwwroot/blogs/article-1/index.html
wwwroot/blogs/article-2/index.html

Please correct me if I'm wrong.

  1. And I noticed the below error from the prerendering output,
Getting http://127.0.0.1:5050 void(0)...
  [ERROR] The request URL (http://127.0.0.1:5050 void(0)) was not valid format.
Fetching complete.
jsakamoto commented 2 years ago

@fingers10

  1. I noticed that prerendering is not replacing Loading... text in #app element. Instead it's appending with #app element content.

That is by design at this time.

The prerendered contents can be visible immediately. But while a few seconds, it can't interact with user operations until the Blazor runtime load all of the required files and has been started runtime.

Therefore, the "BlazorWasmPreRendering.Build" keeps the "Loading..." contents and makes the prerendered contents to be invisible for humans by CSS styling. After the Blazor runtime has started, the contents inside the #app element are overwritten by the Blazor runtime.

That means only search engine crawlers can see the prerendered contents. So the "BlazorWasmPreRendering.Build" aims only at SEO at this time.

However, if the developer knows these backgrounds, the developer does not need to take that strategy.

For example, the "ClickOnce Get" site ( https://clickonceget.azurewebsites.net/ ) that is built on Blazor WebAssembly shows prerendered contents to users immediately, but the buttons are disabled by CSS styling until the Blazor WebAssembly engine has been started.

👉

If developers understand this technic and can implement that controlling user interaction, the "BlazorWasmPreRendering.Build" should replace all of the contents inside the #app element without keeping "Loading..." contents.

Unfortunately, the "BlazorWasmPreRendering.Build" doesn't provide the option that replaces all of the contents inside of the #app element without keeping "Loading..." contents at this time.

However, currently, I'm considering implementing that option.

Appendix: I know the "WebAssemblyPrerendered" render mode and transferring the state from the server-side prerendering process to the client-side Blazor WebAssembly process. I'll also consider the "WebAssemblyPrerendered" render mode scenario.

fingers10 commented 2 years ago

@jsakamoto many thanks for your response. Please can you help me out with other queries in my previous comment?

jsakamoto commented 2 years ago

@fingers10

  1. Inside <head> Tag, I noticed that a script tag is getting appeneded after all content inside <head>

This script deletes the contents that the <HeadContent> prerendered.

At first, the <HeadContent> prerender its contents as the end of children of the <head> element on the publishing process because the HeadOutlet component is instructed to insert it into "head::after" usually.

<head>
  ...
  <!-- %%-PRERENDERING-HEADOUTLET-BEGIN-%% -->
  <meta name=”description” content=”rendered by HeadContent” />
  <!-- %%-PRERENDERING-HEADOUTLET-END-%% -->
</head>

After the browser loaded this HTML, the Blazor WebAssembly engine started and did the initial rendering.

At that time, the <HeadContent> will be rendered dynamically on the client-side process into the insertion point "head::after".

These steps cause the same contents to appear twice, like this!

<head>
  ...
  <!-- %%-PRERENDERING-HEADOUTLET-BEGIN-%% -->
  <meta name=”description” content=”rendered by HeadContent” />
  <!-- %%-PRERENDERING-HEADOUTLET-END-%% -->
  <meta name=”description” content=”rendered by HeadContent” />
</head>

To avoid this problem, the JavaScript code that you asked me removes the prerendered head contents.

Please see also: https://github.com/jsakamoto/BlazorWasmPreRendering.Build/issues/7

Appendix-1: If I could use the "WebAssemblyRendered" render mode at the prerendering process, it doesn't cause that problem. Because the <HeadContent> can manage head content appropriately on the "WebAssemblyRendered" render mode. However, the "WebAssemblyRendered" render mode is not compatible with a typical startup configuration of Blazor WebAssembly apps. So I could not choose the "WebAssemblyRendered" render mode.

Appendix-2: If the JavaScript code you asked me can not be executed due to your site security policy, I might be able to provide another option that loading that JavaScript via normal HTTP protocol instead of "data:" protocol in the future version of this package.

fingers10 commented 2 years ago

@jsakamoto , I think you missed to respond 3rd and 4th query in my original comment. Please can you assist?

jsakamoto commented 2 years ago

@fingers10

Sorry too late! Thank you for waiting for my answer.

  1. I also noticed that the respective index.hml pages are not stored inside correct folder path.

I'm sorry, but I might not understand your question correctly due to my lack of reading skills. But anyway, I'll try to explain it.

"dotnet publish" command targetting Blazor WebAssembly apps generates all of the static contents under the "wwwroot" folder inside of the target of publishing folder.

For example, if you executed the command targetting a Blazor WebAssembly project as below,

> dotnet publish -o:/foo/bar

the result of folders and files structure will be like below.

/foo
  /bar
    /wwwroot
      index.html

That is the standard behavior of ASP.NET Core projects, including Blazor WebbAssembly projects.

And, if that Blazor WebAssembly app has route URLs like https://example.com/blogs/article-1 and https://example.com/blogs/article-2, the "BlazorWasmPreRendering.Build" package will save them to static files the same way with ASP.NET Core's standard folders and files structure, like this.

/foo
  /bar
    /wwwroot
      index.html
      /blogs
        /artice-1
          index.html
        /artice-2
          index.html

That behavior will be what almost ASP.NET Core Web application developers expect, I think.

P.S. If you specify the "BlazorWasmPrerenderingOutputStyle" MSBuild property option to "AppendHtmlExtension", the published folders and files structure will be like this:

/foo
  /bar
    /wwwroot
      index.html
      /blogs
        artice-1.html
        artice-2.html

If your publishing result what you saw is different from my explanation above, please let me know with more details. In that case, that means the "BlazorWasmPreRendering.Build" package might have some software bugs, and I'll fix them.

jsakamoto commented 2 years ago

@fingers10

  1. And I noticed the below error from the prerendering output,

This means one or more pages in your app contains contents like a <a href="javascript:void(0)">~</a> anchor tag element.

The using <a href="javascript:void(0)">~</a> is a well-known technic in the font-end web dev to prevent a default behavior when the anchor tag is clicked.

See also: https://stackoverflow.com/questions/1291942/what-does-javascriptvoid0-mean

Of course, the href property of a <a href="javascript:void(0)">~</a> anchor tag element doesn't point out to navigatble URL. So the "BlazorWasmPreRendering.Build" package just reports it as an error and ignores it on that's crawling process.

fingers10 commented 2 years ago

@jsakamoto, Prerendering and Publish is successful now.

  1. I noticed that prerendering is not replacing Loading... text in #app element. Instead it's appending with #app element content.

image

Thanks for your response. But I think this needs to be considered because when the page gets listed in search result then it will show Loading... text.

  1. Inside <head> Tag, I noticed that a script tag is getting appeneded after all content inside <head>
<!-- %%-PRERENDERING-HEADOUTLET-END-%% -->
<script src="data:text/javascript;base64,KGZ1bmN0aW9uKG4sdCxpKXtmb3IodmFyIGY9bi5jcmVhdGVOb2RlSXRlcmF0b3IobiwxMjgpLHIsZSx1O2YubmV4dE5vZGUoKTspaWYocj1mLnJlZmVyZW5jZU5vZGUsdC50ZXN0KHIudGV4dENvbnRlbnQudHJpbSgpKSl7d2hpbGUoaT1yLm5leHRTaWJsaW5nKWlmKGU9aS50ZXh0Q29udGVudC50cmltKCksaS5yZW1vdmUoKSx0LnRlc3QoZSkpYnJlYWs7ci5yZW1vdmUoKTticmVha311PUFycmF5LmZyb20obi5xdWVyeVNlbGVjdG9yQWxsKCJzY3JpcHQiKSkucG9wKCk7dSYmdS5yZW1vdmUoKX0pKGRvY3VtZW50LC9eJSUtUFJFUkVOREVSSU5HLUhFQURPVVRMRVQtKEJFR0lOfEVORCktJSUkLyk7"></script>
</head>

Thanks for your response. This I resolved by adding data for script in my content security policy.

  1. I also noticed that the respective index.hml pages are not stored inside correct folder path. For example,
blogs/article-1
blogs/article-2

Both the above urls get's saved inside blogs folder as article-1.html and article-2.html but it has to be saved in the below structure. I have previously worked with react-snap which will prerender and follow the below structure.

wwwroot/blogs/article-1/index.html
wwwroot/blogs/article-2/index.html

Thanks for your response. You understood the question correctly and your reading skills are good. BlazorWasmPrerenderingOutputStyle resolved the issue.

  1. And I noticed the below error from the prerendering output,
Getting http://127.0.0.1:5050 void(0)...
  [ERROR] The request URL (http://127.0.0.1:5050 void(0)) was not valid format.
Fetching complete.

Again thanks for the response.

Are you on Linkedin? is there any other ways to contact you other than GitHub? In case you wanna share contact details privately, you can drop a message to me on my Linkedin Profile.

jsakamoto commented 2 years ago

@fingers10

But I think this needs to be considered because when the page gets listed in search result then it will show Loading... text.

Yes, that's right.

So today, I provided the option that developers can choose whether keep the "Loading..." contents in prerendered output HTML files or not.

Please check the "BlazorWasmPreRendering.Build" version 1.0.0-preview.20.0 if you are interested in it.

You can see the detailed documents at the following link.

fingers10 commented 2 years ago

@jsakamoto, publish failed with the following message,

Console output: ``` Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:04.70 Start fetching...[http://127.0.0.1:5050] Getting http://127.0.0.1:5050/... Getting http://127.0.0.1:5050/blogs/webapi-importance-of-status-code... Getting http://127.0.0.1:5050/channels/webapi... [WARNING] The requested URL (javascript: void(0)) was not navigatable. Getting http://127.0.0.1:5050/blogs/blazor-wasm-exception-handling-and-error-boundary... Getting http://127.0.0.1:5050/channels/blazor... Getting http://127.0.0.1:5050/blogs/blazor-wasm-app-settings... Getting http://127.0.0.1:5050/blogs/blazor-wasm-error-logging... Getting http://127.0.0.1:5050/blogs/blazor-wasm-dark-theme-and-light-theme... Getting http://127.0.0.1:5050/blogs/blazor-wasm-javascript-interop-and-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-javascript-interop-and-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-javascript-interop-and-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-javascript-interop-and-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-javascript-interop-and-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-styles-and-css-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-styles-and-css-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-styles-and-css-isolation... Getting http://127.0.0.1:5050/blogs/blazor-wasm-lazy-loading... Getting http://127.0.0.1:5050/blogs/blazor-wasm-lazy-loading... Getting http://127.0.0.1:5050/blogs/blazor-wasm-lazy-loading... Getting http://127.0.0.1:5050/talks/blazor-spa-from-aspnet-family... Getting http://127.0.0.1:5050/channels/talk... Getting http://127.0.0.1:5050/blogs/blazor-wasm-exception-handling-and-error-boundary... Getting http://127.0.0.1:5050/blogs/blazor-wasm-exception-handling-and-error-boundary... Getting http://127.0.0.1:5050/blogs/blazor-wasm-exception-handling-and-error-boundary... Getting http://127.0.0.1:5050/blogs/blazor-wasm-error-logging/... Getting http://127.0.0.1:5050/disclaimer... Getting http://127.0.0.1:5050ab%64%75lrah%6Dan.s%6D%73%69@gm%61il%2Ec%6F%6D... [ERROR] The requested URL (http://127.0.0.1:5050ab%64%75lrah%6Dan.s%6D%73%69@gm%61il%2Ec%6F%6D) was not valid format. INFORMATION =========== The crawler encountered whatever errors. If you want to keep running the pre-rendering server process for debugging it on live, you can do that by setting the "BlazorWasmPrerenderingKeepServer" MSBuild property to "true". ex) dotnet publish -p:BlazorWasmPrerenderingKeepServer=true Fetching complete. C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.21.0\build\BlazorWasmPreRendering.Build.targets(55,5): Error MSB3073: The command "dotnet "C:\Users\Abdul Rahman\.nuget\packages\blazorwasmprerendering.build\1.0.0-preview.21.0\build\../tools/net6.0/blazorwasm-prerendering-server.dll" -a "Web" -t "Web.App" --selectorofrootcomponent "#app,app" --selectorofheadoutletcomponent "head::after" -p "C:\Users\Abdul Rahman\source\repos\xxxx\Web\obj\Release\net6.0\browser-wasm\PubTmp\Out" -i "C:\Users\Abdul Rahman\source\repos\xxxx\Web\obj\Release\net6.0\." -m "Toolbelt.Blazor.HeadElement.ServerPrerendering,,6.0.2" -f "net6.0" --serviceworkerassetsmanifest "service-worker-assets.js" -e "Production" -o "IndexHtmlInSubFolders" -d -u "/disclaimer"" exited with code 1. 5>Build failed. Check the Output window for more details. ========== Build: 4 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== ========== Publish: 0 succeeded, 1 failed, 0 skipped ========== ```
jsakamoto commented 2 years ago

@fingers10 Thank you for the report!

The crawler maybe encountered a mailto:// link.

I'll fix it, and moreover, I'll consider once again how to traverse hyperlinks more carefully than before.

jsakamoto commented 2 years ago

@fingers10

I released the fixed version v.1.0.0-preview.22.0 just now.

I appreciate it if you try it out. Again, I'd say many thanks for your contributions!

fingers10 commented 2 years ago

@jsakamoto that works. Now Loading Text doesn't appear.

fingers10 commented 2 years ago

@jsakamoto out of curiosity I'm asking. index.html without loading text is great. We have same content in index.html once the blazor engine kiks in. But if we load any other page directly for example, www.jsakamoto.com/about in this case index.html content appears and once after blazor engine kicks in actual about page appears. Is it a good user experience?

jsakamoto commented 2 years ago

@fingers10

If my memory is correct, your project is a PWA with offline support, right?

If so, that experience may be caused by a service worker's script.

The default implementation of a service worker script created by standard ASP.NET Core project templates should be like this:

// This is "service-worker.published.js"
....
async function onFetch(event) {
  ...
  const shouldServeIndexHtml = event.request.mode === 'navigate';
  const request = shouldServeIndexHtml ? 'index.html' : event.request;
  ...

That default implementation will always return "index.html" forcibly whatever any URLs of requests as a fallback behavior.

Therefore, when you request the ULR path "/about", the service worker script will return "index.html" even though the "about.html" exists.

To correct this behavior, please try to change the service worker script like this:

// This is "service-worker.published.js"
....
async function onFetch(event) {
  ...
  // 👇 change this line.
  const shouldServeIndexHtml = event.request.mode === 'navigate' && new URL(event.request.url).pathname === '/';
  const request = shouldServeIndexHtml ? 'index.html' : event.request;
  ...

I hope this information will be helpful for you.

fingers10 commented 2 years ago

@jsakamoto, Many thanks. I'll try at the above response.

In PWA apps, index.html always loads the stale content even though published index.html has new content. Is there any way to forcibly fetch index.html from server when online and load index.html from cache when offline?

In general while publishing, if <BlazorWasmPrerenderingDeleteLoadingContents> is enabled, will it be good to replace loading text only in index.html and for remaining paths like /about/index.html can we replace loading text with respective page content?

Here is my view. Please share your thoughts on this.

when <BlazorWasmPrerenderingDeleteLoadingContents> is enabled, wwwroot -> index.html - Replace Loading Text with index.html content

when <BlazorWasmPrerenderingDeleteLoadingContents> is enabled, For any other index.html like, wwwroot/about -> index.html - Replace Loading Text with about page content wwwroot/blog/article1 -> index.html - Replace Loading Text with article1 page content wwwroot/blog/article2 -> index.html - Replace Loading Text with article2 page content

This way crawlers will have correct snapshot of all the pages.

And is there any other way we can avoid flickering effect when directly opening any routes other than index.html because index.html will have same content before and after blazor engine kicks in. For remaining pages index.html loads and then actual page loads.

jsakamoto commented 2 years ago

@fingers10

In PWA apps, index.html always loads the stale content even though published index.html has new content. Is there any way to forcibly fetch index.html from server when online and load index.html from cache when offline?

To my knowledge, the updated index.html contents in a PWA will be definitely reloaded automatically after you re-published the project, but the important thing is it will only happen after all browser instances are exited.

The browser's "reload" button doesn't have any effect.

I forget the source of that information, but I remember that I heard it is by the design of some web browser products.

However, if you are developing that PWA, you can reload forcibly using the Chromium browser's developer tools with the following steps.

  1. Turn on the "Disable cache" check box in the "Network" tab of the Chromium browser's developer tools window.
  1. Turn on the "Update on reload" check box in the "Service Workers" section of the "Application" tab.
  1. Click the "Clear site data" button in the "Storage" section of the "Application" tab.
  1. Right-click the browser's "Reload" button, and click the "Empty cache and hard refresh" menu item.
jsakamoto commented 2 years ago

@fingers10

In general while publishing, if is enabled, will it be good to replace loading text only in index.html and for remaining paths like /about/index.html can we replace loading text with respective page content?

No, all pre-rendered output will be replaced "Loading..." text with respective page content even it is the root index.html.

Particularly, the "Loading..." text of the root "index.html" file will be replaced with the result content of the request to the "/" URL path.

jsakamoto commented 2 years ago

@fingers10

And is there any other way we can avoid flickering effect when directly opening any routes other than index.html because index.html will have same content before and after blazor engine kicks in. For remaining pages index.html loads and then actual page loads.

The published results on usual Blazor WebAssembly apps with this NuGet package will behave without flickering, not as you reported.

I came up with two reasons for those flickering behavior.

  1. As I already said in the previous reply, it might be caused by PWA service workers.
    If that is true, your app will be unflickerly after fixing the "service-worker.published.js".

  2. The web server you used might not have the ability to fall back the request URL path to a rewritten URL that appended the ".html" file extension.
    If that is true, one of the solutions is don't set the BlazorWasmPrerenderingOutputStyle MSBuild property to AppendHtmlExtension when the project is publishing.
    Or, configuring the web server appropriately might also be one of the solutions.

fingers10 commented 2 years ago

@jsakamoto, is it possible for you to let me know your availability for a scheduled call?

jsakamoto commented 2 years ago

@fingers10

First of all, basically, please remember that this package is my hobby project using my free time, so I can't spend much time.

And, I'm a native Japanese speaker, not a native English speaker. I can't speak and hear English fluently at all. I often use machine translation a lot to read your post and write my reply. I watched your technical session video via your post on LinkedIn, but unfortunately, I could not almost recognize what you said in English. (English subtitle of videos is helpful for me to understand what the speaker said.)

And, I live in Japan, so the time zone for me is Japan Standard Time, JST, UTC+9:00.

But I'm a little bit interested in your proposal even though some negative points are above. Just curious, it is a little bit exciting for me talking with people who live over the sea because it is unusual for my life.

If you understand the above list well and still would like to make a scheduled call, would you like to send messages to me via the LinkedIn chatting window? I'll try to make a time.

Of course, I don't mind changing your mind to cancel making a scheduled call for the above reasons.

fingers10 commented 2 years ago

@jsakamoto no worries. sorry to trouble you. we can connect once we get comfortable. till then lets discuss here. Coming to PWA reload. Do all the consumers of app needs to enable update on reload for this to take effect?

jsakamoto commented 2 years ago

@fingers10

Do all the consumers of app needs to enable update on reload for this to take effect?

No, all the consumers of apps usually do not need to enable the update on reload option. The update on reload option is aimed at the app developer.

On the default implementation of the wwwroot/service-worker.published.js, the browser's "Reload" button (or Ctrl+R / F5 / Ctrl + F5 keyboard shortcuts) won't affect refreshing PWA offline apps.

Instead, once all browser processes are exited, or all browser's tabs navigated away from the app, the PWA app will be refreshed automatically next time access. There is no needed press the browser's "Reload" button, Ctrl+R, or so on.

The Microsoft Docs site at the following link must be helpful for you.

Again, that behavior depends on the default implementation of the wwwroot/service-worker.published.js.

We should be able to control the cache behavior of PWA apps, such as choosing cache strategies, but I'm not familiar with it at this time.

About this topic, to ask in the "Stack Overflow" site might be a better way than to discuss in this issue thread.

fingers10 commented 2 years ago

Hi @jsakamoto Publish fails after upgrading Microsoft.AspNetCore.Components.WebAssembly and Microsoft.AspNetCore.Components.WebAssembly.DevServer to 6.0.6.

I just updated all Nuget packages and Visual Studio to latest version. And on publish I get the following error.

C:\Program Files\dotnet\sdk\6.0.301\Sdks\Microsoft.NET.Sdk.BlazorWebAssembly\targets\Mi crosoft.NET.Sdk.BlazorWebAssembly.6_0.targets(614,5): error MSB6006: "C:\Program Files\ dotnet" exited with code 1. [C:\Users\User\source\repos\ilovedotnet\Web\Web.csp roj]