Coder Social home page Coder Social logo

smapiot / piral.blazor Goto Github PK

View Code? Open in Web Editor NEW
53.0 9.0 16.0 1.46 MB

All .NET things to make Blazor work seamlessly in microfrontends using Piral. :jigsaw:

Home Page: https://piral.io

License: MIT License

C# 71.55% HTML 5.96% TypeScript 20.49% JavaScript 0.39% SCSS 1.36% PowerShell 0.05% Shell 0.05% CSS 0.14%
piral blazor aspnet-core webassembly microfrontends spa plugin hacktoberfest

piral.blazor's Introduction

Piral Logo

Piral.Blazor · GitHub License Build Status GitHub Tag GitHub Issues Gitter Chat Feed Status

All .NET things to make  Blazor work seamlessly in microfrontends using  Piral.

This is the branch for Blazor 8.0 with .NET 8.0. If you want to switch to Blazor with the older .NET Core 3.2, please refer to the blazor-3.2, blazor-5.0, blazor-6.0, orblazor-7.0 branch.

Getting Started

You'll also find some information in the piral-blazor package.

Creating a Blazor Pilet

We recommend that you watch the video on scaffolding from the standard VS template before you go over the details below.

In general, to create a Blazor pilet using Piral.Blazor, two approaches can be used:

1. From Scratch

In this case, it is highly recommended to use our template. More information and installation instructions can be found in Piral.Blazor.Template.

2. Transforming an Existing Application

In this case, follow these steps:

  1. Add a PiralInstance property to your .csproj file (The Piral instance name should be the name of the Piral instance you want to use, as it is published on npm.)

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <PiralInstance>my-piral-instance</PiralInstance>
    </PropertyGroup>

    (You can optionally also specify an NpmRegistry property. The default for this is set to https://registry.npmjs.org/)

  2. Install the Piral.Blazor.Tools and Piral.Blazor.Utils packages, make sure they both have a version number of format 8.0.x

  3. Remove the Microsoft.AspNetCore.Components.WebAssembly.DevServer package and install the Piral.Blazor.DevServer package (using the same version as the packages from (2))

  4. Rename Program.cs to Module.cs, and make sure to make the Main method an empty method.

  5. Build the project. The first time you do this, this can take some time as it will fully scaffold the pilet.

If you run the solution using F5 the Piral.Blazor.DevServer will start the Piral CLI under the hood. This allows you to not only use .NET Hot-Reload, but also replace the pilets on demand.

Usage

Build Configuration

The *.csproj file of your pilet offers you some configuration steps to actually tailor the build to your needs.

Here is a minimal example configuration:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <PiralInstance>../../app-shell/dist/emulator/app-shell-1.0.0.tgz</PiralInstance>
  </PropertyGroup>

  <!-- ... -->
</Project>

This one gets the app shell from a local directory. Realistically, you'd have your app shell on a registry. In case of the default registry it could look like

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <PiralInstance>@mycompany/app-shell</PiralInstance>
  </PropertyGroup>

  <!-- ... -->
</Project>

but realistically you'd publish the app shell to a private registry on a different URL. In such scenarios you'd also make use of the NpmRegistry setting:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <PiralInstance>@mycompany/app-shell</PiralInstance>
    <NpmRegistry>https://registry.mycompany.com/</NpmRegistry>
  </PropertyGroup>

  <!-- ... -->
</Project>

Besides these two options (required PiralInstance and optional NpmRegistry) the following settings exist:

  • Version: Sets the version of the pilet. This is a/the standard project property.
  • PiralInstance: Sets the name (or local path) of the app shell.
  • NpmRegistry: Sets the URL of the npm registry to use. Will be used for getting npm dependencies of the app shell (and the app shell itself).
  • Bundler: Sets the name of the bundler to use. By default this is esbuild. The list of all available bundlers can be found in the Piral documentation.
  • ProjectsWithStaticFiles: Sets the names of the projects that contain static files, which require to be copied to the output directory. Separate the names of these projects by semicolons.
  • Monorepo: Sets the behavior of the scaffolding to a monorepo mode. The value must be enable to switch this on.
  • PiralCliVersion: Determines the version of the piral-cli tooling to use. By default this is latest.
  • PiralBundlerVersion: Determines the version of the piral-cli-<bundler> to use. By default, this is the same as the value of the PiralCliVersion.
  • OutputFolder: Sets the temporary output folder for the generated pilet (default: ..\piral~).
  • ConfigFolder: Sets the folder where the config files are stored (default: empty, i.e., current project folder).
  • MocksFolder: Sets the folder where the Kras mock files are stored (default: .\mocks).
  • PiletKind: Sets the pilet kind (values: global, local; default: local).
  • PiletPriority: Sets the optional priority of the pilet when loading (any representable positive number). DLLs of Blazor pilets with higher numbers will always be loaded before the current DLLs (default: none).
  • PublishFeedUrl: Sets the URL to be used for publishing the pilet. If this is left free then using "Publish" in Visual Studio will not trigger a publish of the pilet.
  • PublishFeedApiKey: Sets the API Key to be used when publishing the pilet. If this is left free then the interactive upload is used, which will open a web browser for logging into the feed service.

A more extensive example:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Version>1.2.3</Version>
    <PiralInstance>@mycompany/app-shell</PiralInstance>
    <PiralCliVersion>next</PiralCliVersion>
    <PiralBundlerVersion>1.1.0</PiralBundlerVersion>
    <NpmRegistry>https://registry.mycompany.com/</NpmRegistry>
    <Bundler>esbuild</Bundler>
    <Monorepo>disable</Monorepo>
    <ProjectsWithStaticFiles>
      designsystem;
      someotherproject;
      thirdproj
    </ProjectsWithStaticFiles>
    <PiletPriority>999</PiletPriority>
  </PropertyGroup>

  <!-- ... -->
</Project>

While pilets that define PiletKind to be global only have shared dependencies, the default for local pilets is to have integrated dependencies. If certain dependencies of local pilets should also be loaded into the global context (effectively sharing the dependency between all pilets - independent of the version) then you need to put those dependencies into a dedicated ItemGroup using the Label shared:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <!-- ... -->

  <ItemGroup Label="shared">
    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
  </ItemGroup>

  <ItemGroup>
    <!-- ... -->
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
  </ItemGroup>

</Project>

Pages

A standard page in Blazor, using the @page directive, will work as expected, and will be automatically registered on the pilet API.

Extensions

To register an extension, the PiralExtension attribute can be used. You will also have to provide the extension slot name that defines where the extension should be rendered. The component can even be registered into multiple slots using multiple attributes.

//counter.razor

@attribute [PiralExtension("my-counter-slot")]
@attribute [PiralExtension("another-extension-slot")]

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button @onclick="IncrementCount">Click me</button>

@code {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }
}

