Обновить
47.01

TypeScript *

Cтрого типизированная надстройка для JavaScript

Сначала показывать
Порог рейтинга

Философия IT-собеседований: взгляд разработчика и DevOps-инженера

Привет, Хабр! Мой пост носит дискуссионный характер. В веб-разработке, администрировании и DevOps я уже 17 лет. Долгое время работал «на себя», оказывая помощь клиентам, с которыми выстроены надёжные взаимоотношения, но текущие реалии рынка подтолкнули к поиску работы по ТК, об этом я и хочу поговорить.

Обо мне: 40 лет, из которых 17 лет в коммерческой разработке. Прошел долгий путь как в fullstack-разработке (web), так и в создании embedded-решений (каршеринг), администрировании и DevOps.

Раньше мой процесс найма редко выходил за рамки одного интервью. Сейчас же я регулярно сталкиваюсь с многоступенчатыми отказами, иногда даже на этапе HR-скрининга. Этот контраст заставил меня задуматься: что делает найм эффективным, а что превращает его в фарс? Решил систематизировать свои наблюдения и поделиться тем, что в современных собеседованиях кажется здравым, а что — откровенно лишним.

Описываю позитивные практики, с которыми сталкивался, практики за которые я уважаю потенциальных работодателей и команды. Это парадигма, в которой я вёл деятельность с начала карьеры.

  1. Диалог на равных.
    Мое лучшее интервью: техлид не мучил теорией, а предложил обсудить реальную дилемму, которую он решает в данный момент (внедрение NoSQL-хранилища ради одного специфичного сервиса, т.е. доп. точка отказа vs производительность). Без таймера и стресса мы искали решение. Итог — оффер и годы отличной работы.

  2. Проверка логики, а не памяти.
    Люблю кейсы в духе: «Вот дано А, почему происходит Б?». Из банального: может ли Вася из другого города достучаться до вашего локального IP? Это показывает понимание базы лучше любого теста.

  3. Ценность универсальных знаний.
    Универсальные знания долгое время позволяли быстро находить решение практически любой проблемы от хардверной, до нарушения самых элементарных паттернов проектирования в коде и эффективно их устранять. Мне нравятся задачи, где проблема может быть скрыта на любом уровне и нравятся клиенты, понимающие, как я могу снять их головную боль обеспечив работоспособность ПО в любой среде и условиях.

А теперь я хочу описать то, от чего меня бомбит. Это факторы которые будут отпугивать меня вплоть до момента, когда будет нечего кушать и я буду вынужден прогнуться под выгодное предложение.

  1. Лайвкодинг.
    В 40 лет написание кода для меня — процесс интимный... хотя я практикую парное программирование в реальной команде и это мне нравится, но в предвкушении собеседований иногда хочется "психануть" и на предложение выбрать время для лайвокдинга сказать — "предлагаю парное программирование с одним из ваших специалистов, ведь для меня тоже важно, с кем я буду вести разработку". (Не пробовал так отвечать, но попробую, как только выдастся случай).

  2. Вакансии-обманки.
    Зачем заманивать стеком DevOps (Linux, Nginx, Ansible, Terraform, Puppet, Docker, Kubernetes, MySQL, PostgreSQL, Elasticsearch, Logstash, Kibana, Zabbix), если по факту сообщаете, что ничего этого не будет, а ищите классического сисадмина 9-18? — Давайте адкеватный запрос, а не тратьте время.

  3. Терминологическая каша. Сложно отвечать экспертно, когда интервьюер путает CI и OCI или Redis и Rabbit. Если нет погружения в контекст, конструктивного диалога не выйдет. Готовиться к собеседованию должен не только соискатель, но и тот, кто нанимает.

  4. Отсутствие пунктуальности.
    Для меня было шоком, что фаундер может просто не явиться на собседование, или рекретер забывает о диалоге и назначенной встрече. У вас там всё нормально?) Хотя рекрутер мало чем отличается от агента недвижимости, но фаундер забывающий про собеседование для меня персонаж странный.

  5. Узкая специализация.
    Раньше, как мне кажется, ценилась универсальность, способность разработчика понимать инфраструктуру, а инженера/админа — код. Сегодня индустрия уходит в жесткую сегментацию, видимо, для более точного просчёта рисков. А я считаю, что именно универсальность — это страховка проекта от того, что решение будет принято в вакууме одного стека, без учета общей картины.

