Обновить
64K+

Node.JS *

Среда для запуска JavaScript-приложений

62,04
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Управляемые корутины в TypeScript: как получить контроль над асинхронностью и памятью. Разбираемся во всех аспектах

Уровень сложностиСложный
Время на прочтение14 мин
Охват и читатели679

Современный JavaScript / TypeScript сегодня, предоставляет мощный инструмент для асинхронного программирования, который знаком каждому - async/await на основе Promise. Он позволяет писать последовательный код и легко обрабатывать ошибки. Однако за простотой скрываются серьёзные ограничения, которые становятся критичными в высоко-нагруженных системах, играх, сложных пользовательских интерфейсах и приложениях, требующих предсказуемой производительности.

Представьте себе сервер, обрабатывающий тысячи запросов одновременно. Все они конкурируют за процессорное время. Как гарантировать, что запрос от клиента выполнится раньше, чем фоновая синхронизация? Как отменить долгую операцию, если клиент разорвал соединение? Как избежать пауз сборщика мусора при создании миллионов временных объектов? Нативный async/await не даёт ответов на эти вопросы - он лишь оборачивает асинхронные операции в удобный синтаксис.

В этой статье мы разберём, как кооперативные корутины (Coroutines) решают эти задачи на примере моей библиотеки ts-adaptive-coroutines, изучив каждый аспект по кирпичикам, посмотрев на инструмент, который добавляет в TypeScript адаптивные приоритеты, арены памяти, каналы, семафоры и много-поточность.

Читать далее

Новости

Назад в машинный зал: как собрать эмулятор PDP-11/70 с телетайпом, блэкджеком и без Rust

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели4.4K

Каждый программист «за сорок» рано или поздно проходит через этот кризис среднего возраста. Кто‑то покупает мотоцикл, кто‑то уходит в монастырь функционального программирования… а потом ты становишься «программистом за пятьдесят», и тут‑то вспоминается детство.

У меня оно было интересное (для меня). Запах озона, мигание лампочек на инженерном пульте советских клонов DEC — машин СМ-4 и СМ-1420, за которыми я впервые увидел живой компьютер, — и та самая первая любовь: язык C и старинный компьютер с не менее старой ОС. Любовь, которой уже сорок лет. Естественно, мне захотелось вернуть свой 1984-й.

Читать далее

Монорепозиторий с поддержкой Vite, TS, ESM и абсолютных импортов без расширений с использованием «subpath imports»

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели3.3K

Абсолютные импорты без расширений в ESM-монорепозитории.
Настраиваем Vite, TypeScript и автоимпорты в IDE (VSCode) с помощью “subpath imports”.

Разрешаем конфликты настроек без костылей.

Добавляем приоритет автоимпорта папок в качестве модулей, при наличии “index.ts”.

Настраиваем Vite и TypeScript на работу с исходниками компилируемой библиотеки в dev-режиме.

Читать далее

Сторож бюджета сработал ровно так, как я его написал. Поэтому за сутки ушло 225 евро при жёстком пороге 150

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели3.5K

Я сам написал скрипт, который следит за расходом Telegram Ads и глушит кампании при превышении дневного лимита. Двадцать пятого июня он отработал ровно так, как был написан, — и именно поэтому за сутки открутилось 224,98 € при пороге 150. Разбираю по шагам, где именно я ошибся: почему проверка «раз в час» на самом деле проверяла не то, почему остановка кампании не остановила расход, и как алерт о проблеме ушёл туда, где его никто не читал. С кодом до и после.

Читать далее

Я отдал языковой модели доступ к продовой панели администрирования. Вот что пришлось построить, чтобы она её не сожгла

Уровень сложностиСложный
Время на прочтение18 мин
Охват и читатели7.3K

Полгода назад я поддерживал TypeScript SDK для одной панели администрирования. Обычная библиотека: сгенерированный из OpenAPI клиент, авторизация, ретраи, вебхуки. И в какой‑то момент я поймал себя на том, что рутинные вопросы к панели — «у кого истекает доступ на этой неделе», «почему нода отвалилась», «сколько трафика съел вот этот аккаунт» — я решаю одинаково: открываю редактор, пишу пятнадцать строк скрипта на своём же SDK, запускаю, читаю, удаляю.

Мысль напрашивалась: SDK уже типизирован, схемы уже есть, значит модель может вызывать его сама. Так появился marzban-mcp.

Дальше выяснилось, что «обернуть SDK в MCP» — это примерно 10% работы. Остальные 90% — ответ на вопрос, который в обычной библиотеке вообще не стоит: что можно доверить модели делать с боевой инфраструктурой, а что нельзя, и как эту границу выразить в коде.

Читать далее

