
Deno 1.33: грядет Deno 2
Первоначально опубликовано на deno.com/blog.
Как упоминалось в недавней презентации Принудительная оптимизация на Node Congress 2023», мы усердно работаем над основным выпуском Deno 2 в ближайшие месяцы. Хотя наше видение Deno 2 амбициозно, наши цели не изменились с тех пор, как мы начали проект:
Легкое кодирование. Будь то удаление конфигурации, стандартного кода или шагов сборки, мы продолжаем упрощать вам погружение в код и немедленно приступать к работе. Этот выпуск сделал наш LSP более надежным, позволяя любому редактору кода с поддержкой LSP отлично работать с проектами Deno.
Лучшая в своем классе производительность. Скорость и эффективность важны для разработчиков и пользователей. Этот выпуск улучшил производительность серверов HTTP и WebSocket, а также заложил основу для дальнейшей работы над повышением производительности.
Бескомпромиссная безопасность. Безопасность была встроена в Deno с моделью разрешений по выбору, поэтому вы всегда знаете, к чему имеет доступ ваш код. В ближайшие месяцы мы представим новые функции в системе разрешений Deno, которые упростят и сделают работу с ней более гибкой.
Deno 1.33 — еще один шаг к этим идеалам. С этим выпуском:
- Встроенная база KV
- Плоская
deno.jsonконфигурация - Меньше проверок разрешений для динамического импорта
- Улучшения совместимости npm и Node
- Улучшения производительности
- Улучшения интерфейса командной строки
- Предварительная загрузка документов ЛСП
- Изменения в
DenoAPI - Изменения в стандартной библиотеке
- V8 11.4
По мере того, как мы приближаемся к Deno 2, следующие второстепенные выпуски будут сосредоточены на повышении производительности, создании лучшего в своем классе опыта для разработчиков, повышении безопасности и более надежной совместимости Node/npm.
Встроенная база данных КВ
Deno KV — это бесшовно интегрированная база данных внутри Deno. Без установки каких-либо зависимостей вы можете сразу приступить к созданию приложений. Кроме того, при развертывании в Deno Deploy ваши данные поддерживаются согласованной глобальной базой данных с геореплицированием. Имейте в виду, что KV в настоящее время является нестабильным API, поэтому для его использования вам понадобится флаг — нестабильности.
Начните работу с KV в кратчайшие сроки и без настройки:
const kv = await Deno.openKv();
const key = ["users", crypto.randomUUID()];
const value = { name: "Alice" };
await kv.set(key, value);
const result = await kv.get(key);
result.value; // { name: "Alice" }
Конечно, данные являются надежными и постоянными на диске, что обеспечивает надежное хранение и доступ даже после перезапуска программы.
Чтобы получить исчерпывающую документацию, изучите руководство.
Плоская deno.json конфигурация
Схема deno.json была упрощена, чтобы ее было легче читать и писать.
Вложенные параметры, такие как "lint.files.exclude" или "fmt.options.lineWidth", теперь доступны на верхнем уровне соответствующих разделов.
Вместо того, чтобы писать это:
{
"lint": {
"files": {
"exclude": ["gen.ts"]
}
},
"fmt": {
"options": {
"lineWidth": 80
}
}
}
Теперь вы можете написать это с тем же эффектом:
{
"lint": {
"exclude": ["gen.ts"]
},
"fmt": {
"lineWidth": 80
}
}
Все изменения:

