ES6 импорт с параметрами

Как передать параметры в модуль ES6 при его импорте

Параметры для ES6-импорта

Недавно я спросил себя, действительно ли возможно использовать операторы импорта системы ES6-модулей в Javascript не только обычным способом (импортируя только локальный модуль через относительный путь или имя пакета), но и с параметрами.

Мой вариант использования будет примерно таким: предоставить какие-то параметры во время импорта, чтобы импортированный модуль мог сам обрабатывать эти параметры как флаг для условного импорта или специальной обработки кода.

Как оказалось, это вполне возможно!

Импорт 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": ""
}

Затем определите два минимальных модуля для простой демонстрации.

//
// 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();

Сценарии использования

Примеры в этой статье намеренно очень короткие, но вы уловили идею. В зависимости от ваших требований использование параметров запроса с импортом может быть довольно элегантным вариантом для установки «глобальных» переменных для каждого модуля. Это избавляет от необходимости использовать геттеры и сеттеры провайдера для достижения одной и той же цели.

Предложения

Связанные

Приложение

Языки