To use an extension within a Blazor component, the <Extension> component can be used.

<Extension Name="my-counter-slot"></Extension>

Components, Tiles, Menu Items, and Others

To register a Blazor component for use in the pilet API, the PiralComponent attribute can be used in two ways:

  1. [PiralComponent], this will register the component using the fully qualified name.
  2. [PiralComponent(<name>)] will register the component using the custom name provided.

To register these components onto the pilet API, a setup.tsx file should be created at the root of your Blazor project.

This file may then, for example to register a tile, look like this:

import { PiletApi } from '../piral~/<project_name>/node_modules/<piral_instance>';

type AddScript = (path: string, attrs?: Record<string, string>) => void;
type AddStyles = (path: string, pos?: 'first' | 'last' | 'before' | ' after') => void;

export default (app: PiletApi, addScript: AddScript, addStyles: AddStyles) => {
	//for a component marked with[PiralComponent("my-tile")]
	app.registerTile(app.fromBlazor('my-tile'));
};

The addScript function can be used to actually add more scripts, e.g.:

export default (app: PiletApi, addScript: AddScript, addStyles: AddStyles) => {
	addScript("_content/Microsoft.Authentication.WebAssembly.Msal/AuthenticationService.js");
};

The first argument is the (relative) path to the RCL script, while the optional second argument provides additional attributes for the script to be added to the DOM.

The addStyles function can be used to add more style sheets, e.g.:

export default (app: PiletApi, addScript: AddScript, addStyles: AddStyles) => {
  addStyles("_content/MudBlazor/MudBlazor.min.css");
};

Important: Non-abstract / exposed components with PiralComponent cannot have a type parameter. As these are directly instantiated from JavaScript there is no way to define the type to be used. As such, you cannot mark components as @[PiralComponent] and @typeparam. If you want to use a generic component, then wrap it (i.e., use a second component declared as a PiralComponent, which only mounts / renders the first component with the desired generic type).

Using Parameters

Parameters (or "props") are properly forwarded. Usually, it should be sufficient to declare [Parameter] properties in the Blazor components. Besides, there are more advanced ways.

Generic Approach

For instance, to access the params prop of an extension you can use the PiralParameter attribute. This way, you can "forward" props from JS to the .NET name of your choice (in this case "params" is renamed to "Parameters").

@attribute [PiralExtension("sample-extension")]

<div>@Parameters.Test</div>

@code {
    public class MyParams
    {
        public string Test { get; set; }
    }

    [Parameter]
    [PiralParameter("params")]
    public MyParams Parameters { get; set; }
}

For the serialization you'll need to use either a JsonElement or something that can be serialized into. In this case, we used a class called MyParams.

Important: Make sure that your classes here are serializable, i.e., that they have a default / empty constructor (no parameters) and are public. Best case: These should be POCOs.

With the PiralParameter you can also access / forward children to improve object access:

@attribute [PiralExtension("sample-extension")]

<div>@Message</div>

@code {
    [Parameter]
    [PiralParameter("params.Test")]
    public string Message { get; set; }
}

That way, we only have a property Message which reflects the params.Test. So if the extension is called like that:

<app.Extension
    name="sample-extension"
    params={
        {
            Test: "Hello world",
        }
    }
/>

It would just work.

Routes

If you want to match the route parameter you can use the generic approach, too:

@page "/foo/{id}"

<div>@Id</div>

@code {
    [Parameter]
    [PiralParameter("match.params.id")]
    public string Id { get; set; }
}

However, since using match.params is quite verbose and easy to get wrong you can also use the special PiralRouteParameter attribute.

@page "/foo/{id}"

<div>@Id</div>

@code {
    [Parameter]
    [PiralRouteParameter("id")]
    public string Id { get; set; }
}

Note that there is another convenience deriving from the use of PiralRouteParameter. If your route parameter name matches the name of the property then you can also omit the argument:

@page "/foo/{Id}"

<div>@Id</div>

@code {
    [Parameter]
    [PiralRouteParameter]
    public string Id { get; set; }
}

In addition to route parameters you can also match the query parameters using the PiralQueryParameter attribute:

@page "/foo"

<div>@Id</div>

@code {
    [Parameter]
    [PiralQueryParameter]  
    public string Id { get; set; } 
}

The previous example would match /foo?id=bar with Id being set to bar. You could also change the name of the used query parameter:

@page "/foo"

<div>@SearchQuery</div>

@code {
    [Parameter]
    [PiralQueryParameter("q")]  
    public string SearchQuery { get; set; } 
}

This would print hello for /foo?q=hello.

Dependency Injection

You can define services for dependency injection in a Module class. The name of the class is arbitrary, but it shows the difference to the standard Program class, which should not be available, as mentioned before.

To be able to compile successfully, a Main method should be declared, which should remain empty.

public class Module
{
    public static void Main()
    {
        // this entrypoint should remain empty
    }

    public static void ConfigureServices(IServiceCollection services)
    {
        // configure dependency injection for the components in the pilet here
    }
}

The ConfigureServices method is optional. If you want to configure dependency injection in your pilet then use this.

If a third-party library requires globally shared dependencies (or global injected DI) then add it to a global pilet (setting the PiletKind to global in the csproj / build configuration).

Additionally, the ConfigureServices method supports another argument providing the configuration of the pilet, i.e., the IConfiguration object. So, the example above could be rewritten to be:

public class Module
{
    public static void Main()
    {
        // this entrypoint should remain empty
    }

    public static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
    {
    }
}

The configuration uses the meta.config of the Pilet API provided by the pilet.

Important: There is no support for the appsettings...json file as the configuration is assumed to be distributed. Use the meta.config approach described below for local development and a proper feed service with configuration support for production purposes.

Standard Pilet Service

Every pilet gets automatically a service called IPiletService injected.

Asset URLs

The IPiletService service can be used to compute the URL of a resource.

@inject IPiletService Pilet

The relevant helper method is GetUrl. You can use it like:

@page "/example"
@inject IPiletService Pilet

<img src=@Pilet.GetUrl("images/something.png") alt="Some image" />

In the example above the resource images/something.png would be placed in the wwwroot folder (i.e., wwwroot/images/something). As the content of the wwwroot folder is copied, the image will also be copied. However, the old local URL is not valid in a pilet, which needs to prefix its resources with its base URL. The function above does that. In that case, the URL would maybe be something like http://localhost:1234/$pilet-api/0/images/something.png while debugging, and another fully qualified URL later in production.

Events

You can use the IPiletService service to emit and receive events via the standard Pilet API event bus. This is great for doing loosely-coupled pilet-to-pilet communication.

Example:

@attribute [PiralComponent]
@inject IPiletService ps
@implements IDisposable

<aside class=@_sidebarClass>
  <a @onclick=@CloseSidebar style="display: inline-block; padding: 0 10px; cursor: pointer;">x</a>
</aside> 

@code {
    [Parameter]
    public bool IsOpen { get; set; } = false;

    [Parameter]
    public EventCallback<bool> IsOpenChanged { get; set; }

    string _sidebarClass { get => IsOpen ? "sidebar open" : "sidebar"; }

    public void Dispose()
    {
        ps.RemoveEventListener<bool>("toggle-sidebar", ToggleSidebar);
    }

    protected override void OnInitialized()
    {
        ps.AddEventListener<bool>("toggle-sidebar", ToggleSidebar);
    }

    public void ToggleSidebar(bool value) => IsOpenChanged.InvokeAsync(value);

    public void CloseSidebar() => ToggleSidebar(false);
}

Another component can now trigger this by using ps.DispatchEvent("toggle-sidebar", false); with an injected @inject IPiletService ps.

Pilet Data and API Access

You can use the IPiletService service to call methods living on the pilet API. This makes mostly sense for APIs that are quite primitive, e.g., accepting and returning only strings, booleans, and integers.

In general this is working via the Call API. An example would be:

@attribute [PiralComponent]
@inject IPiletService ps

<button @onclick=@LogValue>Log current value</button>

@code {
    public async void LogValue()
    {
      var value = await ps.Call<string>("getData", "myValue");
      Console.WriteLine("Currently stored value is: {0}", value);
    }
}

For some more common pilet API functions extension methods exist. The call beforehand to the getData function could be simplified with the GetDataValue extension:

@attribute [PiralComponent]
@inject IPiletService ps

<button @onclick=@LogValue>Log current value</button>

@code {
    public async void LogValue()
    {
      var value = await ps.GetDataValue<string>("myValue");
      Console.WriteLine("Currently stored value is: {0}", value);
    }
}

Localization

Localization works almost exactly as with standard Blazor, except that the language can be changed at runtime directly rather then requiring a full reload of the page.

The other difference is that the initial language is no longer decided by the server's response headers, but rather by the app shell. The initial configuration options of the piral-blazor plugin allow setting the initialLanguage. These options also allow setting up a callback to decide when to change the language (and to what language). If not explicitly stated Blazor will just listen to the select-language event of Piral, providing a key currentLanguage in the event arguments.

To dynamically change / refresh your components when the language change you'll need to listen to the LanguageChanged event emitted by the injected IPiletService instance:

@inject IStringLocalizer<MyComponent> loc
@inject IPiletService pilet

<h2>@loc["greeting"]</h2>

@code {
    protected override void OnInitialized()
    {
        pilet.LanguageChanged += (s, e) => this.StateHasChanged();
        base.OnInitialized();
    }
}

This way, your components will always remain up-to-date and render the right translations.

Provider Components

Sometimes Blazor components require some global components (or "providers") to be added. To accomplish this you can create components marked with the PiralProviderAttribute attribute.

Example:

@attribute [PiralProvider]

<MudThemeProvider/>
<MudDialogProvider/>
<MudSnackbarProvider/>

Providers will never receive any parameters - they are rendered only once and will remain active for the whole lifecycle of the application. There can be more than one provider.

Provider components are adjacent to your other components, which may come and go and will be - in general - somewhere else in the DOM. As such they are not ideal for providing some cascading value or other properties. They are ideal, however, when you need something running all the time.

In contrast, Piral also has the concept of a root component, which comes with another set of constraints.

Root Component

By default, the Blazor pilets run in a dedicated Blazor application with no root component. If you need a root component, e.g., to provide some common values from a CascadingValue component such as CascadingAuthenticationState from the Microsoft.AspNetCore.Components.Authorization package, you can actually override the default root component:

@attribute [PiralAppRoot]

<CascadingAuthenticationState>
    @ChildContent
</CascadingAuthenticationState>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }
}

You can also provide your own providers here (or nest them as you want):

@attribute [PiralAppRoot]

<CascadingValue Value="@theme">
    <div>
        @ChildContent
    </div>
