Parameter für einen ES6-Import
Ich habe mich kürzlich gefragt, ob es tatsächlich möglich ist, ES6-Modul-System-Import-Anweisungen in Javascript nicht nur auf die übliche Weise (nur ein lokales Modul über relativen Pfad oder Namen des Pakets importieren), sondern mit Parametern zu verwenden.
Mein Anwendungsfall wäre ungefähr so: Stellen Sie während des Imports eine Art Parameter bereit, damit das importierte Modul diese Parameter selbst als Flag für bedingte Importe oder spezielle Codebehandlung behandeln kann.
Wie sich herausstellt, ist das durchaus möglich!
ES6-Importe sind nur URLs
Bevor wir uns den Code ansehen, ist es wichtig, sich daran zu erinnern, dass import-Anweisungen in Node.js praktisch nur URLs sind. Node.js verwendet standardmäßig einen Algorithmus, um zu bestimmen, wie die URLs tatsächlich aussehen, wenn sie vollständig aufgelöst sind. Wenn Sie beispielsweise nur den relativen Pfad als Importbezeichner angeben, löst Node.js die Zeichenfolge für den Import im Hintergrund dennoch in eine absolute URL auf.
URL-Abfrageparameter für einen Import verwenden
Und da der Import in eine URL aufgelöst wird, können wir die gängigen URL-Suchparameter sowie URL-Fragmente in unseren Importen verwenden.
Stellen Sie zunächst sicher, dass ES6-Module unterstützt werden, um diese Funktion zu testen. Dies erfordert eine kleine Änderung an unserer package.json, wo das "type"-Feld auf "module" gesetzt werden muss. Beachten Sie, dass Sie Node.js Version 12 oder höher verwenden müssen.
{
"name": "es6-import-params",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
Als nächstes definieren Sie zwei minimale Module für eine einfache Demo.
//
// index.js
//
import {greet} from "./lib.js?name=Tom";
// This will print "Hello Tom".
greet();
//
// lib.js
//
// We're using Node's native 'URL'-module
// to transform the provided string into
// a usable representation.
//
// Note that 'import' here isn't part of
// an acutal import, but rather resolved
// to a global variable.
const url = new URL(import.meta.url);
// A simple greeter for demo purposes.
// We just access the map 'searchParams'
// from our usable 'url'-object and use
// a fallback if no params are provided.
export function greet() {
console.log(`Hello ${url.searchParams.get("name") || "World"}`);
}
Mehrere Importe mit unterschiedlichen Parametern
Wie in der Node.js-Dokumentation beschrieben, wird jeder Import zur Laufzeit für schnellere nachfolgende Importe in andere Module zwischengespeichert. Daher ist es wichtig zu wissen, dass Importe aus demselben Modul, aber mit unterschiedlichen Parametern einzeln zwischengespeichert werden. Importe mit passender Signatur werden dann natürlich noch aus dem Cache gelesen.
//
// index.js
//
// A small adaptation for the index.js
// file, this time importing the same
// module twice w/ different params. Each
// module gets cached twice, too.
import * as tomLib from "./lib.js?name=Tom";
import * as lukeLib from "./lib.js?name=Luke";
// 'Hello Tom'.
tomLib.greet();
// 'Hello Luke'.
lukeLib.greet();
// Still 'Hello Tom', as it's
// its own module.
tomLib.greet();
Anwendungsfälle
Die Beispiele in diesem Artikel sind absichtlich sehr kurz gehalten, aber Sie bekommen die Idee. Abhängig von Ihren Anforderungen kann die Verwendung von Abfrageparametern mit Importen eine recht elegante Möglichkeit sein, „globale“ Variablen für jedes Modul zu setzen. Dadurch entfällt die Notwendigkeit, Getter und Setter bereitzustellen, um dasselbe Ziel zu erreichen.