Модули
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.
export function add(a: number, b: number): number {
return a + b;
}
// 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 локальные спецификаторы импорта всегда должны включать полное расширение файла. Его нельзя опускать.
// WRONG: missing file extension
import { add } from "./calc";
// CORRECT: includes file extension
import { add } from "./calc.ts";
Динамический импорт
Приведённые выше инструкции import являются статическими: спецификатор представляет собой строковый литерал, и модуль загружается до запуска вашего кода. Также можно загружать модуль по требованию с помощью функции import(), которая возвращает промис с пространством имён модуля:
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 предоставляет сведения о текущем модуле и функции для разрешения путей относительно него:
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 — распространённый способ сделать файл пригодным и в качестве точки входа, и в качестве импортируемой библиотеки:
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 загружает модуль (включая его зависимости), но не выполняет его код верхнего уровня, пока вы впервые не обратитесь к свойству пространства имён:
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:.
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.
{
"imports": {
"@luca/cases": "jsr:@luca/cases@^1.0.0",
"cowsay": "npm:cowsay@^1.6.0"
}
}
С переназначенными спецификаторами код выглядит чище:
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):
{
"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 достаточно указать спецификатор модуля без завершающего символа /:
{
"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)
Последнее обновление:
© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/manual/basics/import_maps