Комментарии (36)
- Обсуждение вокруг пакета
golang.org/x/tools/goplsи его влияния на разработку, включая предложение использовать Go вместо JavaScript, вызвало споры о целесообразности и практичности такого подхода. - Участники обсуждали, что вместо того, чтобы писать на Go, лучше позволить импортировать
.goфайлы, что более идиоматично для JS бандлеров. - Поднялся вопрос о том, что клиентский код не должен диктовать бизнес-логику, и что стоит быть осторожным с подобными техниками.
- Была отмечена важность такого подхода для обучения и вдохновения новичков в области WASM и Go.
- Также было отмечено, что это может быть полезно для оффлайн-функциональности и как фоллбек, если API недоступен.
- В конце концов, обсуждение свелось к тому, что это может быть полезно для обучения и вдохновения новичков в области WASM и Go.
Doing Rails Wrong 🔥 Горячее 💬 Длинная дискуссия
Диалог высмеивает современную тенденцию усложнять разработку на Rails, добавляя множество инструментов вроде Vite, React, TypeScript, Babel, PostCSS, Tailwind, ESLint, Prettier, Husky, Docker и Redis. Всё это оправдывается стремлением к «современности» и скорости, но приводит к громоздкой настройке.
В противовес этому демонстрируется простота «ванильного» Rails: один командой запускается мгновенно работающее приложение с быстрой загрузкой и формами. Ключевая идея — Rails уже содержит всё необходимое, а избыточные инструменты лишь создают сложность без реальной выгоды. Фраза «Просто используй Rails, блин!» резюмирует мысль: не усложняй там, где это не нужно.
Комментарии (205)
- Участники обсуждают растущую сложность современных веб-фреймворков, отмечая, что Rails предлагает более простой и "батарейками включенный" подход по сравнению с перегруженными инструментами JS-экосистемы.
- Многие выражают ностальгию по классическому Rails, критикуя такие новые решения, как Hotwire и Stimulus, за сложность освоения и недостаток документации, в то время как другие защищают их как "путь Rails".
- Поднимается тема чрезмерного усложнения проектов (over-engineering), особенно для небольших команд, где монолитные фреймворки (Rails, Django) часто продуктивнее разделения на фронтенд и бэкенд.
- JS-экосистема подвергается критике за постоянное "изобретение велосипедов", сложность инструментов и модульность, которая приводит к усталости от инструментария, хотя некоторые защищают её гибкость.
- Отмечается, что выбор инструментов должен определяться конкретными задачами проекта, а не модными тенденциями, и что проверенные временем технологии часто эффективнее для небольших и средних приложений.
Next.js is infuriating 🔥 Горячее 💬 Длинная дискуссия
Next.js выводит из себя
Наконец-то написал пост: злость лучший мотиватор.
В $COMPANY упал сервис на Next.js, а логов в проде нет. Задача — добавить логирование.
Middleware
Дока обещает: «Middleware выполняется до рендера, удобно для логов».
Пробуем pino + AsyncLocalStorage:
// middleware.ts
export async function middleware(req: NextRequest) {
LoggerStorage.enterWith(requestLogger());
logger()?.debug({ url: req.url }, "start");
return NextResponse.next();
}
Запускаем — логи летят в браузер. Почему? Runtime по умолчанию edge. Меняем на nodejs — в новом проекте работает, в боевом нет.
Страницы и layouts
Пишем в компоненте:
logger()?.info("from page");
Тишина. logger() возвращает null: рендер и middleware живут в разных async-контекстах.
Решение
Передаём requestId через заголовки:
// middleware.ts
const id = crypto.randomUUID();
loggerInstance.child({ requestId: id }).debug("start");
return NextResponse.next({ headers: { "x-request-id": id } });
// page.tsx
const id = headers().get("x-request-id");
loggerInstance.child({ requestId: id }).info("from page");
Итог: чтобы просто логировать, нужно городить костыли через заголовки.
Комментарии (445)
- Пользователи жалуются на игнорирование сотен старых issue, перегруженность абстракциями и постоянные «канареечные» решения, которые не доходят до продакшена.
- Сообщество считает Next.js «самой худшей» технологией: сложно понять, где выполняется код, нельзя цепочкой middleware, а апи-шлюзы выглядят «как будто их писали выпускники буткемпа».
- Разработчики предлагают уходить на Remix, React Router v7, Nuxt, SolidStart, Deno Fresh или даже «чистый HTML/CSS» ради простоты и контроля.
- Представитель Vercel признаёт DX-проблемы и обещает улучшения, но многие уже мигрируют на Vite или Django/Rails/Phoenix.
Comptime.ts: compile-time expressions for TypeScript
Простой компилятор TypeScript для вычисления выражений с пометкой comptime на этапе сборки. Полезно для переноса вычислений из рантайма в компиляцию. Вдохновлено Bun macros и Zig comptime.
Внимание: вы сами отвечаете за безопасность выражений, вычисляемых на этапе компиляции. Изоляции нет. Импорты comptime допускаются только в файлах проекта (не в node_modules), но можно импортировать из node_modules как comptime.
Содержание
- Что такое comptime.ts?
- Примеры: 1) простая сумма; 2) CSS без рантайма; 3) константы во время сборки
- Установка
- Использование: Vite, Bun, CLI, API
- Принудительная оценка и промисы, отказ от «вирусности»
- Запуск кода после comptime, как работает, ограничения, практики, отладка, поддержка, лицензия
Что это comptime.ts вычисляет выражения при компиляции, сокращая работу в рантайме.
Примеры
-
Простая сумма import { sum } from "./sum.ts" with { type: "comptime" }; console.log(sum(1, 2)); // => console.log(3);
-
Emotion CSS без рантайма import { css } from "@emotion/css" with { type: "comptime" }; const style = css
color: red; font-size: 16px;; div({ class: style }); // => const style = "css-x2wxma"; div({ class: style });
Примечание: импорт @emotion/css удаляется. Стили нужно вывести отдельно (после comptime или плагином бандлера).
- Константы на этапе сборки import { ms } from "ms" with { type: "comptime" }; const HOUR = ms("1 hour"); // => const HOUR = 3600000;
Поддерживаются многие выражения (включая индексацию и импортированные константы), результат должен быть сериализуем в JSON. Импорты с type: "comptime" удаляются; лишнее убирает ваш бандлер.
Установка bun add comptime.ts pnpm add comptime.ts npm install comptime.ts
Использование
- Vite: import { comptime } from "comptime.ts/vite"; export default defineConfig({ plugins: [comptime()] });
Только в прод-сборке, если поведение совпадает с рантаймом: export default defineConfig({ build: { rollupOptions: { plugins: [comptime()] } } });
- Bun: import { comptime } from "comptime.ts/bun"; await Bun.build({ entrypoints: ["./index.ts"], ou ... })
Комментарии (30)
- Обсуждение крутится вокруг идеи “comptime”/макросов в JS: часть хочет Rust‑подобные макросы и proc‑макросы (вплоть до JSX как jsx! или вообще писать фронт на Rust/wasm), другая сторона категорически против макросов в TS/JS.
- Есть путаница в терминах: “макросы” vs “comptime”; участники критикуют переиспользование терминов и вспоминают неудачный опыт sweet.js.
- Практические вопросы: можно ли делать агрессивный dead‑code elimination через if (comptime …) как в C препроцессоре? Ответ: само comptime подставит true/false, но для выкидывания веток нужен отдельный шаг минификатора/бандлера (Vite/Bun поддержат).
- Дискуссия об импорте with { type: 'comptime' }: одни считают это неправильным использованием атрибута type (ожидается соответствие MIME), другие указывают, что спецификация оставляет семантику type открытой.
- Обсуждают границы возможности: поддержка типов/генериков на уровне comptime (как в Zig) пока ограничена; возврат именованных функций и сложные случаи с замыканиями не поддерживаются из‑за требований к гарантиям и сохранению функций между процессами.
- Альтернативы: настроить сборку для JSX без макросов; использовать библиотеки вроде lite-jsx; для Rust‑фронта рекомендуют Dioxus/Leptos; спорят о реальной применимости wasm и памяти/управления ей в вебе.
- Применимость: идея удобна для предсборки (например, markdown) и константной подстановки, но не заменяет полноценных препроцессоров/макросистем уровня Rust/Zig.