Теги:
+7
Комментарии1

Коллеги, всем привет!

За годы менторства по Angular (в том числе в HTML Academy) я заметил одну системную проблему: студенты и даже миддлы часто знают синтаксис RxJS, но не понимают реактивного мышления. В итоге мы получаем subscribe внутри subscribe и императивную лапшу.

Я искал интерактивные курсы, но большинство бесплатных ресурсов ограничиваются основами.

Курс бесплатный. Делал для себя и студентов, но теперь делюсь со всеми.

Буду рад фидбеку и баг-репортам (проект активно допиливаю).

Ссылка на курс: https://rxjs-course-avy.web.app/

Теги:
+8
Комментарии1

Как мы избавились от рутины в сетевом коде с помощью собственного фреймворка Chord 🪄

Расскажем на крупнейшей конференции для разработчиков разного профиля — Holly JS 🤟

Спикером конференции станет Дмитрий Дин, fullstack-лид Далее. В докладе «Chord’овская декларативность: побеждаем бойлерплейт сетевого взаимодействия» он поделится опытом внедрения собственного инструмента Chord (на базе JSON-RPC), который уже больше года работает в продакшене и избавляет команды от рутины при взаимодействии между клиентом и сервером. 

Доклад будет особенно полезен frontend- и fullstack-разработчикам (уровня Middle и выше), которые работают с TypeScript и современными фреймворками вроде SvelteKit, Next.js или Nuxt. 

Приходите послушать доклад Димы 21 ноября, с 15.30, в секции Фреймворки. 

🔗 Подробнее о докладе и спикере — на сайте Holy JS.

Теги:
Рейтинг0
Комментарии0

Представлен открытый проект релейного компьютера 1961 года Minivac 601, работающий в браузере (код на GitHub). До появления микрочипов компьютеры строились на основе механических реле. Это рабочая модель Minivac 601, образовательного компьютера, разработанного Клодом Шенноном.

Теги:
Всего голосов 5: ↑4 и ↓1+4
Комментарии1

Привет, хабровчане! 😊

Недавно я копался в мире ИИ-инструментов для разработки — тех, что помогают писать код быстрее и умнее. Знаете, когда сидишь за проектом и думаешь: "А не взять ли помощника, который подхватит идеи на лету?" Решил поделиться обзором нескольких интересных вариантов на рынке. Это не глубокий разбор с бенчмарками (для этого нужны отдельные тесты), а просто описание, чтобы понять, что можно выбрать под свои нужды. Я опираюсь на личный опыт и отзывы из сообществ — вдруг кому-то пригодится для экспериментов.