Аналитика без cookie: дневной HMAC вместо идентификатора посетителя

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели7.4K

Внешний счётчик ставится за пять минут, и обычно этого достаточно. Но у модели «сторонний скрипт с чужого домена» есть технический потолок, и на магазине я в него упёрся: запрос к третьему домену режут блокировщики и антитрекинг браузеров, на объёме включается сэмплирование, cookie тянет за собой баннер согласия (а все, кто его отклонил, выпадают из статистики целиком), и главное — поведение ваших покупателей лежит в чужой системе, рядом с которой нет ваших заказов.

Ниже — как устроен свой cookieless‑трекинг в двух проектах на Next.js: интернет‑магазин (Next.js 15.5, TypeScript, Prisma 6, PostgreSQL) и маркетплейс услуг (тот же Next.js, но pg без ORM). Код в статье — из работающих проектов, с теми решениями, которые оказались неочевидными, и с теми, которые пришлось переделать.

Сразу оговорка: это не «Метрика — зло». Для контентного сайта внешний счётчик закрывает вопрос целиком. Разговор начинается там, где аналитика — часть продукта.

Читать далее

Вордстат в чате с Claude, или как я автоматизировал сбор семантики

Уровень сложностиПростой
Время на прочтение3 мин
Охват и читатели6.1K

Честно скажу, идея подключить вордстат к ИИ ко мне пришла достаточно спонтанно и скорее была вынужденной на тот момент необходимостью – у меня в команде сократили SEO специалиста и этот блок полностью лёг на мои плечи. Помимо всех оптимизаций и задач связанных непосредственно с самим seo тут же был и еще один масштабный пласт, дававший бизнесу много денег – seo блог и глоссарий.

Блог был полностью ориентирован на seo и на получение небрендового трафика и перформил очень хорошо. Для меня это означало то, что теперь мне придется его развивать и поддерживать самостоятельно.

Кто собирал ключи в вордстате знает, что помимо базовых функций есть всевозможные расширения в хроме, с помощью которого ключи можно собирать вместе и потом выгружать, но это все равно требует большого количества времени. Плюс к этому для начала все равно нужно ответить на вопрос "а на какую тему мне вообще собирать ключи?".

Такая вот преамбула. Как вы понимаете, дальше я пошел искать пути для аутсорса этой задачи в клод.

Читать далее

От одного npm‑пакета к кластеру Contagious Interview: практическое расследование supply chain‑кампании

Уровень сложностиСложный
Время на прочтение6 мин
Охват и читатели7K

В прошлой статье я рассказывал о случайно попавшем ко мне образце ChainVeil - вредоносном ПО из источника, который на тот момент не был зафиксирован в публичных исследованиях.

На этот раз первым сигналом стал мой собственный supply chain‑мониторинг. Он сообщил о новом npm‑пакете plugin-react-vite. На первый взгляд это выглядело как очередной тайпсквоттинг - ничего особенно необычного.

Но я решил пойти дальше: сначала проверить метаданные пакета, затем код, затем инфраструктуру, а уже после этого попытаться понять, кто стоит за образцом и связан ли он с чем‑то уже известным.

В результате расследование ушло далеко за пределы одного package.json: от подозрительной зависимости я пришел к второму этапу размером около 30 тысяч строк, а затем - к нескольким месяцам активности, связанным пакетам, нескольким npm‑аккаунтам и уже известному кластеру.

Именно этот путь я и хочу разобрать.

Погрузиться в расследование

Вскрытие ноу‑код сметы за 500$ или как купить «АИ — ассистента» который сожрёт весь бюджет заказчика

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели6K

Привет, Хабр! Я разработчик из Минска (работаю официально, в статусе НПД). Занимаюсь автоматизацией на связке Self‑Hosted n8n + Redis. Внедряю автономных ИИ‑агентов для мессенджеров и связываю их с amoCRM.

Поделюсь, как говорится, «мясом» из своей практики. В статье я максимально постараюсь отразить и технический абсурд плавно переходящий в явное кидалово от инфомошенников.

Перед началом сразу обозначу, как говориться, на берегу: во‑первых — это не хейт и не попытка кого‑то «разоблачить». Ленты мессенджеров завалены рекламой от «ИИ‑агентств» и «продавцов успешного‑успеха», которые громко кричат про «...ваш цифровых сотрудников за пару дней...». У меня нет раскрученного профиля с красивыми публикациями, но, есть обычная практика. Данный разбор — это попытка показать (а может кому‑то и знакомо), что скрывается за красивыми нагенерированными видосами и контентом и почему, доверив реальный проект таким «спецам» обойдётся дорого. Во‑вторых — все упоминания брендов и платформ в статье — не реклама и не антиреклама. Названия систем я оставил исключительно ради сохранения контекста, да и в принципе живого отражения примера.

