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