Spec-Zone.ru › Deno 2

Модули

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

Deno также запускает устаревшие модули CommonJS из Node (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 называется картой импорта и основано на стандарте карт импорта.

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-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 расширяет стандарт карт импорта. При использовании поля 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/fundamentals/modules

Spec-Zone.ru

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