[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Magic_comments [Back]  [Original]

Magic Comments - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

Magic Comments

Magic Comments (auch Kommentardirektiven, Annotationen usw. genannt) sind besondere Arten von Kommentaren, die von bestimmten Engines, Bundlern, Typprfern, Debuggern usw. (zusammenfassend als verarbeitende Werkzeuge bezeichnet) erkannt werden, um Funktionen gezielt zu aktivieren. Da es sich um Kommentare handelt, werden sie von Werkzeugen, die sie nicht verstehen, ignoriert. Dieser Artikel stellt verschiedene Arten von Magic Comments vor, die hufig in JavaScript-Quellcode vorkommen, und erlutert, welche Werkzeuge sie verarbeiten sollen.

Ob Magic Comments vorhanden sind oder nicht, ndert normalerweise nichts am Laufzeitverhalten des Programms. Sie knnen beispielsweise die Ausfhrung optimieren, statische Prfungen aktivieren oder deaktivieren oder zustzliche Metadaten bereitstellen. Darin unterscheiden sie sich von Direktiven: Das sind Zeichenfolgen, die das Laufzeitverhalten tatschlich ndern. Beispiele sind die standardisierte Direktive "use strict", die den Strict Mode aktiviert, sowie die React-Direktiven "use server" und "use client", die festlegen, ob eine Komponente server- oder clientseitig ausgefhrt wird.

Um Verwechslungen mit gewhnlichen Kommentaren zu vermeiden, werden Magic Comments blicherweise durch Kennzeichen markiert, etwa ein vorangestelltes # oder @: //# my-setting-name oder //@ my-setting-name. Die genaue Syntax unterscheidet sich je nach Kommentarart.

Hinweis: Fr diese Art von Funktion gibt es keine allgemein gltige Bezeichnung. Auch die genannten Alternativen knnen sich in Details unterscheiden: Pragmas stehen blicherweise am Dateianfang und geben Compilern oder Engines Informationen ber das gesamte Skript; Annotationen knnen an beliebiger Stelle stehen und sich auf ein bestimmtes Konstrukt beziehen; Direktive ist ein allgemeiner Begriff, kann aber mit der JavaScript-Konvention fr Direktiven wie "use strict" verwechselt werden. In diesem Artikel verwenden wir diese Begriffe austauschbar.

In diesem Artikel

Pragmas mit Kompilierungshinweisen

Pragmas mit Kompilierungshinweisen geben JavaScript-Engines Hinweise dazu, wie sie den Code vorab kompilieren sollen. Wie sie interpretiert werden, hngt von der jeweiligen Engine ab.

Sie sind im WICG-Vorschlag Explicit JavaScript Compile Hints beschrieben.

Vorzeitige Kompilierung

Das folgende Pragma aktiviert die vorzeitige Kompilierung aller Funktionen im aktuellen Skript.

js
//# allFunctionsCalledOnLoad

Fr Syntax und Platzierung gelten folgende Anforderungen:

  • Dieser Kommentar muss am Anfang des Skripts stehen, vor jeglichem Code und Leerraum. Nur andere Kommentare, einzeilige Kommentare oder Blockkommentare, drfen davor stehen.
  • Der Kommentar kann ein Zeilenkommentar oder ein Blockkommentar sein.
  • Zwischen # und // beziehungsweise /* darf kein Leerzeichen stehen.
  • Vor und nach allFunctionsCalledOnLoad darf beliebig viel Leerraum stehen.

Im folgenden Beispiel signalisiert der Magic Comment, dass die Funktionen in der Datei wahrscheinlich beim Laden der Seite aufgerufen werden:

js
//# allFunctionsCalledOnLoad
function init() {
  console.log("init");
}

init();

Ohne diesen Hinweis kann die Engine die Kompilierung einer Funktion aufschieben, bis sie aufgerufen wird.

Die vorzeitige Kompilierung bietet folgende Vorteile:

  • Sie vermeidet doppeltes Parsen: Whrend der Initialisierung fhrt die Engine bereits ein leichtes Parsen durch, um Anfang und Ende der Funktion zu ermitteln. Beim Aufruf der Funktion muss sie diese dann noch einmal vollstndig parsen. Kann die Funktion vorzeitig kompiliert werden, fhrt die Engine das vollstndige Parsen sofort durch, ohne einen gesonderten Durchlauf fr das leichte Parsen.
  • Sie kann parallelisiert werden: Lst ein Funktionsaufruf whrend der Ausfhrung eine verzgerte Kompilierung aus, muss diese den Hauptthread blockieren, damit die Ausfhrung synchron bleibt. Das Laden von Skripten erfolgt asynchron. Daher lsst sich das Parsen effizienter einplanen und kann sogar bereits whrend des Abrufs des Skripts stattfinden.

Das Kompilieren von Funktionen, die nie aufgerufen werden, kann jedoch Zeit und Speicher verschwenden. Wie bei allen Leistungsfragen sollten Sie Benchmarks durchfhren und die verschiedenen Vor- und Nachteile abwgen. Eine gute Faustregel steht bereits im Namen des Pragmas: Aktivieren Sie diesen Modus nur, wenn die Funktionen beim Laden aufgerufen werden.

Siehe auch Faster JavaScript Startup with Explicit Compile Hints auf v8.dev.

Source-Map-Annotationen

Source-Map-Annotationen verknpfen JavaScript-Code mit Quelldateien. Dadurch lsst sich generierter, evaluierter oder minimierter Code leichter debuggen.

Sie sind in der TC39-Spezifikation ECMA-426 Source map format beschrieben.

Source-URLs

Die folgende Annotation weist einem Codeabschnitt eine URL als Kennung zu.

js
//# sourceURL=<url>

Fr Syntax und Platzierung gelten folgende Anforderungen:

  • Dieser Kommentar muss am Ende des Skripts, nach jeglichem Code stehen. Weitere einzeilige Kommentare, Leerraum und Zeilenumbrche drfen darauf folgen.
  • Der Kommentar muss ein Zeilenkommentar sein.
  • Statt # kann auch @ als Kennzeichen verwendet werden; # wird jedoch bevorzugt, da //@ mit Internet-Explorer-Pragmas kollidieren knnte.
  • Vor und nach sourceURL=<url> darf beliebig viel Leerraum stehen.
  • Die <url> darf keine Leerraumzeichen enthalten. Diese sollten beispielsweise als %20 prozentkodiert werden.

Source-URLs sind besonders ntzlich fr Code, der nicht aus einer bereits mit einer URL verknpften Ressource stammt, etwa fr Code, der mit eval() ausgefhrt wird:

js
eval(
  'console.log("Hello"); throw new Error("error");\n//# sourceURL=generated-code.js',
);

Das obige Beispiel kann in der Browserkonsole folgende Ausgabe erzeugen:

Hello        generated-code.js:1
Uncaught Error: error
    <anonymous> generated-code.js:1
    <anonymous> debugger eval code:1

Diese Annotation wird von vielen Funktionen genutzt und dient hauptschlich dem Debugging:

  • Ausgaben in der Konsole und im Debugger, wie oben gezeigt.
  • Der stack-Eigenschaft von Error.
  • Der Auflsung von sourceMapURL.

Siehe auch naming evaluated code with sourceURL auf developer.chrome.com und Give your eval a name with //@ sourceURL auf Firebug.

Source-Map-URLs

Die folgende Annotation verknpft generierten Code mit einer Source Map.

js
//# sourceMappingURL=<url>

Fr Syntax und Platzierung gelten dieselben Anforderungen wie fr sourceURL.

Die Source-Map-URL kann eine relative URL sein. In diesem Fall kann sie anhand von sourceURL, dem src-Attribut des <script>-Elements, dem Ursprung des Dokuments, das das <script>-Element enthlt, usw. aufgelst werden, wie in ECMA 426 festgelegt. Sie kann auch eine data:-URL mit einer eingebetteten Source Map sein. Der HTTP-Header SourceMap hat Vorrang vor diesem Kommentar.

Ein Debugger kann mithilfe der Map den ursprnglichen Quellcode anzeigen und Breakpoints einem minimierten Bundle zuordnen. Auch in Editoren ist sie ntzlich, etwa um zu Definitionen zu springen oder Referenzen zu finden.

Build-Werkzeuge (Bundler, Transpiler usw.) erzeugen diesen Kommentar zusammen mit der Map in der kompilierten Ausgabe. Entwickler mssen ihn normalerweise nicht von Hand schreiben.

Bundler-Annotationen

Bundler, Minimizer und Transpiler verwenden Magic Comments, um die Codegenerierung, Optimierung und Verarbeitung von Abhngigkeiten zu steuern. Diese Annotationen werden whrend des Build-Prozesses verarbeitet, nicht von der JavaScript-Engine, die das Ergebnis ausfhrt.

Es gibt dafr keine Spezifikation, und Bundler entwickeln hufig eigene Annotationen. Dieser Abschnitt beschreibt nur einige verbreitete Annotationen, die von mehreren Werkzeugen untersttzt werden. Ob ein bestimmter Bundler eine Annotation untersttzt, mssen Sie in dessen Dokumentation nachsehen.

Tree Shaking

Die Annotationen /*#__PURE__*/ und /*@__PURE__*/ kennzeichnen einen bestimmten Funktions- oder Konstruktoraufruf als gefahrlos entfernbar, wenn sein Ergebnis nicht verwendet wird:

js
function createPoint(x, y) {
  return { x, y };
}

const point = /*#__PURE__*/ createPoint(1, 2);

Hinweis: Das bedeutet nicht, dass der Aufruf im Sinne der funktionalen Programmierung rein ist. Sein Ergebnis kann zufllig sein, von externem Zustand abhngen usw. Solange das Entfernen das Anwendungsverhalten nicht in relevanter Weise verndert, kann der Aufruf jedoch als rein annotiert werden.

Ohne die Annotation muss der Bundler den Funktionsaufruf mglicherweise beibehalten, selbst wenn die Ergebnisvariable point nicht verwendet wird:

js
// -- Compiler output --
function createPoint(x, y) {
  return { x, y };
}

createPoint(1, 2);

Mit der Annotation kann der Bundler den Funktionsaufruf vollstndig entfernen. Wird createPoint() sonst nirgends aufgerufen, kann er auch die Funktionsdefinition entfernen. Eine falsche Annotation kann dazu fhren, dass erforderliches Verhalten entfernt wird.

Die Annotation gilt fr den jeweiligen Funktionsaufruf. ber die Seiteneffekte bei der Auswertung der Argumentausdrcke wird getrennt entschieden. Zum Beispiel:

js
/*#__PURE__*/ createPoint(1, getY());

In diesem Beispiel ist der Aufruf von createPoint() rein, und Bundler wissen, dass die Auswertung von 1 keine Seiteneffekte hat. Sie knnen jedoch nicht feststellen, ob getY() rein ist. Deshalb enthlt die Ausgabe den Aufruf von getY(); mglicherweise bleibt auch der Aufruf von createPoint() erhalten. Damit alles entfernt werden kann, muss jeder Funktionsaufruf einzeln annotiert werden:

js
/*#__PURE__*/ createPoint(1, /*#__PURE__*/ getY());

Siehe auch esbuilds Pure-Annotationen und Tersers Annotationen.

Einige Bundler erkennen auerdem /*#__NO_SIDE_EFFECTS__*/ und /*@__NO_SIDE_EFFECTS__*/. Diese annotieren eine Funktionsdeklaration oder eine untersttzte Variablendeklaration, die eine Funktion enthlt, damit Aufrufe dieser Funktion als frei von Seiteneffekten behandelt werden knnen:

js
/*#__NO_SIDE_EFFECTS__*/
function createPoint(x, y) {
  return { x, y };
}

Siehe Rollups Tree-Shaking-Annotationen.

Minimierung

Zwei wichtige Minimierungstechniken knnen unter Umstnden nicht gefahrlos angewendet werden: Inlining und Property Mangling. Beim Inlining wird ein Funktionsaufruf direkt durch den Funktionskrper ersetzt. Beim Property Mangling werden Eigenschaftsnamen durch krzere Zeichenfolgen ersetzt.

Mit /*@__INLINE__*/ und /*@__NOINLINE__*/ knnen Sie Inlining fr bestimmte Funktionsaufrufe gezielt aktivieren oder deaktivieren. Beachten Sie dabei Folgendes:

  • Inlining kann die Aufrufleistung verbessern, da Stack Frames nicht angelegt und wieder entfernt werden mssen. Allerdings kann die Engine selbst Inlining durchfhren, und Inlining im Quellcode kann ihre Entscheidungen auf unvorhersehbare Weise beeinflussen.
  • Inlining kann die Bundle-Gre verringern, wenn eine Funktion nur einmal verwendet wird, und sie vergrern, wenn die Funktion hufig verwendet wird. Minimizer treffen blicherweise Entscheidungen, die die Bundle-Gre optimieren.

Beim Property Mangling ersetzt der Minimizer Eigenschaftsnamen im gesamten Code durch krzere Zeichenfolgen, wobei unterschiedliche Namen unterscheidbar bleiben. Das ist nicht immer gefahrlos, da ein Objekt von auen zugnglich sein kann, etwa wenn es an externe Funktionen bergeben oder von exportierten Funktionen zurckgegeben wird. Deshalb muss Property Mangling blicherweise ausdrcklich aktiviert werden. Wenn Sie es aktivieren, sollten Sie es wahrscheinlich auf Namensmuster beschrnken, von denen bekannt ist, dass sie nur intern verwendet werden, beispielsweise auf Namen mit vorangestelltem Unterstrich.

Die Annotation /*@__KEY__*/ kennzeichnet ein Zeichenfolgenliteral als Eigenschaftsnamen, der umbenannt werden soll. Standardmig kann der Minimizer nur bestimmte Syntaxformen erkennen. Deshalb mssen Zeichenfolgen, die an beliebige Funktionen bergeben werden, ausdrcklich gekennzeichnet werden.

js
const record = { _internalValue: 42 };
Object.getOwnPropertyDescriptor(record, /*@__KEY__*/ "_internalValue");

Mit der Annotation /*@__MANGLE_PROP__*/ lsst sich Property Mangling fr eine bestimmte Eigenschaft oder ein bestimmtes Klassenfeld ausdrcklich aktivieren.

Siehe auch Terser Annotations.

JSX-Transformation

JSX-Transpiler verwenden Pragmas auf Dateiebene, um festzulegen, wie JSX in JavaScript umgewandelt wird. Zum Beispiel:

jsx
/** @jsxRuntime automatic */
/** @jsxImportSource preact */

const heading = <h1>Hello</h1>;

Daraus wird Folgendes generiert:

js
import { jsx as _jsx } from "preact/jsx-runtime";

const heading = _jsx("h1", {
  children: "Hello",
});

Diese Einstellungen knnen auch global im Transpiler konfiguriert werden. Pragmas sind nur erforderlich, wenn fr eine bestimmte Datei eine andere Einstellung gelten soll.

Siehe auch Babels JSX-Transformation und esbuilds JSX-Konfiguration.

Direktiven fr statische Prfwerkzeuge

Auch statische Prfwerkzeuge und verwandte Entwicklungswerkzeuge interpretieren Kommentare als Konfiguration oder Metadaten. Einige Beispiele:

  • JSDoc: JSDoc-Annotationen wie @type und @param liefern Typinformationen. Sie ermglichen auerdem Editorfunktionen wie eingeblendete Beschreibungen.
  • TypeScript (tsc): // @ts-check und // @ts-nocheck aktivieren oder deaktivieren die Typprfung fr eine JavaScript-Datei. // @ts-ignore unterdrckt Diagnosemeldungen fr die nchste Zeile; // @ts-expect-error meldet zustzlich einen Fehler, wenn kein Fehler zu unterdrcken war.
  • ESLint: Konfigurationskommentare wie /* eslint no-console: "warn" */ konfigurieren Regeln, whrend // eslint-disable-next-line no-console eine Regel fr die nchste Zeile deaktiviert.
  • Prettier: // prettier-ignore nimmt den nchsten Syntaxknoten von der Formatierung aus.
  • Flow: // @flow aktiviert die Typprfung fr eine Datei. Typen in Kommentaren, beispielsweise /*: number */, betten Typsyntax in JavaScript-Kommentare ein.

Veraltete bedingte Kompilierung

Warnung: Dieser Abschnitt behandelt einen IE-spezifischen Mechanismus. Wie IE selbst ist er inzwischen veraltet. Sie knnen ihm jedoch weiterhin in altem Code begegnen, und er beeinflusst noch immer die Gestaltung der Sprache etwa dadurch, dass //# sourceMapURL gegenber //@ sourceMapURL bevorzugt wird. Der Abschnitt bleibt aus historischem Interesse erhalten.

Die JScript-Engine von Internet Explorer untersttzte die bedingte Kompilierung: einen veralteten, nicht standardisierten Mechanismus, der Code innerhalb speziell gekennzeichneter Kommentare interpretieren konnte. Anders als Optimierungshinweise oder Debugging-Metadaten konnten diese Kommentare ndern, welcher Code ausgefhrt wurde.

Die Anweisung @cc_on aktivierte die bedingte Kompilierung. Mit @set wurden Variablen fr die bedingte Kompilierung definiert; @if, @elif, @else und @end whlten anhand dieser Variablen Code aus. Zu den vordefinierten Variablen gehrte @_jscript_version, die die Version der JScript-Engine angab.

js
var supportsConditionalCompilation = false;
/*@cc_on
  supportsConditionalCompilation = true;
@*/

In einer Engine, die diesen Mechanismus untersttzte, wurde die Zuweisung innerhalb des Kommentars ausgefhrt. Andere Engines behandelten den gesamten Block als gewhnlichen Kommentar, sodass die Variable false blieb. Es gab auch eine Variante als Zeilenkommentar: //@cc_on.

Siehe auch Microsofts historischen Entwurf JScript Conditional Compilation.


Web Proxy Viewer  |  New URL  |  Original Page