Spec-Zone.ru › Deno 2

Модули

Deno использует модули ECMAScript в качестве основной системы модулей — официального стандарта JavaScript. Кодом между файлами можно делиться с помощью стандартных инструкций import и export и запускать его напрямую, без сборщика или этапа сборки. Это та же система модулей, что используется в браузерах, поэтому написанный вами код остаётся переносимым между средами.

Deno также запускает устаревшие модули Node в формате CommonJS (require и module.exports), поэтому существующие пакеты npm и проекты Node работают без преобразования. Обе системы полностью поддерживаются и взаимодействуют друг с другом, однако для нового кода рекомендуется использовать модули ECMAScript; CommonJS в основном стоит выбирать, если зависимость или существующий проект всё ещё использует его.

Deno определяет систему, используемую файлом, по его расширению и ближайшему package.json: файл .mjs всегда является модулем ES, файл .cjs всегда использует CommonJS, а файлы .js и .ts считаются модулями ES, если только package.json не задаёт "type": "commonjs". Остальная часть этой страницы посвящена модулям ES; о том, как работают require, разрешение модулей и взаимодействие ESM/CommonJS, см. в разделе Поддержка CommonJS.

Импорт модулей

В этом примере функция add импортируется из локального модуля calc.ts.

calc.ts
export function add(a: number, b: number): number {
  return a + b;
}
main.ts
// imports the `calc.ts` module next to this file
import { add } from "./calc.ts";

console.log(add(1, 2)); // 3

Запустить этот пример можно, вызвав deno run main.ts в каталоге, содержащем файлы main.ts и calc.ts.

При использовании модулей ECMAScript локальные спецификаторы импорта всегда должны включать полное расширение файла. Его нельзя опускать.

example.ts
// WRONG: missing file extension
import { add } from "./calc";

// CORRECT: includes file extension
import { add } from "./calc.ts";

Динамический импорт

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

main.ts
const { add } = await import("./calc.ts");

console.log(add(1, 2)); // 3

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

if (Deno.args.includes("--greet")) {
  const { greet } = await import("./greet.ts");
  greet();
}

Динамический import() со строковым литералом в качестве спецификатора является частью статического графа модулей и загружается без дополнительных разрешений. Если спецификатор вычисляется во время работы программы, он проверяется системой разрешений при выполнении: для локальных путей требуется --allow-read, а для удалённых URL — --allow-import. Подробности см. в разделе Безопасность.

Метаданные импорта

В любом модуле import.meta предоставляет сведения о текущем модуле и функции для разрешения путей относительно него:

main.ts
console.log(import.meta.url); // file:///path/to/main.ts
console.log(import.meta.main); // true if this is the entry module
console.log(import.meta.filename); // /path/to/main.ts (local modules only)
console.log(import.meta.dirname); // /path/to (local modules only)
console.log(import.meta.resolve("./data.json")); // resolves a specifier to a URL

import.meta.main — распространённый способ сделать файл пригодным и в качестве точки входа, и в качестве импортируемой библиотеки:

server.ts
export function createServer() {/* ... */}

// Only start the server when run directly, not when imported.
if (import.meta.main) {
  createServer();
}

filename и dirname — это undefined для удалённых модулей. Полное пошаговое руководство см. в руководстве по метаданным модулей.

Атрибуты импорта

Deno поддерживает синтаксис атрибута импорта with { type: "json" } для импорта файлов JSON:

import data from "./data.json" with { type: "json" };

console.log(data.property); // Access JSON data as an object

Начиная с Deno 2.4 можно также импортировать модули text и bytes.

import text from "./log.txt" with { type: "text" };

console.log(typeof text === "string");
// true
console.log(text);
// Hello from a text file
Импорт text

Стабильно в Deno 2.8; флаг больше не требуется.

import bytes from "./image.png" with { type: "bytes" };

console.log(bytes instanceof Uint8Array);
// true
console.log(bytes);
// Uint8Array(12) [
//    72, 101, 108, 108, 111,
//    44,  32,  68, 101, 110,
//   111,  33
// ]
Импорт bytes

Пока находится в экспериментальном статусе. Включите его с помощью флага CLI --unstable-raw-imports или параметра unstable.raw-import в файле deno.json.