Давайте по порядку:

  1. Cursor — это как эволюция VS Code с встроенным ИИ. Он автокомплитит код, генерирует фрагменты по описанию, понимает контекст проекта и даже помогает с отладкой. Подходит для тех, кто любит привычный интерфейс, но хочет ускорить рутину. Работает на Windows, macOS и Linux, есть бесплатная версия, но премиум открывает больше моделей ИИ. Идеально для соло-разработчиков или команд, где нужно быстро итератировать.

  2. Harvi Code — российский продукт, первый в России аналог Cursor, построенный на мощной модели Sonnet 4.5 (от Anthropic, которая славится точностью и скоростью). Это расширение для VS Code и Cursor с удобным интерфейсом, как в знакомых IDE, плюс фокус на хороших ценах (не дерут втридорога за подписку). Подходит для генерации кода, отладки и работы с проектами. Если вы в РФ и ищете локальный вариант без заморочек с платежами — стоит попробовать.

  3. Lovable — здесь акцент на создание веб-приложений без глубокого кодинга. Чат с ИИ: описываешь идею на естественном языке, и он генерирует full-stack app — от фронта до бэка. Удобно для прототипов или MVP, особенно если вы не хотите копаться в деталях. Поддерживает интеграции с базами данных и API. Минус — иногда нужно дорабатывать вручную, но для стартапов или хобби-проектов это спасение.

  4. Bolt (bolt.new) — браузерный инструмент для быстрого создания сайтов, приложений и прототипов. Вводишь промпт — и вуаля, он строит всё от начала до конца, включая деплой. Работает с веб, iOS и Android. Круто для тех, кто хочет экспериментировать без установки софта. Есть интеграции с Expo для мобильных apps. Подходит новичкам или когда нужно быстро проверить концепцию.

  5. Roo Code — это расширение для VS Code и Cursor, как целая команда ИИ-агентов прямо в вашем редакторе. Он анализирует весь проект, предлагает мульти-шаговые решения, ускоряет редактирование в 10 раз. Поддерживает разные модели ИИ (Anthropic, OpenAI), есть инструменты для автоматизации задач. Хорош для сложных проектов, где нужен глубокий контекст — не просто автокомплит, а умный помощник.

  6. Kilo Code — открытый ИИ-агент в виде расширения для VS Code, JetBrains и Cursor. Генерирует код, автоматизирует задачи, предлагает рефакторинг. Есть система инструментов для взаимодействия с окружением (безопасно, с контролем). Бесплатный, с опцией кастомизации. Идеален для тех, кто предпочитает open-source и хочет интегрировать в свой workflow без лишних зависимостей.

В общем, выбор зависит от вашего стиля: если любите браузер — Bolt или Lovable; если вглубь кода — Cursor, Harvi, Roo или Kilo. Я пробовал пару из них на пет-проектах, и реально сэкономил время. Что вы думаете? Пользовались кем-то из списка? Делитесь в комментах, может, вместе разберёмся, какой подойдёт под разные языки или фреймворки. Буду рад обсуждению! 🚀

Ссылки для удобства:

Теги:
Всего голосов 14: ↑10 и ↓4+6
Комментарии1

Жёсткая структура React-компонентов

При работе над React-приложениями я часто сталкиваюсь с тем, что мои коллеги смешивают в одном файле и JSX, и CSS-in-JS стили, и логику, и типы компонента. Работать с таким месивом очень сложно. Даже если настаивать на выделении логики, стилей и типов в отдельные файлы, это то делается, то нет. Для введения жёсткой структуры компонентов мною была написана простейшая библиотека react-component-structure.

https://github.com/sergeyshpadyrev/react-component-structure

Работает она простейшим образом. Любой компонент необходимо разделить на три хука и файл с типами:

-| Component
    -| index.ts
    -| logic.ts
    -| render.tsx
    -| style.ts
    -| types.ts

В файле logic.ts мы пишем хук useLogic - контроллер компонента, включающий в себя всю его бизнес-логику - все хуки useCallback, useEffect, useMemo и подобные. В этом хуке у нас есть доступ к props компонента.

import { useCallback, useState } from 'react';
import type { Props } from './types';

const useLogic = (props: Props) => {
    const [count, setCount] = useState(props.defaultCount);

    const onClickMinus = useCallback(() => setCount((c) => c - 1), []);
    const onClickPlus = useCallback(() => setCount((c) => c + 1), []);

    return {
        count,
        onClickMinus,
        onClickPlus,
    };
};

export default useLogic;

В файле styles.ts мы помещаем хук useStyle со стилями нашего компонента. Тут мы можем использовать inline-стили, CSS-in-JS или Tailwind. В этом хуке у нас есть доступ к props нашего компонента и к его контроллеру.