История статьи началась, наверное можно сказать в 2 этапа. На первом этапе, который был ещё наверное в марте этого года, ко мне обратился заказчик с интересным ТЗ: стек Instagram+ amoCRM + Google Sheets при плотном трафике до 5000 диалогов в месяц (таргет что тогда, что по сей день заходит «на ура»). Причём сёстры (заказчик — это семейный бренд ателье дизайнерских украшений) своими силами опробовали «...платформы где платишь подписку и в соответсвии с трафиком выбираешь соответствующий пакет услуг. Итог в который после первого дня триала по самым средним подсчётам вышел бы 1100$ в месяц расхода (!). Поскольку моя статья не о том какая архитектура была в итоге у них развёрнута, так что пойдём дальше.»

Читать далее

Универсальный подход к регрессионному тестированию микросервисов: интеграция Postman, Newman и Python в Jenkins

Уровень сложностиСредний
Время на прочтение19 мин
Охват и читатели6.6K

Привет всем заглянувшим!

В этой статье я поделюсь опытом автоматизации API‑тестирования связкой Postman + Newman, но с небольшим «секретным ингредиентом». Мы не просто будем запускать коллекции в Jenkins напрямую, а используем универсальный Python‑скрипт, который превращает стандартный прогон в мощный инструмент мониторинга.

В чем «фишка» этого подхода?

Обычно Newman выдает довольно сухие отчеты. Мой скрипт выступает в роли умной прослойки: он обрабатывает результаты тестов на статус‑коды, собирает данные и упаковывает их в наглядный Allure‑отчет. Более того, здесь добавлена функция почтовых уведомлений, чтобы контролировать состояние системы, не заходя в Jenkins.

Читать далее

Когда setState недостаточно: как я написал транзакционный стейт-менеджер на TypeScript

Уровень сложностиПростой
Время на прочтение18 мин
Охват и читатели11K

Стейт-менеджеров в JavaScript уже столько, что идея написать ещё один выглядит немного сомнительно. Есть Redux Toolkit, Zustand, MobX, Jotai, XState и десятки менее известных библиотек. Почти для любого способа хранить состояние уже существует готовое решение. Но все же в качестве эксперимента, решил реализовать свою идею.

Читать далее

Как выжать максимум из Генотека: вайбкодим кастомный ДНК-анализатор

Уровень сложностиСредний
Время на прочтение14 мин
Охват и читатели13K

Дисклеймер: не читайте эту статью, если вы фанат традиционных ценностей и от заголовка уже хотите написать в комментах, что мне стоит изучить базу и отучиться в меде. Читайте эту статью только если вы прогрессивный, веселый и любите необычные проекты ♥ Статья носит исключительно научпоп-инженерно-юмористический характер. Не используйте самодельные скрипты для постановки диагнозов (хотя сходить на ПЦР-тест или к врачу после них никто не запрещает)!

Скажите, вы же тоже ожидали большего от интерпретаций коммерческих ДНК-тестов типа Genotek, 23andMe, Atlas? Ну вот и я не была в восторге от того, что я на 4.2% скандинавка, мне вреден арахис, и скорее всего я люблю кинзу.

В этой статье я расскажу, как я на диком азарте построила свой пайплайн анализа генома. Мы пройдем от пересборки координат и импутации 40 миллионов маркеров на суперкомпьютере TOPMed до укрощения памяти Node.js, чтобы скрипт не умер от 43 ГБ данных, а я покажу, как все устроено под капотом. Осторожно, много блоков кода и дисклеймеров!

Читать далее

Часть 1. Как я делаю backend для браузерной игры три в ряд: server-driven контент, транзакции и идемпотентность

Уровень сложностиПростой
Время на прочтение18 мин
Охват и читатели9.2K

Часть 1. Как я делаю backend для браузерной игры три в ряд: server-driven персонажи и способности, общий контракт клиента и сервера, версионирование контента, транзакции, идемпотентность и админка.

Читать далее

Ближайшие события

Смена типа в объекте тоже не бесплатна

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели11K

В прошлой статье про объекты и скорость доступа к известному полю я рассказал про hidden classes, inline cache и форму объекта. Практический совет там был простой: если поле опциональное, создай его сразу и положи null. Тогда экземпляры сохранят одинаковую форму.

Совет рабочий, но неполный. Форма объекта у V8 может остаться прежней, а вот внутренний контракт хранения поля может измениться. Если горячая функция успела прогреться под старый контракт, V8 пометит её на деоптимизацию.

