ES6インポートのパラメーター
私は最近、JavascriptでES6モジュールシステムのインポートステートメントを一般的な方法(相対パスまたはパッケージの名前を介してローカルモジュールのみをインポートする)だけでなく、パラメータを使用して使用できるかどうかを自問しました。
私のユースケースは次のようになります。インポート中にある種のパラメーターを提供して、インポートされたモジュール自体がそれらのパラメーターを条件付きインポートまたは特別なコード処理のフラグとして処理できるようにします。
結局のところ、それは完全に可能です!
ES6のインポートは単なるURLです
コードを見る前に、Node.jsのインポートステートメントは実際には単なるURLであることを覚えておくことが重要です。 Node.jsはデフォルトでアルゴリズムを使用して、完全に解決されたときにURLが実際にどのように見えるかを決定します。たとえば、インポート指定子として相対パスのみを指定した場合でも、Node.jsは文字列をバックグラウンドでインポートするための絶対URLに解決します。
インポートにURLクエリパラメータを使用する
また、インポートはURLに解決されるため、インポートで共通のURL検索パラメーターとURLフラグメントを使用できます。
まず、この機能をテストするためにES6モジュールがサポートされていることを確認してください。これには、package.jsonに小さな変更を加える必要があります。ここで、「type」フィールドを「module」に設定する必要があります。 Node.jsバージョン12以降を使用する必要があることに注意してください。
{
"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": ""
}
次に、簡単なデモ用に2つの最小限のモジュールを定義します。
//
// 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"}`);
}
異なるパラメータを使用した複数のインポート
Node.jsのドキュメントに記載されているように、各インポートは実行時にキャッシュされ、他のモジュールでの後続のインポートを高速化します。したがって、同じモジュールからのインポートで、パラメータが異なる場合は、それぞれが個別にキャッシュされることを知っておくことが重要です。もちろん、署名が一致するインポートは、キャッシュから読み取られます。
//
// 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();
ユースケース
この記事の例は意図的に非常に短いものですが、あなたはその考えを理解しています。要件によっては、インポートでクエリパラメータを使用することは、各モジュールの「グローバル」変数を設定するための非常に洗練されたオプションです。これにより、同じ目標を達成するためにゲッターとセッターを提供する必要がなくなります。