Spec-Zone.ru › JavaScript

import source

Декларация import source похожа на обычную декларацию import, за исключением того, что она приводит к созданию объекта, представляющего скомпилированный исходный код модуля. Модуль загружается и компилируется, но его зависимости не загружаются, и он не связывается и не вычисляется. Он может быть императивно вычислен позже, например, с помощью динамического импорта или WebAssembly.instantiate().

Чтобы использовать import source, целевой модуль должен относиться к типу, поддерживающему импорт фазы исходного кода. В настоящее время только модули WebAssembly поддерживают импорт фазы исходного кода и возвращают объекты WebAssembly.Module. Объекты исходного кода модулей JavaScript будут добавлены в соответствии с предложением ECMAScript Module Phase Imports.

Синтаксис

import source x from "module-name";
x
Имя, которое будет ссылаться на объект исходного кода модуля. Должно быть допустимым идентификатором JavaScript.
module-name
Модуль для импорта. Обрабатывается так же, как module-name в обычных декларациях import.

Атрибуты импорта (Import attributes) также поддерживаются, используя условие with после спецификатора модуля.

source не является зарезервированным словом. Например, import source from "./module.js" по-прежнему является обычным импортом по умолчанию, локальное связывание которого названо source.

Исключения

SyntaxError
Выдается, если целевой модуль не поддерживает импорт фазы исходного кода.

Описание

По умолчанию декларация import выполняет множество задач одновременно: разрешение спецификатора модуля, загрузку исходного кода модуля, синтаксический анализ (потенциальное обнаружение транзитивных зависимостей), связывание и вычисление. Эта форма немедленного вычисления (eager evaluation) не всегда желательна, особенно когда исходный код модуля предназначен для вычисления в каком-либо другом контексте, например, в рабочем потоке.

Модификатор фазы импорта (import phase modifier) позволяет процессу импорта модуля остановиться на определенной фазе. При добавлении source после import исходный код анализируется и компилируется, но остается не связанным и не вычисленным. Импорт исходного кода не загружает транзитивные зависимости модуля.

Традиционно, единственный способ запустить часть конвейера заключался в ручной реализации всей его части. Например, в случае с WebAssembly вы сначала используете fetch() для получения бинарных байтов модуля, а затем компилируете их с помощью WebAssembly.compile() или компилируете поток ответа с помощью WebAssembly.compileStreaming() в объект WebAssembly.Module.

const myModuleSource = await WebAssembly.compileStreaming(
  fetch("./my-module.wasm"),
);

Такой ручной рабочий процесс проблематичен по нескольким причинам:

  • Он включает слишком много низкоуровневых манипуляций, что может быть несовместимо с поведением загрузчика модулей по умолчанию, таким как кэширование, настройки заголовков HTTP и разрешение спецификаторов модулей.
  • Он является императивным, что затрудняет анализ зависимостей модуля и порядка их вычисления, особенно для сборщиков (bundlers) или других инструментов анализа.
  • Вычисление необработанного исходного кода на уровне пользовательского кода (userland evaluation) несовместимо со строгими настройками CSP.

Использование импорта фазы исходного кода позволяет избежать этих проблем.

import source myModuleSource from "./my-module.wasm";

Объект, полученный при таком импорте, является экземпляром подкласса AbstractModuleSource. Каждый тип модуля, поддерживающий импорт фазы исходного кода, определяет свой собственный подкласс. Для WebAssembly подклассом является WebAssembly.Module. Этот объект кэшируется для конкретного модуля, так что последующие импорты исходного кода с тем же спецификатором возвращают один и тот же объект.

В отличие от import defer, использование импорта исходного кода также откладывает связывание. Связывание на раннем этапе позволяет загрузчику модулей разрешить зависимости, обнаруживая отсутствующие зависимости или недопустимые импорты до того, как модуль будет использован. Сохранение модуля несвязанным позволяет избежать загрузки зависимостей, которые могут не понадобиться, и позволяет вам контролировать, как он будет инстанцирован. Например, вы можете инстанцировать импортированный исходный модуль WebAssembly несколько раз с разными импортами или отправить его в рабочий поток для инстанцирования там.

В отличие от import(), импортированный исходный модуль загружается и компилируется заранее, без вычисления. import source также обладает большинством преимуществ статической декларации, таких как улучшенный статический анализ.

Обратите внимание, что поддерживается только синтаксис "импорта по умолчанию" (default import). Вы не можете использовать import source { property } from "./my-module.wasm" и т. д.

Импорт исходного кода WebAssembly

Для WebAssembly вы предоставляете импортируемые значения при инстанцировании модуля:

import source myModuleSource from "./my-module.wasm";

