Создание приложений командной строки
Deno отлично подходит для создания инструментов командной строки. Ваш инструмент — это просто TypeScript, поэтому для его запуска не требуется этап сборки. Когда вы будете готовы распространять его, deno compile превратит его в единый автономный исполняемый файл, который работает без установленного Deno.
Чтение аргументов командной строки
Исходные аргументы доступны в Deno.args. Для полноценных инструментов разбирайте их с помощью @std/cli: он обрабатывает флаги, параметры и значения по умолчанию:
import { parseArgs } from "jsr:@std/cli/parse-args";
const flags = parseArgs(Deno.args, {
string: ["name"],
default: { name: "world" },
});
console.log(`Hello, ${flags.name}!`);
$ deno run greet.ts --name=Deno
Hello, Deno!
Чтение из stdin и определение TTY
Хорошие инструменты командной строки умеют работать в конвейерах. Deno.stdin предоставляет стандартный ввод как поток ReadableStream, поэтому проще всего прочитать весь текст, переданный через конвейер, обернув его в Response:
const input = await new Response(Deno.stdin.readable).text();
Если ваш инструмент можно использовать обоими способами, применяйте Deno.stdin.isTerminal(), чтобы определить, является ли stdin интерактивным терминалом или конвейером, и выбирать дальнейшее поведение соответствующим образом. Так же инструменты решают, выводить ли цвета и индикаторы выполнения (в интерактивном режиме) или обычный машиночитаемый вывод (при передаче через конвейер). В этом примере, если данные не поступают через конвейер, инструмент запрашивает их у пользователя:
let input: string;
if (Deno.stdin.isTerminal()) {
input = prompt("Enter some text:") ?? "";
} else {
input = await new Response(Deno.stdin.readable).text();
}
console.log(`Got ${input.trim().length} characters`);
$ echo "hello from a pipe" | deno run count.ts
Got 17 characters
$ deno run count.ts
Enter some text: hi
Got 2 characters
Для чтения из stdin не нужны флаги разрешений.
Если вы переносите инструмент командной строки Node.js или используете библиотеки npm для чтения входных данных, стиль Node.js process.stdin (из node:process или глобального объекта process) также работает в Deno, поэтому такой код можно использовать без изменений.
Запрос ввода у пользователя
Для простого интерактивного ввода в Deno доступны браузерные глобальные функции prompt(), confirm() и alert(). Они блокируют выполнение до ответа пользователя (выполнение приостанавливается на этой строке, и ничего больше не запускается, пока не поступят данные) и не требуют импортов или разрешений:
const name = prompt("Project name:", "my-app");
const ok = confirm(`Create ${name}?`);
if (!ok) Deno.exit(1);
console.log(`Creating ${name}...`);
Для более сложных задач используйте @std/cli. Помимо разбора аргументов, библиотека включает индикаторы загрузки, индикаторы выполнения и запросы с выбором. Эти модули имеют префикс unstable-, поэтому их API всё ещё может измениться. Класс Spinner отображает анимированную строку состояния, пока работает ваш инструмент:
import { Spinner } from "jsr:@std/cli/unstable-spinner";
const spinner = new Spinner({ message: "Downloading..." });
spinner.start();
await new Promise((resolve) => setTimeout(resolve, 2000));
spinner.stop();
console.log("Done");
deno run spin.ts
Завершение с правильным кодом
Оболочки, скрипты и системы CI полагаются на код завершения вашего инструмента: ноль означает успех, любое другое значение — ошибку. Deno.exit() немедленно завершает процесс с указанным кодом:
if (Deno.args.length === 0) {
console.error("Usage: check <file>...");
Deno.exit(2);
}
Поскольку Deno.exit() немедленно останавливает процесс, незавершённые операции, например сброс журналов или блоки finally, не выполняются. Если нужно зафиксировать ошибку, но продолжить работу, вместо этого задайте Deno.exitCode. Процесс продолжит работу, завершится естественным образом, а затем выйдет с указанным кодом. Так следует поступать в линтерах и пакетных инструментах, которые должны сообщать обо всех проблемах, а не останавливаться на первой:
for (const file of Deno.args) {
try {
await Deno.lstat(file);
} catch {
console.error(`Missing: ${file}`);
Deno.exitCode = 1;
}
}
console.log("Check finished");
$ deno run --allow-read check.ts real.txt nope.txt
Missing: nope.txt
Check finished
$ echo $?
1
Для ненулевых кодов нет строго установленного значения, кроме «ошибка», но обычно 1 используют для ошибок, которые проверяет ваш инструмент, а 2 — для ошибок использования, например отсутствующих аргументов.
Компиляция в единый исполняемый файл
deno compile объединяет вашу программу и среду выполнения Deno в один двоичный файл: никаких node_modules и никакой установки для пользователей.
deno compile greet.ts
./greet --name=Deno
Задайте имя двоичного файла с помощью --output. Если вашему инструменту нужны разрешения, добавьте их при сборке с помощью обычных флагов --allow-*, чтобы запускать его без запросов:
deno compile --output greet greet.ts
Если размер двоичного файла важнее максимальной скорости выполнения, можно собрать его для экспериментального движка QuickJS вместо V8 с помощью --engine quickjs. Подробнее о компромиссах см. в разделе выбор движка JavaScript.
Встраивание ресурсов в двоичный файл
Исполняемый файл из одного файла должен оставаться таким и в том случае, если инструменту нужны данные, например шаблоны, списки слов или конфигурации по умолчанию. Передайте --include, чтобы включить файлы или каталоги в двоичный файл:
deno compile --include names.csv --output greet greet.ts
Во время выполнения читайте встроенные файлы относительно каталога модуля с помощью import.meta.dirname:
const names = Deno.readTextFileSync(import.meta.dirname + "/names.csv");
Один и тот же код работает как при разработке с deno run, так и в скомпилированном двоичном файле, независимо от того, откуда пользователь его запускает. Сведения о включении каталогов и настройке путей один раз в deno.json см. в разделе включение файлов с данными.
Кросс-компиляция для других платформ
Собирайте приложение для другой платформы с помощью --target, чтобы создавать двоичные файлы для Windows, macOS и Linux на одном компьютере:
deno compile --target x86_64-pc-windows-msvc --output greet.exe greet.ts
deno compile --target aarch64-apple-darwin --output greet greet.ts
Полный список целевых платформ включает сборки Linux, macOS и Windows для x86_64 и ARM; см. раздел поддерживаемые целевые платформы. Если вы распространяете двоичные файлы среди конечных пользователей, их также можно подписать, чтобы операционные системы доверяли вашему инструменту; инструкции для macOS и Windows см. в разделе подписание кода.
Установка инструмента из исходного кода
Чтобы сделать скрипт доступным в виде команды на своём компьютере (без компиляции), установите его глобально с помощью deno install:
deno install --global --name greet greet.ts
greet --name=Deno
Что ещё можно изучить
- deno compile. Все целевые платформы, флаги, встраивание ресурсов, значки и подписание кода.
- deno install. Установка инструментов и зависимостей.
- @std/cli. Разбор аргументов, индикаторы загрузки и выполнения, а также интерактивные запросы.
-
Справочник по API Deno. Всё, что относится к пространству имён
Deno, включая stdin, коды завершения и API для работы с файлами. - Разрешения. Точный выбор того, к чему может обращаться скомпилированный инструмент.
Последнее обновление:
© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/cli_apps