Fresh построен поверх Deno и изначально использует ES-модули, URL-импорты и строгую модель безопасности. При этом одной из ключевых особенностей фреймворка является возможность работать с экосистемой npm, несмотря на фундаментальные различия между Deno и Node.js. Совместимость достигается не за счёт эмуляции среды Node.js, а через встроенный механизм поддержки npm-пакетов в Deno, который Fresh использует напрямую.
В основе лежит несколько принципов:
node_modules — управление
зависимостями происходит централизованно.Fresh не имеет собственного менеджера пакетов. Используется
стандартный механизм Deno с префиксом npm:. Импорт
npm-пакета выглядит как обычный ES-импорт:
import lodash from "npm:lodash";
При первом запуске Deno:
Версия может быть зафиксирована напрямую в импорте:
import express from "npm:express@4.18.2";
Для Fresh это полностью прозрачный процесс — код фреймворка не различает npm-пакеты и модули, загруженные по URL.
deno.jsonДля крупных проектов прямые импорты с версиями становятся неудобными.
Fresh поддерживает централизованное управление зависимостями через
deno.json:
{
"imports": {
"lodash": "npm:lodash@4.17.21",
"zod": "npm:zod@3.22.4"
}
}
После этого используется короткий синтаксис:
import { z } from "zod";
Преимущества такого подхода:
Deno самостоятельно формирует внутренний lock-механизм, обеспечивая воспроизводимость сборки.
Большая часть npm-экосистемы исторически использует CommonJS. Deno выполняет автоматическую трансформацию:
require → importmodule.exports → default exportПример:
import chalk from "npm:chalk";
Даже если chalk внутри использует CommonJS, в коде Fresh
он выглядит как полноценный ES-модуль.
Ограничения:
require может не работать,__dirname, требуют адаптации,process возможно только при разрешении
соответствующих API.Многие npm-пакеты используют стандартные модули Node.js
(fs, path, crypto). Deno
предоставляет совместимый слой:
import fs from "node:fs";
import path from "node:path";
Fresh позволяет использовать такие импорты без дополнительной настройки. Однако действуют правила безопасности Deno:
--allow-read /
--allow-write,--allow-net,--allow-env.Это означает, что npm-пакет может быть технически совместим, но функционально ограничен без соответствующих разрешений.
Fresh чётко разделяет серверный и клиентский код. npm-пакеты могут использоваться в обоих контекстах, но с разными требованиями.
Серверная часть:
Клиентская часть (islands):
Попытка использовать npm-пакет с fs внутри island
приведёт к ошибке сборки или выполнения.
Fresh использует TypeScript без этапа компиляции. npm-пакеты с типами подключаются автоматически:
.d.ts,@types/*,Пример:
import axios from "npm:axios";
Типы axios будут доступны без дополнительной настройки.
Если пакет не содержит типизации, возможны варианты:
// @ts-ignore,Deno не поддерживает автоматическую установку @types,
поэтому предпочтение отдаётся современным пакетам с встроенными
типами.
Не все npm-пакеты одинаково совместимы с Fresh. Наиболее проблемные категории:
process.argv, stdin/stdout.node-gyp,
бинарные зависимости.Для таких случаев используются альтернативы:
Fresh не бандлит серверный код, но клиентские islands проходят оптимизацию. npm-пакеты, используемые в islands:
Лучше всего работают пакеты:
Пример предпочтительного импорта:
import debounce from "npm:lodash.debounce";
Вместо:
import _ from "npm:lodash";
При интеграции npm-зависимостей в проект на Fresh применяются практические критерии:
Часто предпочтение отдаётся пакетам, ориентированным на web-стандарты, а не на Node.js как платформу.
Fresh допускает одновременное использование npm-пакетов и модулей по URL:
import { serve } from "https://deno.land/std/http/server.ts";
import z from "zod";
Это позволяет:
Такой гибридный подход является характерной особенностью экосистемы Fresh и Deno.
При деплое приложения на Fresh:
npm install,На платформах, поддерживающих Deno (включая Deno Deploy), npm-совместимость работает без дополнительной конфигурации, при условии отсутствия native-модулей.
Это делает Fresh особенно подходящим для serverless-архитектур и
edge-окружений, где классический Node.js-подход с
node_modules затруднителен.