Таблицу стилей можно импортировать с помощью with { type: "css" }. Результатом импорта будет CSSStyleSheet, как и в браузерах. Это в основном полезно для запуска в Deno неизменённых графов модулей браузера, например при серверном рендеринге или тестировании веб-компонентов, когда без этого CSS-импорт не позволил бы загрузить граф модулей:

import sheet from "./styles.css" with { type: "css" };

console.log(sheet instanceof CSSStyleSheet);
// true

Динамический импорт работает так же:

const { default: sheet } = await import("./styles.css", {
  with: { type: "css" },
});

Статический импорт и динамический импорт со статически анализируемым спецификатором загружаются как часть графа модулей и не требуют разрешений. Только динамический импорт со спецификатором, который невозможно проанализировать, например import(base + "styles.css"), считывает файл во время выполнения и поэтому требует разрешения на чтение (--allow-read).

Deno реализует небольшую часть интерфейса CSSStyleSheet, на который опираются графы модулей браузера:

  • cssRules возвращает правила верхнего уровня таблицы стилей. В отличие от браузера, это замороженный массив объектов CSSRule (а не динамически обновляемый CSSRuleList); при каждом обращении создаётся новый массив.
  • CSSRule.cssText — это текст одного правила верхнего уровня без изменений.
  • replace(text) и replaceSync(text) заменяют содержимое таблицы стилей. Как и в браузере для создаваемых таблиц стилей, правила @import верхнего уровня удаляются.
  • Конструктор new CSSStyleSheet() доступен, но его аргумент options (media, disabled, baseURL) не поддерживается.
import sheet from "./styles.css" with { type: "css" };

for (const rule of sheet.cssRules) {
  console.log(rule.cssText);
}

sheet.replaceSync("body { color: red; }");

Поскольку в Deno нет DOM, таблицу стилей нельзя подключить ни к одному элементу; реализация опирается на исходный текст CSS, а не на полноценную объектную модель CSS. cssRules использует упрощённое разделение правил верхнего уровня, поэтому методы динамического изменения insertRule и deleteRule не реализованы.

Импорт css

Пока находится в экспериментальном статусе. Включите его с помощью флага CLI --unstable-raw-imports или параметра unstable.raw-import в файле deno.json.

Отложенное выполнение модулей

Начиная с Deno 2.8 поддерживается предложение TC39 об отложенном выполнении модулей. Синтаксис import defer загружает модуль (включая его зависимости), но не выполняет его код верхнего уровня, пока вы впервые не обратитесь к свойству пространства имён:

main.ts
import defer * as expensive from "./expensive.ts";

console.log("startup is fast: expensive.ts has not run yet");

// Touching any property triggers synchronous evaluation
console.log(expensive.value);

Используйте его, чтобы отложить загрузку модулей, которые нужны только при определённых условиях; например, кода обработки ошибок в CLI-инструменте или реализации функции, включаемой флагом, если её инициализация требует значительных затрат.

Предложение всё ещё находится на третьем этапе TC39, поэтому этот синтаксис считается экспериментальным и может измениться. Стандартный import по-прежнему остаётся рекомендуемым вариантом по умолчанию.

Модули WebAssembly

Deno поддерживает прямой импорт модулей Wasm:

import { add } from "./add.wasm";

console.log(add(1, 2));

Именованные экспорты соответствуют экспортам модуля Wasm: функции, памяти и таблицы доступны в виде соответствующих объектов JavaScript, а экспорт global разрешается в содержащееся в нём значение, а не в оболочку WebAssembly.Global, что соответствует интеграции модулей WebAssembly с ES.

Подробнее см. в разделе WebAssembly

Импорт URL данных

Deno поддерживает импорт URL данных, позволяющий импортировать содержимое, которое не находится в отдельном файле. Это удобно для тестирования, прототипирования или программной генерации модулей.

Модули можно создавать на лету с помощью схемы URL data::

// Import a simple JavaScript module from a data URL
import * as module from "data:application/javascript;base64,ZXhwb3J0IGNvbnN0IG1lc3NhZ2UgPSAiSGVsbG8gZnJvbSBkYXRhIFVSTCI7";
console.log(module.message); // Outputs: Hello from data URL

// You can also use the non-base64 format
const plainModule = await import(
  "data:application/javascript,export function greet() { return 'Hi there!'; }"
);
console.log(plainModule.greet()); // Outputs: Hi there!

