microsoft/fluentui-blazor

MAUI Project can not import web-components script automatically

RiuHDuo opened this issue · 11 comments

I created a MAUI-Blazor project with VS 2022.
and installed Microsoft.Fast.Components.FluentUI 2.3.2
image

Add @using Microsoft.Fast.Components.FluentUI in _Imports.razor.
image

Add tag in index.html
image

Followed documents modified Promgram.cs
image

Add sample code in index.razor

<FluentCard Style="padding: 1.5rem; width: 400px; height: 250px; ">
  <h2>Hello World!</h2>
  <FluentButton Appearance="@Appearance.Accent">Click Me</FluentButton>
</FluentCard>

App can not work well.
image

If add web-component script in index.html.
image

it will work well.
image

In v2.3.4, this issue can still be reproduced. And same with (WPF) Blazor app

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        builder.Services.AddMauiBlazorWebView();

        builder.Services.AddFluentUIComponents(options =>
        {
            options.HostingModel = BlazorHostingModel.Hybrid;
            options.IconConfiguration = new(true)
            {
                Sizes = new[] { IconSize.Size20, IconSize.Size24, IconSize.Size32 },
                Variants = new[] { IconVariant.Filled, IconVariant.Regular }
            };
            options.EmojiConfiguration = new(true)
            {
                Groups = new[] { EmojiGroup.Activities, EmojiGroup.Flags },
                Styles = new[] { EmojiStyle.Color }
            };
        });

        builder.Services.AddScoped<IStaticAssetService, FileBasedStaticAssetService>();

#if DEBUG
        builder.Services.AddBlazorWebViewDeveloperTools();
        builder.Logging.AddDebug();
#endif


        return builder.Build();
    }
}

Looks like the root cause for this issue is the same as for #327.

Microsoft.Fast.Components.FluentUI package has an initializer Microsoft.Fast.Components.FluentUI.lib.module.js which loads web-components.js, but this initializer is ignored by Blazor Hybrid.

Build generates [AppName].modules.json file (bin[Configuration][FW][Platform]\AppX\wwwroot[AppName].modules.json) and populates it with found initilizers, but blazor.webview.js doesn't use this file.
It loads initializers from '_framework/blazor.modules.json' instead. blazor.modules.json contains an empty array, it's embeded as resource in Microsoft.AspNetCore.Components.WebView and provided to blazor.webview.js by WebViewManager as is - array of initializers is always empty.

As sort of PoC, replaced '_framework/blazor.modules.json' with 'MauiApp1.modules.json', rebuilt Microsoft.AspNetCore.Components.WebView and copied new version into bin folder:

image

Microsoft.Fast.Components.FluentUI.lib.module.js was loaded and controls initialized properly

@andreisaperski Can you test if custom web component events (like accordion change event) work with this setup as well?

Copied content of AccordionDefault.razor into Index.razor of MAUI App, initial state:

image

After click on 'Panel two':
image

Handler for @onaccordionchange was called and Accordion raised OnAccordionItemChange

So if people want to use the library in MAUI, we just need to tell them to compile their own WebView and everything works! 🤣🤣

There's another option )
image

@andreisaperski please chime in on the issue in the aspnetcore repo I linked to above

@vnbaaij not sure if i can add anything there, the comment you linked there, reflects all i have

There's a simpler workaround: intercept '_framework/blazor.modules.json' and provide proper JS initializers file (created by build). You can drop this initializersLoader.windows.js into wwwroot folder of app and add script tag for it to index.html right before '_framework/blazor.webview.js' tag:

<script app-name="FluentUI.Demo.Hybrid.MAUI" src="./_content/FluentUI.Demo.Hybrid.Shared/js/initializersLoader.windows.js"></script>
<script src="_framework/blazor.webview.js"></script>

'app-name' attribute needs to match app's assembly name - initializersLoader uses 'app-name' to resolve name of the file with initializers.
initializersLoader replaces 'fetch' function with another one which provides the right file instead of empty blazor.modules.json. 'fetch' is restored to its original state once '_framework/blazor.modules.json' request is intercepted.

When original issue is resolved, all that need to be done is to remove the tag and the script.

Adding these instructions to the Blazor Hybrid section in the readme!!

Closing this as we now have a workaround. See https://github.com/microsoft/fluentui-blazor#tempory-workaround-for-maui-issues for the details