Это изменение обратно совместимо, но мы стремимся отказаться от старой схемы в будущем.
Спасибо @scarf005 за внедрение этого изменения.
Меньше проверок разрешений для динамического импорта
В этом выпуске значительно улучшено качество жизни при работе с динамическим импортом.
Если вы используете строковый литерал в вызове import() (например, import("https://deno.land/std/version.ts")), Deno больше не будет требовать разрешения для выполнения этого импорта. Мы уже давно можем загружать и анализировать такие виды импорта, и после обсуждений решили, что лучше не требовать разрешения на выполнение этого кода — он уже является частью «графа модулей» вашей программы и отображается в выход deno info main.ts.
Это изменение упростит условное выполнение некоторого кода в определенных ситуациях — например, если у вас есть инструмент CLI, который включает много подкоманд, вы можете захотеть условно загрузить соответствующие обработчики только при вызове подкоманды. Это значительно сокращает время запуска вашего инструмента. Другой пример — загрузка полифилла только тогда, когда это необходимо, или выполнение кода отладки в вашем серверном приложении только при наличии переменной среды.
Имейте в виду, что разрешения по-прежнему будут проверяться для динамического импорта, который не поддается статическому анализу (т. е. не используйте строковые литералы для спецификатора):
import("" + "https://deno.land/std/version.ts");
import(`https://deno.land/std@${STD_VERSION}/version.ts`);
const someVariable = "./my_mod.ts";
import(someVariable);
Спасибо Найим Рахман за внедрение этого изменения.
Улучшения совместимости npm и Node.
Модуль node:crypto, node:http и node:vm был значительно улучшен по сравнению с последним выпуском. Мы полифилили большинство node:crypto API, которые разблокировали многие популярные пакеты npm (включая SDK облачных провайдеров). Изменения в node:http и node:vm особенно полезны для пользователей Vite, и теперь Vite должен быть намного более стабильным и производительным при использовании с Deno.
Полный список всех API, реализованных в этом релизе:
crypto.checkPrimecrypto.checkPrimeSynccrypto.createSecretKeycrypto.createVerifycrypto.ECDHcrypto.generateKeycrypto.generateKeyPaircrypto.generateKeyPairSynccrypto.generateKeySynccrypto.generatePrimecrypto.generatePrimeSynccrypto.getCurvescrypto.hkdfcrypto.hkdfSynccrypto.signcrypto.Signcrypto.verifycrypto.Verifycrypto.X509Certificatehttp.ClientRequest.setTimeouthttp.IncomingMessage.socketmodule.Module._preloadModulesvm.runInThisContext
Что касается поддержки npm, мы значительно улучшили обработку кеша для пакетов npm. Начиная с этого выпуска, Deno будет пытаться извлечь информацию из реестра, когда обнаружит отсутствующую версию (или несоответствие версий) пакета в кэше. Это должно привести к гораздо меньшему количеству сообщений, предлагающих использовать флаг --reload для получения последней информации реестра.
Улучшения производительности
В этом выпуске мы пересмотрели наши реализации HTTP-сервера, а также клиента и сервера для WebSockets. За последние несколько месяцев мы получили отзывы о том, что API-интерфейсы Deno.serve и WebSocket не так эффективны и надежны, как должны быть.
Мы приняли эти отзывы близко к сердцу и неустанно работаем над их улучшением. Хотя изменения в тестах RPS могут быть еще не видны в ваших приложениях, мы предприняли радикальные шаги для повышения общей производительности этих API, которые мы представим в ближайшие месяцы.
Улучшения интерфейса командной строки
deno bench - --no-run флаг
В этом выпуске к подкоманде deno bench добавлен новый флаг --no-run для кэширования всех разрешенных тестовых файлов без их запуска. Это выравнивает deno bench с deno test.
> deno bench --no-run Download https://deno.land/[email protected]/path/mod.ts Download ...etc... Check file:///home/user/project/main_bench.ts
Спасибо Geert-Jan Zwiers за эту функцию.
deno task - unset команда
Кроссплатформенная команда unset была добавлена в оболочку в deno task, чтобы разрешить удаление переменных среды и оболочки. Это работает так же, как команда POSIX unset, и выполнение MY_VAR= теперь корректно устанавливает пустую переменную.
{
"tasks": {
// `deno task example` outputs "1" then "false"
"example": "export VAR=1 && echo $VAR && deno task next",
"next": "unset VAR && deno eval 'console.log(Deno.env.has(\"VAR\"))'"
}
}
Предварительная загрузка документов LSP
В предыдущих версиях Deno вы могли обнаружить, что некоторые функции не работают, если вы ранее не открывали файл. Например, выполнение «поиска ссылок» для некоторого кода могло не показать, что он используется в тестовом файле, если тестовый файл не был ранее открыт. Эта проблема теперь устранена за счет предварительной загрузки файлов при инициализации языкового сервера, что должно значительно улучшить работу.
Обратите внимание, что в рамках этой предварительной загрузки языковой сервер просматривает максимум 1000 записей файловой системы и выводит сообщение журнала, когда это происходит. В тех случаях, когда это проблема и в рабочей области много файлов, не связанных с Deno, вы можете воспользоваться опцией "deno.enablePaths", чтобы частично активировать рабочую область.
Изменения в Deno API
Мы объявляем Deno.run API устаревшим. Со стабилизацией Deno.Command API в версии 1.31 это наш рекомендуемый способ порождения подпроцессов. Deno.run имеет несколько особенностей, которые оказалось трудно решить, и мы направили большую часть наших усилий на разработку лучшего API, который будет проще в использовании. Deno.run будет удалено в версии 2.0, поэтому мы настоятельно рекомендуем вам перенести свой код на Deno.Command.
Нестабильный API Deno.serve получает критическое изменение, удаляя одну из перегрузок API в рамках подготовки к стабилизации этого API. Перегрузка Deno.serve(handler: Deno.ServeHandler, options: Deno.ServeOptions) была удалена и больше не доступна в версии 1.33.
Обновите свой код, чтобы использовать одну из доступных перегрузок:
Deno.serve((_req) => new Response("Hello, world"));
Deno.serve({ port: 3000 }, (_req) => new Response("Hello, world"));
Deno.serve({
onListen({ port, hostname }) {
console.log(`Server started at http://${hostname}:${port}`);
// ... more info specific to your server ..
},
handler: (_req) => new Response("Hello, world"),
});
Мы намерены стабилизировать Deno.serve в следующем месяце, и это должно быть предпочтительным API для использования вместо Deno.serveHttp.
Изменения в стандартной библиотеке
Критические изменения в модуле std/encoding
Как было объявлено в предыдущем сообщении о выпуске, следующие 6 модулей кодирования были перемещены на верхний уровень.
std/encoding/csvбыл перемещен вstd/csvstd/encoding/yamlбыл перемещен вstd/yamlstd/encoding/tomlбыл перемещен вstd/tomlstd/encoding/jsonбыл перемещен вstd/jsonstd/encoding/jsoncбыл перемещен вstd/jsoncstd/encoding/front_matterбыл перемещен вstd/front_matter
В этом выпуске эти устаревшие модули полностью удалены. Если вы еще не перешли на новые пути, обновите к ним спецификаторы импорта.
Примечание. Если вы не зависите от этих удаленных путей напрямую, но ваши транзитивные зависимости неправильно зависят от этих путей с неверсионным URL-адресом модуля, возможно, вы не сможете решить проблему, обновив собственный исходный код. В этом случае используйте карту импорта следующего образца:
{
"imports": {
"https://deno.land/std/encoding/yaml.ts": "https://deno.land/[email protected]/encoding/yaml.ts"
}
}
Это вызывает переназначение неверсионных URL-адресов стандартной библиотеки (в данном случае https://deno.land/std/encoding/yaml.ts) на версионный (https://deno.land/[email protected]/encoding/yaml.ts) во всем вашем графе зависимостей и решит проблему в ваших зависимостях.
Прекращение поддержки fs.exists отменено.
exists и existsSync в модуле std/fs когда-то устарели в v0.111.0, но их устаревание было отменено в этом выпуске.
Эти API устарели из-за их подверженности ошибкам. Они легко вызывают ошибку состояния гонки, известную как TOCTOU. Однако после его устаревания была долгая дискуссия о правильном/достойном использовании о них. Баланс между их удобством и подверженностью ошибкам был пересмотрен, и их было решено восстановить.
Обновления модуля std/csv
В этом выпуске был добавлен CsvStringifyStream API. Этот API преобразует поток исходных данных в поток строк csv.
import { CsvStringifyStream } from "https://deno.land/[email protected]/csv/mod.ts";
import { readableStreamFromIterable } from "https://deno.land/[email protected]/streams/mod.ts";
const file = await Deno.open("data.csv", { create: true, write: true });
const readable = readableStreamFromIterable([
{ id: 1, name: "one" },
{ id: 2, name: "two" },
{ id: 3, name: "three" },
]);
await readable
.pipeThrough(new CsvStringifyStream({ columns: ["id", "name"] }))
.pipeThrough(new TextEncoderStream())
.pipeTo(file.writable);
После вышеупомянутого добавления CsvStream был переименован в CsvParseStream, чтобы уточнить его назначение.
Спасибо Юки Танака за вклад.
V8 11.4
Этот выпуск обновляется до последней версии V8 (11.4, ранее 11.2).
В этом обновлении доступно несколько новых интересных функций JavaScript: