JavaScript einbinden

Eine neue Komponente bringt ihr JavaScript über eine Klasse ins Bundle. Der Regelfall ist das Standard-Bundle fmh-scripts, das über _BodyIncludes am Seitenende geladen wird.

Die Provider-Klasse

Ablage: src/FMH.Komponente.MeineKomponente/BundleKonfiguration/MeineKomponenteBundleScriptSetup.cs

using System.Collections.Generic;
using FMH.Komponente.Infrastruktur.Bundle;
using FMH.Komponente.Infrastruktur.Bundle.Schnittstellen;

namespace FMH.Komponente.MeineKomponente.BundleKonfiguration;

public class MeineKomponenteBundleScriptSetup : IJavaScriptProvider
{
    public string BundleName => BundleKonstanten.FmhScriptBundleName;

    public int Order => 100;

    public IEnumerable<string> GetJavaScriptPaths()
    {
        return
        [
            "_content/FMH.Komponente.MeineKomponente/lib/fremdbibliothek/lib.js",
            "_content/FMH.Komponente.MeineKomponente/js/meine-komponente.js",
        ];
    }
}

Das ist alles. Kein Eintrag in Program.cs, keine Registrierung im Container.

BundleName muss hier gesetzt werden: Der Standardwert der Schnittstelle ist "fmh" und würde ein eigenes, nirgends eingebundenes /bundle/fmh.js erzeugen.

Wohin die Dateien gehören

Was Wohin
Eigene Skripte wwwroot/js/
Fremdbibliotheken wwwroot/lib/<name>/ — bezogen über libman.json, nicht von Hand kopiert
Die Provider-Klasse BundleKonfiguration/

Der Pfad ist der Knackpunkt

Die Pfade sind Static-Web-Asset-Pfade der Razor Class Library:

_content/<AssemblyName>/<Pfad relativ zu wwwroot>

Ohne führenden Schrägstrich, ohne das Segment wwwroot.

<AssemblyName> ist der Name der Projektdatei, nicht der des Ordners. Das ist im Repo eine echte Stolperfalle, weil beide bei der Basis auseinanderlaufen:

Ordner Projektdatei Pfad-Segment
src/FMH.Komponenten.Basis FMH.Komponente.Basis.csproj _content/FMH.Komponente.Basis/…
src/FMH.Komponente.Tabelle FMH.Komponente.Tabelle.csproj _content/FMH.Komponente.Tabelle/…
src/FMH.Komponente.FileUpload FMH.Komponente.FileUpload.csproj _content/FMH.Komponente.FileUpload/…

Bei der Basis heisst der Ordner «Komponenten» im Plural, das Pfad-Segment aber FMH.Komponente.Basis im Singular. Im Zweifel den Dateinamen der .csproj nachsehen — beziehungsweise AssemblyName, falls die Projektdatei ihn ausdrücklich setzt, wie es die Basis tut.

Ein falscher Pfad meldet sich nicht

Ein Tippfehler im Pfad wirft keine Ausnahme. Die Datei fehlt einfach im Bundle, und das Skript tut nichts. So lässt sich das prüfen:

/bundle/fmh-scripts.js

Die Adresse direkt im Browser aufrufen und nach einem markanten Bezeichner aus der eigenen Datei suchen. Fehlt er, stimmt der Pfad nicht.

Achtung bei der Gross-/Kleinschreibung im Dateinamen: Unter Windows ist sie egal, auf einem case-sensitiven Dateisystem nicht. Ein Pfad, der lokal einwandfrei liefert, kann dort ins Leere laufen — deshalb den Dateinamen genau so schreiben, wie die Datei heisst.

Reihenfolge

Zwei Ebenen, beide wichtig:

  • Zwischen Providern entscheidet Order. Für eine neue Komponente ist ein Wert oberhalb der belegten sinnvoll, damit sie nach der Basis geladen wird — die stellt mit Bootstrap und jQuery-Erweiterungen die Grundlage bereit.
  • Innerhalb eines Providers gilt die Reihenfolge im Array. Deshalb steht im Beispiel die Fremdbibliothek vor dem eigenen Skript: Sonst ruft das eigene Skript beim Laden etwas auf, das es noch nicht gibt.

Wenn das Skript ein ES-Modul ist

Dann gehört es nicht ins Bundle. NUglify minifiziert die Dateien und versteht import/export nicht — das Ergebnis ist kaputtes JavaScript.

Native Module laufen stattdessen über den Modulkatalog: statt IJavaScriptProvider implementiert die Komponente IModuleScriptProvider. Das ist in «Native ES-Module einbinden» beschrieben.