const instance = await WebAssembly.instantiate(myModuleSource, {
  env: { log: console.log },
});
const { exports } = instance;

В отличие от обычного импорта модуля WebAssembly, это создает новый экземпляр с предоставленными вами импортами, а не использует кэшированный экземпляр, связанный загрузчиком модулей. Его объект exports не является объектом пространства имен модуля JavaScript. Например, глобальные переменные WebAssembly представляются как объекты WebAssembly.Global через instance.exports, тогда как интеграция ESM предоставляет их значения импортерам JavaScript.

Примечание: Поддержка импорта фазы исходного кода WebAssembly не подразумевает поддержку обычного импорта модулей WebAssembly. Хост может поддерживать import source mod from "./mod.wasm", отклоняя import * as ns from "./mod.wasm".

Импорт исходного кода использует загрузчик модулей хоста, включая его настройки компиляции. Они не обязательно эквивалентны вызову WebAssembly.compileStreaming() с параметрами по умолчанию. Например, Node.js включает встроенные строковые функции JavaScript для импорта Wasm и отклоняет зарезервированные имена импорта и экспорта. Используйте прямые API компиляции WebAssembly, когда вам требуются пользовательские параметры компиляции.

Импорт исходного кода JavaScript

Для JavaScript (при условии поддержки предлагаемого import(moduleSource), также в ECMAScript Module Phase Imports):

import * as namespace from "./my-module.js";

// Is equivalent to:

import source myModuleSource from "./my-module.js";

const namespace = await import(myModuleSource);

Семантика кэширования

Модификатор применяется к импорту, а не к самому модулю. Если другая часть приложения импортирует тот же модуль без source, модуль вычисляется как обычно. Обе формы используют одно и то же состояние модуля, и код модуля выполняется не более одного раза. Изменение фазы импорта не создает отдельный модуль в кэше:

import * as x from "foo";
import source xSource from "foo";

console.log((await import(xSource)) === x); // true

Примечание: Этот кэшированный экземпляр используется повторно, когда вы используете import(), но не при ручном инстанцировании WebAssembly. Каждый вызов WebAssembly.instantiate(modSource, imports) или new WebAssembly.Instance(modSource, imports) создает новый экземпляр и выполняет его инициализацию, включая любую стартовую функцию. В отличие от этого, WebAssembly.compileStreaming() только компилирует; он не выполняет модуль и не использует кэш модулей ESM.

Напротив, атрибуты импорта могут влиять на идентификацию модуля. Например, в хосте, который поддерживает текстовые модули, эти две декларации запрашивают разные типы модулей:

import * as mod from "./module.js";
import text from "./module.js" with { type: "text" };

Два импорта считаются относящимися к разным модулям, которые имеют общий строковый спецификатор (в вебе они будут запрошены с разными заголовками HTTP). Поддерживаемые атрибуты и их влияние на загрузку и идентификацию модуля определяются хостом.

Примеры

Инстанцирование модуля с различными импортами

Предположим, counter.wasm импортирует неизменяемую глобальную переменную i32 с именем initial из env, инициализирует из нее внутренний счетчик и экспортирует функцию с именем increment. Вы можете повторно использовать его скомпилированный исходный код с различными импортами и независимыми внутренними счетчиками:

import source counterSource from "./counter.wasm";

const first = await WebAssembly.instantiate(counterSource, {
  env: { initial: 0 },
});
const second = await WebAssembly.instantiate(counterSource, {
  env: { initial: 100 },
});

console.log(first.exports.increment()); // 1
console.log(first.exports.increment()); // 2
console.log(second.exports.increment()); // 101

Каждый экземпляр имеет свое собственное внутреннее состояние, хотя явно импортированные памяти, таблицы или другие изменяемые объекты могут совместно использоваться экземплярами. Вы также можете отправить скомпилированный исходный код в рабочий поток для инстанцирования там.

Экспорт исходного кода модуля

Не существует синтаксиса export source (см. export для получения дополнительной информации). Вы можете импортировать исходный код модуля, а затем экспортировать его привязку, не инстанцируя и не вычисляя модуль:

// -- sources.js --
import source counterSource from "./counter.wasm";

export { counterSource };
// -- main.js --
import { counterSource } from "./sources.js";

const instance = new WebAssembly.Instance(counterSource, {
  env: { initial: 0 },
});

Спецификации

Спецификация
Source Phase Imports
# sec-import-calls

Совместимость с браузерами

Десктопные Мобильные Серверные
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
import_source
Нет
Нет
153
Нет
Нет
Нет
153
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет
import_wasm_modules
Нет
Нет
Предпросмотр
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет
Нет

Смотрите также

  • Руководство по модулям JavaScript
  • import
  • import.source()
  • AbstractModuleSource

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import/source

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API