</CascadingValue>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }
    
    private string theme = "dark";
}

Note: There is always just one PiralAppRoot component. If you did not supply one then the default PiralAppRoot will be used. If you already provided one, no other PiralAppRoot can be used.

It is critical to understand that each attached pilet component starts its own Blazor rendering tree. Therefore, while there is just a single PiralAppRoot component there might be multiple instances active at a given point in time. This is a crucial difference to PiralProvider components, which are essentially singletons from a rendering perspective.

Running and Debugging the Pilet 🚀

From your Blazor project folder, run your pilet via the Piral CLI:

cd ../piral~/<project-name>
npm start

In addition to this, if you want to debug your Blazor pilet using for example Visual Studio, these requirements should be considered:

  • keep the Piral CLI running
  • debug your Blazor pilet using IISExpress

⚠️ if you want to run your pilet and directly visit it in the browser without debugging via IISExpress, you will have to disable a kras script injector before visiting the pilet. To do this, go to http://localhost:1234/manage-mock-server/#/injectors, disable the debug.js script, and save your changes. Afterwards, you can visit http://localhost:1234.

Special Files

There are some special files that you can add in your project (adjacent to the .csproj file):

  • setup.tsx
  • teardown.tsx
  • package-overwrites.json
  • meta-overwrites.json
  • kras-overwrites.json
  • js-imports.json

Note: The location of these files can also be changed through the ConfigFolder option. By default, this one is empty, i.e., all files have to be placed adjacent to the .csproj file as mentioned above. However, if you set the value to, e.g., .piletconfig then the files will be retrieved from this subdirectory. For instance, the setup file would then be read from .piletconfig/setup.tsx.

Let's see what these files do and how they can be used.

Extending the Pilet's Setup

The setup.tsx file can be used to define more things that should be done in a pilet's setup function. By default, the content of the setup function is auto generated. Things such as @page /path-to-use components or components with @attribute [PiralExtension("name-of-slot")] would be automatically registered. However, already in case of @attribute [PiralComponent] we have a problem. What should this component do? Where is it used?

The solution is to use the setup.tsx file. An example:

export default (app) => {
  app.registerMenu(app.fromBlazor('counter-menu'));

  app.registerExtension("ListToggle", app.fromBlazor('counter-preview'));
};

This example registers a pilet's component named "counter-menu" as a menu entry. Furthermore, it also adds the "counter-preview" component as an extension to the "ListToggle" slot.

Anything that is available on the Pilet API provided via the app argument is available in the function. The only import part of setup.tsx is that has a default export - which is actually a function.

Overwriting the Package Manifest

The generated / used pilet is a standard npm package. Therefore, it will have a package.json. The content of this package.json is mostly pre-determined. Things such as piral-cli or the pilet's app shell package are in there. In some cases, additional JS dependencies for runtime or development aspects are necessary or useful. In such cases the package-overwrites.json comes in handy.

For instance, to actually extend the devDependencies you could write:

{
  "devDependencies": {
    "axios": "^0.20.0"
  }
}

This would add a development dependency to the axios package. Likewise, other details, such as a publish config or a description could also be added / overwritten:

{
  "description": "This is my pilet description.",
  "publishConfig": {
    "access": "public"
  }
}

The rules for the merge follow the Json.NET approach.

Overwriting the Debug Meta Data

The generated / used pilet is served from the local file system instead of a feed service. Therefore, it will not have things like a configuration store. However, you might want to use one - or at least test against one. For this, usually a meta.json file can be used. The content of this meta.json is then merged into the metadata of a served pilet. For Piral.Blazor this file is premade, however, its content can still be overwritten using a meta-overwrites.json file.

For instance, to include a custom config field (with one config called backendUrl) in the pilet's metadata you can use the following content:

{
  "config": {
    "backendUrl": "http://localhost:7345"
  }
}

The rules for the merge follow the Json.NET approach.

Extending the Pilet's Teardown

The teardown.tsx file can be used to define more things that should be done in a pilet's teardown function. By default, the content of the teardown function is auto generated. Things such as pages and extensions would be automatically unregistered. However, in some cases you will need to unregister things manually. You can do this here.

Defining Additional JavaScript Imports

Some Blazor dependencies require additional JavaScript packages in order to work correctly. The js-imports.json file can be to declare all these. The files will then be added via a generated import statement in the pilet's root module.

The content of the js-imports.json file is a JSON array. For example:

[
  "axios",
  "global-date-functions"
]

Includes the two dependencies via the respective import statements.

DevServer Settings

The Piral.Blazor.DevServer can be configured, too. Much like the standard / official Blazor DevServer you can introduce a blazor-devserversettings.json file that describes more options. Most of the contained options are the same as the one for the official Blazor DevServer.

Current options found in the Piral section:

  • forwardedPaths - is an array of strings describing the path segments that should be forwarded to the Piral CLI dev server (using kras)

    Example:

    {
      "Piral": {
        "forwardedPaths": [ "/foo" ]
      }
    }
  • feedUrl - is a string defining an URL for including an external / remote feed of pilets into the debug process

    Example:

    {
      "Piral": {
        "feedUrl": "https://feed.piral.cloud/api/v1/pilet/sample"
      }
    }

In addition, the options for the DevServer also touch the configured options for the Piral.Blazor.Tools, such as OutputFolder which is used to define where the scaffolded pilet is stored.

Setting the Logging Level

The log level can be set either within your Blazor pilets using the ILoggingConfiguration service or from JavaScript:

DotNet.invokeMethodAsync('Piral.Blazor.Core', 'SetLogLevel', logLevel);

Here, the value for logLevel should be between 0-6, where 0 logs everything (even traces) and 6 logs nothing. Alternatively, you can also set a log level when initializing piral-blazor.

FAQ

  1. I cannot use breakpoints when I debug a Piral.Blazor pilet in VS. What could be wrong?

Make sure you actually emit a PDB and have Debug selected as configuration. Also, don't change the configuration to have <DebugType>Full</DebugType> or similar in the project file. You'll need a portable PDB (modern format), not a full PDB (legacy format for Windows).

License

Piral.Blazor is released using the MIT license. For more information see the license file.

piral.blazor's People

Contributors

daniel-rck avatar dantederuwe avatar david-najar avatar dependabot[bot] avatar florianrappl avatar johannesehrhart avatar luckyluggi avatar prepfarm avatar software-programmer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

piral.blazor's Issues

Configure the order for pilets to load.

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Our project has y Layout pilet which configures services (in ConfigureShared) needed by every other pilet.
For that to work wee need it to be loaded first.

Currently this can not be guaranteed. As discussed we'd need a way to set the pilets priority to load. This priority should be used when running all pilets from the feed, when running one pilet locally and all others from the feed and when running multiple pilets locally.

Background

[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]

Discussion

[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]

Add overrides for package.json

Right now with the standard template the contents of the actual pilet are pretty much "hidden" for the end-user.

We should add a way (e.g., using a file "overrides.json") to merge in custom settings (should be deep merged, not shallow merged) just like we did with "setup.ts".

Piral.Blazor 5 (and 6..)

Currently version 3.2.1 is released, 5 is in prerelease and there isn't anything for dotnet6 blazor. Will eventually 5 and 6 be released?
By the way, amazing work!

Blazor Pilet Debugging - Pull in pilets within configured feed

New Feature Proposal

Would like to have a way to configure a feed to pull other enabled pilets from a configured feed during a specific Blazor pilets debug session. This could potentially be a parameter to somehow pass to Piral.Blazor.DevServer or via the devserver config directly. We see npx pilet debug has a --feed param but we are not able to hook into this as Piral.Blazor.DevServer abstracts the blazor pilet debug process,

image
ref: https://github.com/smapiot/piral/blob/main/docs/commands/debug-pilet.md#--feed

This would allow us to ensure pilets integrate together well during development workflows.

It should be configurable where the piral~ folder is created

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Currentl the folder is created one directory up. We would like to configure it to be 2 directories up.

Background

[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]

Discussion

[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]

Add possibility to configure ILogger

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Since the ILogger is configured in piral core we currently can not configure it. We need a possibility to do that.

Background

[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]

Discussion

[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]

If the [PiralComponent] attribute is added to a base component it should also be inherited.

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

See an example here (Problem nr. 2 in the Readme.md file):
https://github.com/luckyluggi/piral_meeting_examples

Background

[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]

Discussion

[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]

Overridable meta.json for Blazor DevServer

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

The meta.json files should be configurable to override some default values in debug environment, similar to packages-override.json.

Background

As far as I understood, you can set default configs via piletConfig, that are overridden by the feed service. When running the Blazor DevServer there is a meta.json that overrides the piletConfig - but I can't define what else should be overriden in local development. Somewhat like

{
    "backendUrl": "http://localhost:7345/"
}

NavLink active class does not get updated and NavigationManager.LocationChanged is not called.

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version?
  • Did you perform a search in the issues?

Description

If you switch Change Routes in the app the active class in Components is not updated.
Also NavigationManager.LocationChanged does not get called.

Steps to Reproduce

I Have created an MVP to make this clearer.
https://github.com/luckyluggi/mvp_route_update

The Browser Window does a hard reload when navigating to an upper route.

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version?
  • Did you perform a search in the issues?

Environment Details and Version

[Package Version, Blazor Version, OS, Browser,...]

Description

I've created an mvp showing the problem:
https://github.com/luckyluggi/mvp_route_reload

When you enter the root Page you can switch between all pages using the buttons at the top like it should be. In this case <base href="http://localhost:1234/"> is set in the .

But if you go to http://localhost:1234/winter/posts and press F5 -> <base href="http://localhost:1234/winter/posts"> gets written into the <head>. Now you can switch between all /winter/-Pages like it should be, but as soon as you switch to a /summer/-Page the browser window reloads.

I belive it has something to do with the <base>.

Steps to Reproduce

  1. [First Step]
  2. [next step...]

Expected behavior

[What you expected to happen]

Actual behavior

[What actually happened]

Possible Origin / Solution

[Optionally, share your idea to fix the issue]

Add Support for ordering Extensions

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

It Should be supported to order Extensions inside Blazor Pilets

In js pilets this is already supported like so:

<piral.Extension 
          name="topbar-left"
          order={(extensions: Array<ExtensionRegistration>) => {
            return extensions.sort((a, b) => {
                if(a.defaults?.order > b.defaults?.order) return 1;
                if(a.defaults?.order < b.defaults?.order) return -1;
                return 0;
            })
          }}
        />

other pilets can then add items like so:

app.registerExtension("topbar-left", () => {
    return <li>First</li>; 
  }, {order: 50});

and even blazor pilets can add items like so:

app.registerExtension('topbar-left', app.fromBlazor('my-extension'),{order: 10});

In Blazor we can create the extension like so:

<Extension name="topbar-left" />

but we currently don't have the possibility to sort the items.

Background

[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]

Discussion

[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]

Integrate Into Publish from Visual Studio

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Right now pilets are published by opening a terminal and changing directory to the scaffolded folder of a pilet. Then, the npx pilet command has to be used with the publish subcommand to trigger the publishing.

This should be simplified.

Background

It should be possible to just publish a pilet without any terminal interaction at all.

Discussion

Right now we want to automatically have the publishing provider adjusted to make this just work nicely. Two options exist:

  1. Somewhat introduce a new provider, which might not be easy and would require a VS extension. https://learn.microsoft.com/en-us/visualstudio/deployment/deploying-applications-services-and-components-resources?view=vs-2022
  2. Just make a post publish command; https://social.msdn.microsoft.com/Forums/vstudio/en-US/e5c7114d-e465-4a46-a4e1-3850c578400e/how-do-i-add-a-custom-command-to-the-publish-process-for-a-web-project?forum=msbuild - this would be part of Piral.Blazor.Tools and it would take (optional) input such as the API key (otherwise, interactive would be used anyway, opening a web browser to authenticate) or the feed URL to publish.

(The second way has the benefit that it would automatically also work with dotnet publish.)

Support Hot Reload

Please add support for .net6.0 hot reload.

Expected behavior

When i do the following:

  • add "hotReloadProfile": "blazorwasm" in the launchSettings.json like explained here
  • run npm start inside myproject/piral~/my-pilet
  • run dotnet watch inside myproject/my-pilet
  • change something inside the blazor pilet

The Browser should reload and show the changes applied

Piral should search for dlls using <AssemblyName> if it is set.

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version?
  • Did you perform a search in the issues?

Environment Details and Version

Latest version of Piral Blazor 6.

Description

Piral does not find referenced packages if they are renamed using <AssemblyName>

Steps to Reproduce

The behavior can be reproduced with this project (Infos in the readme):
https://github.com/luckyluggi/mvp_piral_blazor_extension

Expected behavior

The custom AssemblyName - if given - is used to determine the DLL name.

Actual behavior

No custom name can be used.

Possible Origin / Solution

N/A

Support Satellite Assemblies

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Right now satellite assemblies used for localizations are not picked up. They should be.

Background

Most users will actually use the localization system from .NET (https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-7.0&pivots=webassembly). This way, multiple satellite assemblies will be created - depending on the provided localization resources.

Discussion

How should the language be changed? The main idea would be that this would / could work implicitly, but the behavior could also be determined when configuring piral-blazor. For standalone pilets a dedicated API to configure / change this would be provided.

Scaffold with NPM v6

Right now our structure requires NPM v7/v8:

The command is the one from the Prial.Blazor.Tools.targets: npx --package=piral-cli -y pilet new $(PiralInstance) --base $(_piletFolderBase) --target $(MSBuildProjectName) --registry $(NpmRegistry) --bundler $(_bundler). the command "new" is not found.

It works with:

npm init pilet --source $(PiralInstance) --base $(_piletFolderBase) --target $(MSBuildProjectName) --registry $(NpmRegistry) --bundler $(_bundler) --defaults

So we'd need to find out the current version and switch command appropriately.

Components with the [PiralComponent] attribute should support adding @typeparam

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • [ x] Can you reproduce the problem in a MWE?
  • [ x] Are you running the latest version?
  • [ x] Did you perform a search in the issues?

Environment Details and Version

[Package Version, Blazor Version, OS, Browser,...]

Description

See an example here (Problem nr. 1 in the Readme.md file):
https://github.com/luckyluggi/piral_meeting_examples

Steps to Reproduce

  1. [First Step]
  2. [next step...]

Expected behavior

[What you expected to happen]

Actual behavior

[What actually happened]

Possible Origin / Solution

[Optionally, share your idea to fix the issue]

Error Starting Blazor

I followed the instructions for setting up a Piral shell and a Blazor Pilet from the template and I'm getting the following error when debugging the Blazor app:

Uncaught RuntimeError: memory access out of boundsUncaught RangeError: Invalid typed array length: 534384Uncaught Error: Failed to start platform. Reason: RangeError: Invalid typed array length: 43920The thread 0x3a84 has exited with code 0 (0x0).

Any idea what I'm doing wrong?

Calling StateHasChanged() does not reload Page and Extension Components

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version?
  • Did you perform a search in the issues?

Environment Details and Version

[Package Version, Blazor Version, OS, Browser,...]

Description

Hy. I've been tracking down a problem in my app and i think i've found the source of the problem now.
I have created this mvp to show the problem:
https://github.com/luckyluggi/-mvp_piral_statehaschanged

There i have a StateContainer (my-pilet\State\ShoppingCartState.cs) with Items.
Whenever i add items i call StateHasChanged() in my-pilet\Pages\ShopPage.razor and my-pilet\Components\ShoppingCartIcon.razor but the state does not get updated.

Steps to Reproduce

see mvp

Expected behavior

Component should reload and show new state

Actual behavior

does not reload

Possible Origin / Solution

[Optionally, share your idea to fix the issue]

Allow Forwarding Requests to Kras Proxy

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Right now the Kras proxy cannot be configured / used with the Piral.Blazor.DevServer. This should be changed

Background

One of the reasons is that we don't forward non-pilet requests to the Kras proxy. As a mitigation, the Kras proxy scripts should be placed (configurably) in some directory, with the kras config being read and all proxy-endpoints being forwarded properly.

Discussion

I think a good starting point would be the definition of the mocks directory (e.g., <MocksDir>mocks</Mocks>), which might contain a .krasrc file and other files. The .krasrc file would then be merged / brought over to the pilet, with the scripts being referenced / used directly. The keys of the map property will be used as forwarding endpoints.

Urls build with IPiletService.GetUrl() are not correct.

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • [ x] Can you reproduce the problem in a MWE?
  • [ x] Are you running the latest version?
  • [ x] Did you perform a search in the issues?

Environment Details and Version

[Package Version, Blazor Version, OS, Browser,...]

Description

Image loaded from wwwroot via IPiletService.GetUrl() are not found.
I've reproduced the bug here:
https://github.com/luckyluggi/piral_extensions_and_aimages

Steps to Reproduce

  1. [First Step]
  2. [next step...]

Expected behavior

[What you expected to happen]

Actual behavior

[What actually happened]

Possible Origin / Solution

[Optionally, share your idea to fix the issue]

Blazor Calling Extensions won't pass the Params correctly

In the sample:
https://github.com/smapiot/Piral.Blazor/blob/blazor-5.0/example/pilet/Pilet/Components/SampleExtension.razor

the react-counter is called with params new { count = 10, diff = 3 } however upon loading the page the starting value is 0 and the increment is 1, so the props have the default value.

image

Adding a console.log(params); to the react-counter extension shows that the params is not undefined, but empty and have no properties.
image

So calling Extensions from Blazor with Params, the Params is not correctly passed through.
Calling a Blazor Extension from React works.

Override "Normal" Routing

For the current model we've introduced the custom Anchor element. Blazor's "primitives" here (just standard a or something like NavLink) should, however, also just work.

So instead, I propose to just override the standard routing behavior. The mechanism should be to use the context's Router instead of the history API. Most likely, this is a change in the piral-blazor code.

Support @page Directive

The @page directive is used to automatically add pages to the router. Internally, this just adds the [PageAttribute] to the generated class.

Most likely, we could do some "magic" and introduce an auto inclusion of these pages. Potentially, it makes sense to trigger this via piral-blazor (explicitly), such that it could be turned off - if not desired.

export function setup(api) {
  api.defineBlazorReferences([...], {
    includePages: true, //set to false or omit to not auto discover
  });
}

Support (and Use) Blazor's Assembly Lazy Loading

For the upcoming Blazor / Piral.Blazor 5.0.0 release the new lazy loading of Blazor should be used.

This makes especially sense regarding framework support for larger applications. It should bring an additional layer of reliability, too.

More information can be found:

Images from isnide the wwwroot folder can not be referenced.

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version?
  • Did you perform a search in the issues?

Environment Details and Version

[Package Version, Blazor Version, OS, Browser,...]

Description

When i try to reference an image from inside the wwwroot folder it is not shown.
Example:

The image does exist in wwwroot/img/logo.png but is not shown.

Steps to Reproduce

  1. [First Step]
  2. [next step...]

Expected behavior

[What you expected to happen]

Actual behavior

[What actually happened]

Possible Origin / Solution

[Optionally, share your idea to fix the issue]

Pilets should be able to add to App.razor

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Currently the App. razor file is locked away and has to be taken as it is.
If f.e. Microsoft.AspNetCore.Components.Authorization should be used The App.razor must be edited like this:

<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView RouteData="@routeData" 
                DefaultLayout="@typeof(MainLayout)" />
        </Found>
        <NotFound>
            <LayoutView ...>
                ...
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

This should be possible.

Background

[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]

Discussion

[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]

piralVersion is not defined

In case the core dependencies are not found, e.g.,

Piral Blazor was not found in the Piral Instance, and the needed dependencies are also not found. Installing them now...

it may throw an error

(node:12052) UnhandledPromiseRejectionWarning: ReferenceError: piralVersion is not defined

This should be fixed in blazor.codegen. ("the error is throwing from the line blazor.codegen:276:77")

Support `appsettings.*.json` and pass bound `IConfiguration` to `Module.ConfigureServices()`

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Blazor WASM provides a way of providing environment-specific client-side configuration by placing appsettings.*.json files into the wwwroot folder. The active environment can then be set using, for example, a startup configuration as outlined here.

It would be helpful if appsettings.*.json files could be used for client-side app configuration within a Blazor pilet to populate an IConfiguration instance, and if that instance would then be passed to the Module.ConfigureServices method as outlined in the minimal example below.

appsettings.json:

{
  "Api": {
    "BaseUrl": "https://my.api.com/"
  }
}

ApiOptions.cs:

public class ApiOptions
{
  public string? BaseUrl { get; set; }
}

Module.cs:

[...]
  public static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
  {
    services.AddOptions();

    services.Configure<ApiOptions>(options => configuration.Bind("Api", options));
    // or
    services.Configure<ApiOptions>(configuration.GetSection("Api"));
  }
[...]

Background

As of now, IConfiguration is not bound. This leaves the pilet author with hard-coding necessary configuration values within the ConfigureServices method and also neglects the need for environment-specific configuration within pilets.

Scaffolding on MacOS / nix breaks `blazor.codegen`

When doing this on a non-Windows system the blazor.codegen has slashes (/) everywhere where backslashes ( \) have been used. This breaks the code as regular expressions (and other things) suddenly become invalid syntax.

Support for .NET 7

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

Now that .NET 7 / Blazor 7 is officially released we should also have a blazor-7.0 branch with an associated release.

Background

One of the things with .NET 7 is that Blazor now has a stable custom elements API - which would be another capability for Piral.Blazor. Using .NET 7 we would not need the DOM projection any more, but instead of web components. Otherwise, it's still the same as .NET 6.

Discussion

Anything else in Blazor 7 that is of particular interest for Piral / would make our live here easier / better?

Scaffolding check always passing

Related to PR #38

afaik the _piletFolderPath already has the MSBuildProjectName included, so it should already be considered when scaffolding. This being merged now includes the project name twice (e.g. piral~/projectname/projectname) and results in the scaffold always happening.

Originally posted by @DanteDeRuwe in #38 (comment)

Reposted here to get opinion of @FlorianRappl about this

Support Global Dependency Injection in Shared Libraries

Right now the DI works only partially. Full DI (i.e., pilet-local specified dependencies) can be fully injected in a pilet (i.e., components within the pilet), however, for components coming from other DLLs this is not working.

In general it is very difficult (almost impossible) to reliably inject the right dependencies in such components. While we could track the happy path (i.e., Component from pilet -> Component from library) and therefore use the right service container, the problem becomes much more difficult when there are interruptions along the way. (i.e., Component from pilet 1 -> async waiting; Component from pilet 2 -> done; async waiting over -> Component from library => which service container would we choose now? last rendering indicates pilet 2, but the actual path / rendering origin was originating from pilet 1).

What we therefore want to do is to enable the global shared dependencies (i.e., obtained from the ConfigureShared method, not ConfigureServices in Module.cs) to be used here. The advantage is that in this case we do not need to track the origin - it would just work and be in this case reliable.

Avoid Allowing Referencing Piral.Blazor.Core

Right now when somebody starts a new Piral.Blazor pilet without the template one may be tempted to just reference Piral.Blazor.Core (instead of the usually wanted Piral.Blazor.Utils). Since Piral.Blazor.Core is an application and only meant as a carrier for the shared dependencies we should be very explicit to discourage this.

Ideally, the referencing does not work (how?). In the worst case we just show some warning or info in Visual Studio.

Whatever we do, we should not impact the NuGet experience for piral-blazor, which downloads and unzips the package to get / use the content.

Moving to another route using NavigationManager.NavigateTo() is rurrently not possible

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • Can you reproduce the problem in a MWE?
  • Are you running the latest version?
  • Did you perform a search in the issues?

Environment Details and Version

[Package Version, Blazor Version, OS, Browser,...]

Description

When i want to move to another page programmatically by injecting "Navigationmanager" and calling "_navigationManager.NavigateTo($"/item/create");" the page does not change.
I can ofcourse add true as a second param to bypass client side routing and load the new page from the server, and it does work, but that's not rly nice and slow.

I've added an example page to the mvp (/navigationmanager):
https://github.com/luckyluggi/mvp_piral_route_params

More info on Navigationmanager:
https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.navigationmanager.navigateto?view=aspnetcore-6.0

Steps to Reproduce

see mvp

Expected behavior

should move to another route

Actual behavior

does not move to another route

Possible Origin / Solution

[Optionally, share your idea to fix the issue]

Refresh scaffolded pilet

Right now the scaffolded pilet is a bit "too sticky". In order to apply, e.g., an update of the Piral instance / emulator package, you'd need to manually go to the pilet's directory and run pilet upgrade. Sure, this is the "usual" way, however, for a Blazor Pilet (Blazelet?) it should not be necessary. Ideally, this can be done directly from Visual Studio - and even better: it may even be implicit.

We should add at least a task to do that, but maybe even automate it appropriately. Easiest way would be to have something like <PiralInstanceVersion> in the csproj, such that it is (by default set to) "latest" (which auto-checks), but could also be set to anything else (and, e.g., in case of explicit versions may only check if the version match, resulting in an update of the scaffolded pilet, or not).

Auto run pilet debug when debugging

One of my biggest concerns (still) is that we need to run the debug from VS, but also from the command line (sure this can also be done from within VS, but the thing is that its still 2 commands where it should be just one).

Ideally, there is a way to run a process / command when the IIS express starts.

Maybe someone in the aspnetcore gitter or so knows how / if this works.

Update to Blazor 3.2.1

Piral.Blazor should be adjusted to v3.2.1.

In this process we should start aligning the version numbers. The NuGets coming from this repo should always have the same version (Major, Minor, Patch) as Blazor. Thus anyone interested in a particular version of Blazor only needs to know this version for choosing the right version of Piral.Blazor.

Configuration Values (configured in the feed) should also be available when debugging.

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

The possibility to set configs in the feed service is great, but while running pilets locally via pilet debug the configs are currently empty. It would be great if they were also pulled if i add the feed via --feed.
Or even better if they could be configured in a json file just for running and debugging pilets localy.

Background

[Provide any additional background for the feature, e.g., why is the current solution insufficient, what problem will it solve, etc.]

Discussion

[Optionally, outline any pros and cons you can currently think of to provide the basis for a solid discussion]

Add Debugging Capability to the Template

Right now the template still needs to be enhanced to allow for more rapid development.

The most important feature is to have the source maps properly working. That means not only debugging in the browser is fine, but also that a breakpoint in VS is triggered properly.

We should check and ensure that this works as expected.

Extension parameter don't work.

Bug Report

For more information, see the CONTRIBUTING guide.

Prerequisites

  • [ x] Can you reproduce the problem in a MWE?
  • [ x] Are you running the latest version?
  • [ x] Did you perform a search in the issues?

Environment Details and Version

[Package Version, Blazor Version, OS, Browser,...]

Description

Parameters given to piral extensions are not working.
I've reproduced the bug here:
https://github.com/luckyluggi/piral_extensions_and_aimages

Steps to Reproduce

  1. [First Step]
  2. [next step...]

Expected behavior

[What you expected to happen]

Actual behavior

[What actually happened]

Possible Origin / Solution

[Optionally, share your idea to fix the issue]

Scaffolding Issue Prevents Rebuild

Similar to #59 we need to ensure that a failed scaffold (e.g., due to some missing dependency) does not prevent a scaffold in the future.

Right now when the initial scaffold fail (but still created the folder structure) a subsequent scaffold will not touch it. This is sub-optimal.

Ideally, we introduce a flag that also includes all used dependencies, allowing us to determine when we need to upgrade / re-scaffold etc.

Use .Net/Blazor package version for the pilet

The Blazor pilet seems to remain at 1.0.0, but it should be synced with the version defined in the .NET project. This way, there is no need to touch the contents of the package.json or override them.

Include script files in referenced packages or RCLs

New Feature Proposal

For more information, see the CONTRIBUTING guide.

Description

In Blazor WASM, it is sometimes necessary to reference static JS assets defined in imported NuGet packages or referenced Razor Class Libraries. One example is Microsoft.Authentication.WebAssembly.Msal, which provides a static script file named AuthenticationService.js which needs to be referenced in the HTML body of wwwroot/index.html like so:

<script src="_content/Microsoft.Authentication.WebAssembly.Msal/AuthenticationService.js"></script>

The same applies to any shared Razor Class Libraries referenced by a pilet, which may also provide static JS files to be used in the same fashion as described above.

Piral.Blazor should support this pattern and provide a way to reference these assets.

Background

As of now, there is no obvious way to reference static JS files within RCLs or NuGet packages from within a Blazor pilet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.