// A simpler example with text content
const textModule = await import(
  "data:text/plain,export default 'This is plain text'"
);
console.log(textModule.default); // Outputs: This is plain text

Формат URL данных соответствует следующему шаблону:

›_
data:[<media type>][;base64],<data>

Для модулей JavaScript используйте application/javascript в качестве типа медиа. Также поддерживается TypeScript с application/typescript. Эта возможность особенно полезна для изолированного тестирования модулей и создания модулей-заглушек во время тестов.

Импорт сторонних модулей и библиотек

При работе со сторонними модулями в Deno используйте тот же синтаксис import, что и для локального кода. Сторонние модули обычно импортируются из удалённого реестра, а их спецификаторы начинаются с jsr: или npm:.

main.ts
import { camelCase } from "jsr:@luca/cases@1.0.0";
import { say } from "npm:cowsay@1.6.0";

Deno рекомендует использовать JSR — современный реестр JavaScript для сторонних модулей. Здесь вы найдёте множество хорошо документированных модулей ES для своих проектов, включая стандартную библиотеку Deno.

Подробнее о поддержке пакетов npm в Deno можно прочитать здесь.

Управление сторонними модулями и библиотеками

При импорте модулей в нескольких файлах вводить имя модуля с полным указанием версии может быть утомительно. Управлять удалёнными модулями централизованно можно с помощью поля imports в файле deno.json. Это поле imports называется картой импорта и основано на стандарте Import Maps.

deno.json
{
  "imports": {
    "@luca/cases": "jsr:@luca/cases@^1.0.0",
    "cowsay": "npm:cowsay@^1.6.0"
  }
}

С переназначенными спецификаторами код выглядит чище:

main.ts
import { camelCase } from "@luca/cases";
import { say } from "cowsay";

Переназначенное имя может быть любым допустимым спецификатором. Это очень гибкая возможность Deno, позволяющая переназначать что угодно. Подробнее см. в разделе о зависимостях в конфигурации.

Различия между imports или importMap в deno.json и параметром --import-map

Стандарт Import Maps требует две записи для каждого модуля: одну для спецификатора модуля и другую для спецификатора с завершающим символом /. Это связано с тем, что стандарт допускает только одну запись на спецификатор модуля, а завершающий символ / указывает, что спецификатор относится к каталогу. Например, при использовании параметра --import-map import_map.json файл import_map.json должен содержать обе записи для каждого модуля (обратите внимание: вместо jsr:@std/async используется jsr:/@std/async):

import_map.json
{
  "imports": {
    "@std/async": "jsr:@std/async@^1.0.0",
    "@std/async/": "jsr:/@std/async@^1.0.0/"
  }
}

Файл import_map.json, указанный в поле importMap файла deno.json, работает точно так же, как параметр --import-map, и для каждого модуля необходимо включить обе записи, как показано выше.

В отличие от этого, deno.json расширяет стандарт import maps. При использовании поля imports в deno.json достаточно указать спецификатор модуля без завершающего символа /:

deno.json
{
  "imports": {
    "@std/async": "jsr:@std/async@^1.0.0"
  }
}

Управление зависимостями

Теперь, когда вы знаете, как Deno разрешает и импортирует модули, ознакомьтесь с руководством по управлению зависимостями, где описаны повседневные задачи: добавление и удаление пакетов с помощью deno add / deno remove, фиксация версий, переопределение и включение зависимостей в проект, файлы блокировки и проверка целостности, управление цепочкой поставок, публикация собственных модулей и использование приватных реестров.

Обновление версий из командной строки

Необязательно вручную редактировать номера версий в deno.json. Чтобы обновить зависимости до более новых версий, запустите deno outdated, чтобы узнать, какие версии устарели, а затем выполните deno outdated --update, чтобы обновить их:

›_
deno outdated            # list dependencies with newer versions available
deno outdated --update   # update them in deno.json

Чтобы увеличить значение поля version собственного пакета между выпусками, используйте deno bump-version:

›_
deno bump-version patch  # 1.4.6 -> 1.4.7 (also: minor, major, or a prerelease)

Последнее обновление: 30 июня 2026 г.

© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/manual/basics/import_maps

Spec-Zone.ru

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