import type { Props } from './types';
import useLogic from './logic';
import { useMemo } from 'react';

const useStyle = (props: Props, logic: ReturnType<typeof useLogic>) =>
    useMemo(
        () => ({
            counter: {
                fontSize: logic.count + 10,
            },
            title: {
                color: props.color,
            },
        }),
        [logic.count, props.color],
    );

export default useStyle;

В файле render.tsx мы помещаем хук useRender с JSX, то бишь отображение компонента. В этом хуке у нас есть доступ и к props компонента, и к его контроллеру logic, и к стилям.

import type { Props } from './types';
import type useLogic from './logic';
import type useStyle from './style';

const useRender = (props: Props, logic: ReturnType<typeof useLogic>, style: ReturnType<typeof useStyle>) => {
    return (
        <div>
            <div style={style.title}>Hello {props.greeting}!</div>
            <div style={style.counter}>Count: {logic.count}</div>
            <div onClick={logic.onClickMinus}>Decrease</div>
            <div onClick={logic.onClickPlus}>Increase</div>
        </div>
    );
};

export default useRender;

В index.ts файле мы соединяем все три хука с помощью функции createComponent:

import { createComponent } from 'react-component-structure';

import useLogic from './logic';
import useRender from './render';
import useStyle from './style';

const Component = createComponent({ useLogic, useRender, useStyle });

export default Component;

И в файле types.ts мы объявляем тип для props компонента:

export interface Props {
    color: string;
    defaultCount: number;
    greeting: string;
}

Если у компонента нет props, то можно объявить их так:

export type Props = unknown

При использовании каждый компонент нашего приложения имеет чёткую структуру, состоящую из файлов контроллера, отображения, стилей и типов. Это разделение подобно разделению на HTML (отображение), CSS (стили) и JavaScript (контроллер) в ванильных JS-приложениях.

Если подход и библиотека вам понравились, поставьте репозиторию звезду на гитхабе. Надеюсь этот подход будет вам полезен.

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии12

TypeScript и C++ в одном бинаре. Первый open source-проект от МойОфис

Команда МойОфис выложила в open source собственную разработку — компилятор tsnative. Это кроссплатформенный инструмент, который объединяет удобство TypeScript с производительностью C++ в одном приложении. Исходники — на GitHub под лицензией Apache 2.0.

Компилятор tsnative — это первая и ключевая часть более масштабного проекта под названием AntiQ, в котором мы переосмысляем подход к кроссплатформенной разработке без тяжёлых фреймворков.

AntiQ разделен на два самостоятельных компонента. Сейчас в open source опубликован только tsnative — главный модуль, в котором сосредоточена основная логика и заложены архитектурные принципы всей платформы.

Зачем это нужно?

tsnative — это кроссплатформенный компилятор, преобразующий TypeScript в нативный машинный код. Он обеспечивает бесшовную интеграцию с C++ без glue-кода или JavaScript-движков, объединяя удобство высокоуровневой разработки с производительностью системного кода. В результате вы получаете один бинарник, собранный из двух языков.

Как это работает:

  • C++-функции помечаются TS_EXPORT;

  • генерируются .d.ts-декларации для TS;

  • TypeScript- и C++-код собираются через LLVM;

  • на выходе — один исполняемый файл, без обёрток.

// math.cpp
#include "TS.h"
TS_EXPORT int add(int a, int b) {
return a + b;
}
// index.ts
console.log(add(2, 3)); // -> 5
// index.ts
console.log(add(2, 3)); // -> 5

Проект может быть интересен тем, кто:

  • делает нативные приложения, но хочет писать часть логики на TS;

  • ищет замену закрытым коммерческим компиляторам;

  • любит ковыряться в сборке, кросс-компиляции и низкоуровневом коде.