Напомню, что для обычного CRUD это не повод выбрасывать null из модели и бежать переписывать все. Но вот для систем с путями по которым проходят десятки тысяч однотипных объектов в секунду, полезно знать вторую половину механики.

Какой такой контракт?

Пишем нативные аддоны для Node.js на Rust: что умеет NAPI-RS и где он правда нужен

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели7.8K

Привет, Хабр! Меня зовут Сергей Маркизов и я бэкенд-разработчик в Далее

Периодически я сталкиваюсь с задачами, где привычного JavaScript недостаточно: нужно быстрее считать, вручную управлять памятью или подключить существующую нативную библиотеку.

Node.js отлично чувствует себя в I/O-bound задачах (API, микросервисы, работа с базами данных и очередями), но как только в приложение попадает тяжелая CPU-bound логика (хеширование больших файлов, обработка изображений, видео, криптография) event loop может стать узким местом.

Один из способов решить эту проблему — вынести тяжелую часть в нативный аддон. В статье разберемся, как делать такие аддоны на Rust с помощью NAPI-RS: посмотрим на базовые типы, классы, асинхронные задачи, работу с JavaScript-объектами и управление ресурсами через Reference и External. 

Материал будет полезен Node.js-разработчикам, backend-инженерам и всем, кто хочет понять, когда Rust можно встроить в JavaScript-проект без боли для пользователей библиотеки.

Читать далее

Encode, don't stringify — как JSON.stringify вам врёт

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели6.7K

Помните, как лет 5–7 назад все сидели на Yup или Ajv и всех всё устраивало? Признаю, половину интернета устраивает до сих пор 🫡

Потом появилось «Parse, don’t validate», стало настольной книгой для кучи разработчиков и в итоге выстрелило и у нас, в JavaScript и TypeScript. Тысячи библиотек со схемами — лучшее тому подтверждение 😁

Но это уже решённая проблема, и статью вы открыли не ради неё. А вот что не решено:

Читать далее

Приложение течёт, а утечки нет: как оптимизатор картинок Next.js съел 4-гигабайтный VPS

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели9.2K

История про то, как я три дня искал утечку памяти в Node-приложении, не нашёл — и был прав, что не нашёл. А ещё про то, что у каждого починенного пункта тут оказывался свой счёт: фикс памяти через месяц вернулся жалобой на скорость, а разбор скорости вскрыл третью проблему, о которой я не думал вовсе.

Читать далее

Бесшовный переезд с Perl на Nuxt: история одного 20-летнего монолита

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели7.7K

Привет, Хабр! Меня зовут Эрнест Гилязов, я тимлид группы разработки интерфейсов Рунити. В этой статье расскажу, как мы переносим на новый стек проект Рег.ру, кодовой базе которого исполняется 20 лет, и почему в итоге Nuxt-приложение само раздает шапку и футер в легаси-монолит через обычный JSON-эндпоинт.

Читать далее

Реалтайм на WebSocket со сквозной типизацией: TypeScript, Bun, React, Point0

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели7.9K

Бывает так: есть фулстек проект, и в нём всё хорошо. Откуда-то есть сквозные типы (tRPC, генерация из OpenAPI), есть авторизация, есть основной функционал. А потом вы решаете добавить реалтайм: уведомление о новом посте в ленте, чат между пользователями, интерактивную доску. И появляется целый новый слой абстракций, в котором надо заново изобрести всё, что в проекте уже есть, только на новый лад. И дальше поддерживать две разные системы.

В своём фреймворке Point0 я добавил четыре новых реалтайм-поинта (структурные единицы наравне со страницами, лэйаутами, квери, мутациями): канал, спейс, клиентский хэндлер, серверный хэндлер. На них собирается практически любая реалтайм-функциональность, кода получается мало, и читается он интуитивно. Эти поинты несут те же свойства, что и все остальные:

код сервера и клиента живут в одном файле, компилятор вырезает клиентский код из серверной сборки, а серверный из клиентской

типизация сквозная и выводится из дженериков самого фреймворка, без генерации типов

Под катом покажу на примерах, как это работает, и объясню суть парадигмы, чтобы вы могли собрать любое реалтайм-приложение.

Читать далее

Чему мы научились, написав на Rust среду выполнения для TypeScript

Время на прочтение17 мин
Охват и читатели9.6K

Encore зародился как фреймворк на Go, и на Go там были написаны среда выполнения, интерфейс командной строки (CLI), парсер и компилятор. Когда мы решили поддерживать TypeScript, логичнее всего было бы написать на TypeScript и среду выполнения тоже, либо достроить к среде выполнения Go какой‑нибудь мостик. Но в итоге пришли к тому, что написали новую среду выполнения с нуля на Rust.

Читать далее
1
23 ...