Открытый код — не просто «выложили и забыли». Мы хотим, чтобы проектом пользовались, коммитили, обсуждали. Поэтому будем рады pull request’ам, issue и звёздочкам. Всё как обычно :)

Исходники на GitHub

Если у вас есть вопросы или комментарии, вы можете задать их в чате проекта: https://t.me/antiqmyoffice

Теги:
Всего голосов 33: ↑33 и ↓0+36
Комментарии12

Под пост в телеграм про наш ответ аналог Grafana пришли руководители "Лаборатории Числитель" и конкретно "Пульта", в чью систему входит платформа мониторинга и анализа "Графиня".

Дмитрий Унтила и Владимир Утратенко любезно ответили на ряд вопросов по платформе, и я хотел бы подвести краткое резюме:

  • Запрос на аналог Grafana появился в момент продажи "Пульта", так как "не всем можно брать забугорный опесорс себе в контур. Потому решили делать. А название Графиня просто ради лулзов."

  • Графиня писалась с полного нуля. Хотя предложение взять за основу Grafana было, но команда смогла обосновать геморрой, который на неё упадёт, если взяться за доработку, и объяснила руководству, почему лучше сделать с нуля.

  • Время разработки: 3 месяца - MVP, 6 месяцев - 1 релиз.

  • Технологический стек: фронтенд: TypeScript + React 18, бэкенд: TypeScript + Node.js, база данных: MongoDB, плагины: Java.

  • На мое предложение сделать проект опенсорс Дмитрий Унтила пообещал подумать. Но, понятное дело, если это часть коммерческого продукта, прям сильно думать в лаборатории не будут))

  • Демо-стенда в интернете пока нет, можно только записаться на показ системы через форму обратной связи.

Благодарю парней за такой актив и обратную связь, рад, что у людей есть на это время!

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии3

Ко мне в телеграм канал заглянул один из разработчиков Графини (убийцы Grafana), с пояснением, зачем они её родили, и что писали полностью с нуля.

Я верю.

Теги:
Всего голосов 12: ↑4 и ↓8-4
Комментарии2

Сила RxJS. scan + mergeScan = 'Загрузить еще'

Кнопка 'Загрузить еще' (либо автоматическая подгрузка данных при скролле) довольно часто встречается в проектах и обычно решение связано с большим количеством подписок и переменных.

Как всегда, для оптимизации чего либо нам на помощь приходит великий и могучий RxJS, а в данной ситуации конкретно операторы scan & mergeScan.

Код:

  readonly loadTrigger$ = new Subject<void>();
  private readonly batchSize = 5;

  private readonly posts$ = this.loadTrigger$.pipe(
    startWith(void 0),
    scan((offset) => offset + this.batchSize, -this.batchSize),
    mergeScan(
      (accPosts: Post[], offset: number) =>
        getPosts(offset, this.batchSize).pipe(
          map((newPosts) => [...accPosts, ...newPosts]),
        ),
      [] as Post[],
    ),
  );
  1. scan – калькулятор + хранитель состояния для offset:

    • Управляет состоянием загрузки (текущее смещение)

    • Начинается с -batchSize, чтобы первая загрузка была с 0

    • Увеличивает смещение на batchSize при каждом срабатывании

  2. mergeScan – волшебный оператор для инкрементальной загрузки:

    • Сохраняет массив накопленных постов

    • Объединяет новые данные с существующими

    • Корректно обрабатывает параллельные запросы (в отличие от обычного scan)

Где полезен этот паттерн?

  • Постраничные API (пагинация)

  • Бесконечная прокрутка

  • Порционная загрузка данных

  • Любые сценарии накопления асинхронных данных

scan - https://rxjs.dev/api/operators/scan
mergeScan - https://rxjs.dev/api/operators/mergeScan
Больше об Angular - https://t.me/grandgular

Теги:
Рейтинг0
Комментарии0

afterEveryRender и afterNextRender

В Angular 20 afterRender был переименован в afterEveryRender, и это очень логично, так как теперь он более четко отражает суть (нейминг решает). Сам afterRender (далее afterEveryRender) и его брат afterNextRender появились в версии 17. Рассмотрим, почему эти два мощных инструмента управления рендерингом — не просто альтернативы ngAfterViewInit, а полноценные хуки жизненного цикла с бесшовной поддержкой SSR!

Это хуки?
Да! Это хуки нового типа, которые выполняются после рендеринга компонента:

  • Они не заменяют ngAfterViewInit/ngAfterContentInit, а дополняют их

  • Включают гранулярные реакции на рендеры, включая обновления

Почему идеально подходит для SSR?
Главное преимущество: обратные вызовы выполняются только на клиенте!
✅ После гидратации (в SSR)
✅ После первоначального рендеринга (в CSR)
✅ Больше никаких ошибок «документ не определен»

Использование:
constructor() {
// 🚫 Не запускается на сервере
// ✅ Запускается только один раз после загрузки браузера!
// 📊 Идеально подходит для однократной инициализации
afterNextRender(() => {
console.log('Next');
});

// 🚫 Не запускается на сервере
// 🔄 Запускается после каждого цикла обнаружения изменений
// ✨ Отлично подходит для обновлений, зависящих от DOM
afterEveryRender(() => {
console.log('Every');
});
}


Когда использовать?

afterNextRender

  • Одноразовые операции (инициализация библиотеки, загрузка данных)

  • Безопасная замена ngAfterViewInit для SSR

afterEveryRender

  • Отслеживание изменений DOM (измерения элементов, позиции)

    ⚠️ Внимание: может повлиять на производительность

Основные выводы

  • Интегрировано в систему жизненного цикла Angular

  • Автоматический пропуск на стороне сервера - больше никаких хаков isPlatformBrowser!

  • afterNextRender - "один раз после рендеринга"

  • afterEveryRender - "после каждого обновления"

"Я пока не использовал afterEveryRender в своих проектах - есть ли у вас практические примеры использования? Поделитесь в комментариях!"

Больше об 🅰️ngular в моём Telegram-канале

Теги:
Рейтинг0
Комментарии0

withComponentInputBinding()
Упрощение работы с параметрами маршрутизатора в Angular.

Как было раньше?

  1. Создаем переменную/свойство (Signal, BehaivorSubject, Observable, неважно)

  2. Инжектим и подписываемся на ActivatedRoute

  3. Получаем параметры маршрута

  4. Записываем в BS/Signal

😵‍💫😵‍💫😵‍💫

Манипуляций довольно много, но мы все к этому привыкли и это кажется нормальным.

Но с withComponentInputBinding() все стало намного проще:
1. Создаем сигнальный инпут... и...
Вот и все!

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

Функция не новая (кажется, появилась в Angular 16), но я редко ее видел в проектах.

Немного технической информации из документации:

🔍Маршрутизатор передает данные в input() из:

  1. Параметров запроса (?page=1&sort=asc)

  2. Параметров пути и матрицы (/users/123;details=true)

  3. Статических данных маршрута (data: { role: 'admin' })

  4. Результатов резолвера (resolve: { user: userResolver })

🔍 Приоритеты:
Если есть дублирующиеся ключи, данные переопределяются в порядке выше — резолверы имеют наивысший приоритет и перезапишут остальные.

🚩 Важный нюанс
Если в маршруте нет данных для input(), он получит undefined (например, если параметр запроса удален из URL).

ℹ️ Как задать значения по умолчанию?

✔ Через resolver (чтобы данные всегда были в маршруте)
✔ Через transform в input() (если нужно обрабатывать undefined)

Спасибо разработчикам Angular за эту функциональность 🙏.

Больше об 🅰️ngular в моём Telegram-канале

Теги:
Всего голосов 2: ↑1 и ↓1+2
Комментарии0

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

🦥 RxJS defer — ленивая инициализация Observable

defer — это фабрика, которая создает Observable только при подписке, а не во время объявления. Идеально подходит для:

  • HTTP-запросов (чтобы избежать преждевременного выполнения)

  • динамических данных (которые должны быть свежими при каждой подписке)

  • условных потоков (когда Observable зависит от состояния времени выполнения)

📌 Основные варианты использования

  1. Свежие данные при каждой подписке

    const freshData$ = defer(() => of(Date.now()));

    // Новая временная метка при каждой подписке()

  2. Работа с изменяемым состоянием

    const token$ = defer(() => of(localStorage.getItem('token')));

    // Всегда получает текущий токен, даже если обновлен

  3. Условные наблюдаемые

    const api$ = defer(() => isLoggedIn ? http.get('/user') : http.get('/guest') );

  4. Генерация случайного значения

    const random$ = defer(() => of(Math.random()));

    // Новое случайное число на подписку

🚫 Ограничения defer

  • нет кэширования → используйте shareReplay, если вам нужно повторно использовать результаты.

  • нет отмены запроса → объедините с switchMap/takeUntil для управления отменой

⚡Когда следует выбирать defer вместо обычных наблюдаемых?

  • данные должны быть свежими при каждом subscribe()

  • cоздание наблюдаемого стоит дорого и должно быть отложено

  • поток зависит от изменяемых условий (флаги функций, статус аутентификации и т. д.)

Больше об 🅰️ngular в моём Telegram-канале

Теги:
Рейтинг0
Комментарии0

Angular Hack: Цикл без данных (в тэмплейте)

Иногда нужно отобразить несколько одинаковых элементов чисто для ui-целей: скелетоны загрузки, звёзды рейтинга, пустые таблицы и т.д., но без реальных данных для итерации.

Вот мой способ (по крайней мере, я нигде такого не видел):

@for (_ of [].constructor(10); track $index) {
<div class="item"></div>
}

Используется Array.constructor, чтобы создать пустую массив фиксированной длины, который @for может перебрать по индексам.

Плюсы ✅

  • Чудо-код (удивит коллег)

  • Минимум кода (не нужно объявлять массив в компоненте)

Минусы ⚠️

  • Чудо-код (может ненадолго ввести в ступор чающего код человека)

Конечно, можно просто использовать Array.from({length: 10})... но так все делают, не интересно)

Норм тема? Как считаете?

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии3

Приглашаем вас на бесплатный вебинар «TypeScript за час: основы, плюсы и практика». Познакомим вас с TypeScript. Расскажем, зачем он появился, в чём его преимущества и как он помогает писать понятный и надёжный код. Подойдёт и новичкам, и практикам.

⁉️ На вебинаре вы сможете задать вопросы спикеру.

📅 Дата: 13.05.2025

Время: 17:00-18:00 (Мск)

На вебинаре:

✔️ История возникновения TypeScript

✔️ Преимущества использования TypeScript

✔️ Пример написания кода на TypeScript

👨‍🎓 Спикер: Кучин Евгений — разработчик на Java и JavaScript.

✍️Записаться на вебинар

Возможно, вам будет интересен курс «Язык программирования TypeScript». Вы освоите TypeScript, изучив типизацию, интерфейсы и классы. Узнаете, как использовать статическую типизацию, интегрировать TypeScript с существующим JavaScript и настраивать окружение разработки. Это поможет сделать ваш код более безопасным и структурированным.

Старт: 19 мая

Цена: 14 900 8 940 ₽ (-40%)

✍️ Записаться на курс

Теги:
Всего голосов 3: ↑1 и ↓2+1
Комментарии0

Приглашаем на новый бесплатный вебинар «Pattern matching в TypeScript: делаем код предсказуемым».

Разработчики часто сталкиваются с ситуациями, когда необходимость учёта множества сценариев делает код запутанным и трудным для восприятия. Проверки на null/undefined и конструкции if превращают его в нечитабельный и сложный для тестирования.

На вебинаре мы обсудим, как избежать этих ошибок, используя подходы из Domain-Driven Design (DDD) и функционального программирования (FP). Вы узнаете, как отделить бизнес-логику от реализационных деталей, создать качественные доменные модели и эффективно применять discriminated unions и паттерн-матчинг в Typescript.

⁉️ На вебинаре вы сможете задать вопросы спикеру.

📅 Дата: 24.04.2025

Время: 18:00-19:30 (мск)

На вебинаре:

✔️ Discriminated Unions

✔️ DDD

✔️ Business Logic as Data

✔️ FP

✔️ Declarative Programming

👨‍🎓 Спикер: Борисов Никита — эксперт в области фронтенд-разработки.

👉Записаться👈

Теги:
Рейтинг0
Комментарии0

Как я выбил 350к в месяц, не написав ни одной строчки кода сам

2025 год. Реалии
2025 год. Реалии

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

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

Инструменты

Harvi.pro — мой основной инструмент. Норм генерит фронт по текстовому описанию, меньше заморочек с оплатой для наших:

  • 999₽ — 10М токенов

  • 2499₽ — 25М + 5М бонусом

  • 4999₽ — 50М + 10М бонусом

Под капотом Claude 3.7 Sonnet. Беру средний тариф, хватает на 3-4 недели активной работы.

V0.dev от Vercel — тоже неплохой, но дороговат для меня:

  • Free — 20 генераций

  • Pro — $20 в месяц

  • Team — $30 в месяц

Под капотом тоже Claude 3.7 Sonnet. Качество вроде чуть лучше бывает, но с оплатой сами знаете что.

Replit — тут я собираю всё в кучу, тестирую и деплою. Удобно, что можно быстро показать клиенту результат.

Как это на самом деле работает

Не буду врать, что просто нажимаю кнопку и получаю готовый продукт. Это все еще работа:

  1. Собираю с клиента максимум инфы и референсов

  2. Генерю компоненты по частям (целые страницы редко получаются с первого раза)

  3. Много времени уходит на склеивание и фиксы

  4. Приходится знать хотя бы основы, чтобы понимать, что пошло не так

Но при этом скорость выросла раза в 3-4. Раньше лендинг делал неделю, сейчас — день-два. Простое приложение с формами — было 2 недели, стало 3-4 дня.

Беру в среднем 80-100к за проект, делаю 3-4 в месяц. Вот и выходит около 350к.

Да, чувствую, что теряю навыки в некоторых областях. Зато прокачался в составлении промптов — это теперь как отдельная специальность.

Ручной кодинг... скоро только в музее)))

Теги:
Всего голосов 7: ↑4 и ↓3+3
Комментарии7

Регулярно на Хабре выходят статьи с рекомендацией использовать moment.js. В комментариях обязательно начинают советовать какой-нибудь dayjs или js-joda, но не потому, что они чем-то сильно лучше, а потому, что первый задепрекейчен авторами.. в пользу luxon.

Что за мания такая у JS-еров использовать раздутые тормозные библиотеки? Есть же быстрый и миниатюрный $mol_time с гораздо более удобным и функциональным API, почти полностью поддерживающим ISO8601, в отличие от всех остальных библиотек.

Бенчмарки говорят сами за себя
Бенчмарки говорят сами за себя

Что мотивирует людей довольствоваться не самым лучшим решением в индустрии? Я, наверно, странный, но я не могу этого понять.

Теги:
Всего голосов 18: ↑7 и ↓11-2
Комментарии39

Энтузиасты запустили Doom с помощью типов TypeScript.

Проект запуска Doom исключительно в системе ввода TypeScript занял 12 дней по 18 часов в сутки. Разработчики провели проверку 3,5 триллиона строк текста, создали виртуальную машину WebAssembly на основе TypeScript и 177 ТБ типов TypeScript.

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии2