Frontender's notes [ru] – Telegram
Frontender's notes [ru]
33.8K subscribers
578 photos
38 videos
1 file
3.43K links
Ведущий канал о современном фронтенде: статьи, новости и практики.

По вопросам рекламы или разработки:
@g_abashkin

РКН: https://vk.cc/cJPG6y
Download Telegram
↔️ Logical properties в CSS — как сделать стили гибкими и универсальными

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

ℹ️ Что же это такое и когда они полезны?

inline определяет направление текста (например, слева направо или справа налево), а block — направление блоков, обычно сверху вниз, в зависимости от потока документа. Для горизонтальных отступов используются margin-inline-start и margin-inline-end, для вертикальных — padding-block-start и padding-block-end. Для позиционирования и границ применяются border-inline и inset-block.

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

• Переворачиваемые макеты

Для компонентов, которые могут «переворачиваться» (например, аватар слева/справа или сайдбар), логические свойства устраняют необходимость прописывать условные операторы в CSS.

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

• Контейнеры с изменяемым направлением потока

Представь карточки, которые становятся горизонтальными на десктопе — логические свойства автоматически подстроят все отступы и позиции.


Простой пример и мини-читшит

/* Старый способ */
.card {
padding-top: 12px;
padding-left: 16px;
}

/* С логическими свойствами */
.card {
padding-block-start: 12px;
padding-inline-start: 16px;
}

/* margin-inline — отступы по горизонтали
margin-block — отступы по вертикали
padding-inline — внутренние отступы горизонтальные
padding-block — внутренние вертикальные
inset-inline — позиционирование по горизонтали (left/right)
inset-block — позиционирование по вертикали (top/bottom) */


📌 Логические свойства CSS — это довольно современная и удобная фича которую стоит как минимум иметь в виду.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍5🐳1
📸 Атрибуты loading, decoding, fetchpriority — как ускорить загрузку изображений с нативными атрибутами

Есть три простых и нативных атрибута HTML, которые могут значительно ускорить загрузку изображений и сделать ваш интерфейс более отзывчивым. И хотя они поддерживаются всеми современными браузерами, почему-то их редко используют на практике. Давайте разберём их по порядку.

⬅️ loading="lazy" — откладываем загрузку

Атрибут loading="lazy" заставляет браузер откладывать загрузку изображений за пределами экрана, что экономит трафик пользователей, уменьшает время до интерактивности (TTI) и снижает нагрузку на слабые устройства. Его следует применять для всех изображений ниже первого экрана, а также для карточек, списков и галерей. Однако, не стоит использовать этот атрибут для важных для интерфейса изображений на первом экране, таких как логотипы и hero-изображения, чтобы избежать задержек в загрузке сайта.

⚡️ decoding="async" — асинхронная декодировка

Атрибут async позволяет браузеру асинхронно декодировать изображения, не блокируя рендеринг других элементов, что уменьшает визуальные задержки и ускоряет загрузку страниц. Это особенно полезно для больших изображений и элементов в лентах и списках, улучшая восприятие производительности и снижая «дерганье».

🔫 fetchpriority="high | low" — управление приоритетом загрузки

Атрибут loading определяет приоритет загрузки изображения: high для первоочередной загрузки, low для загрузки позже. Это уменьшает конкуренцию между ресурсами, ускоряет LCP и снижает визуальные задержки при рендеринге страницы, обеспечивая более быструю и плавную загрузку.


👀 Примеры и как использовать вместе

<!-- Откладываем загрузку -->
<img src="hero.png" loading="lazy" />

<!-- Асинхронная декодировка -->
<img src="photo.jpg" decoding="async" />

<!-- Управление приоритетом загрузки -->
<img src="hero.jpg" fetchpriority="high" />
<img src="avatar.jpg" loading="lazy" fetchpriority="low" />

<!-- Всё вместе -->
<img src="hero.jpg" decoding="async" fetchpriority="high" />
<img src="thumb.jpg" loading="lazy" decoding="async" fetchpriority="low" />


🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍116👀1
💡 Render Cost: как оценивать стоимость UI-операций

Производительность фронтенда — это не просто «быстрее». Важно понимать, какие операции UI обходятся браузеру в наибольшую цену. Render cost помогает измерять стоимость рендера, обновлений, изменений DOM, расчётов layout и стилей. Это важная метрика для оптимизации интерфейсов.

ℹ️ Что такое render cost?

Render cost — это сумма всех затрат, которые браузер несёт при выполнении операций с пользовательским интерфейсом, включая создание и изменение DOM-узлов, обновление стилей, пересчёт layout, перерисовка элементов и выполнение JS, которое запускает все эти операции. В крупных проектах неправильные UI-операции могут стать причиной лагов и фризов интерфейса.

Самые дорогие операции

Перерасчёт геометрии элементов, запуск рендеринга с кистью и смешивание слоёв — все эти процессы могут быть затратными для производительности приложения. Пересчёт геометрии элементов происходит при чтении свойств offsetWidth, getBoundingClientRect(), изменении размеров, положения или шрифтов, а также при применении сложных CSS-правил. Запуск рендеринга с кистью особенно дорог при использовании эффектов, фильтров или градиентов.

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

Как оценить render cost в реальных проектах

• React DevTools Profiler: Позволяет понять, какие компоненты перерисовываются слишком часто, где тратится больше всего времени и какие пропсы вызывают каскадные обновления.

• Chrome Performance panel: Главный инструмент для анализа. Позволяет увидеть трейсинг JS, layout events, paint events и точные триггеры reflow.

• Performance Insights: Подсвечивает проблемные места и даёт рекомендации по улучшению производительности.

• Lighthouse: Отлично показывает точки деградации на высоком уровне и предлагает пути для их устранения.

🤚 Что считается «дорогим» в UI?

В пользовательском интерфейсе (UI) «дорогим» считается всё, что требует значительных ресурсов для выполнения и может замедлять работу приложения. К таким элементам относятся частые полные перерисовки списков вместо частичных обновлений, громоздкие компоненты, где один стейт перерисовывает всю страницу, сложные CSS-стили, например, глубокие селекторы, а также DOM с тысячами узлов на одном экране и последовательное чтение и изменение layout (forcing reflow).

⚡️ Как снижать render cost

Чтобы снизить render cost, важно оптимизировать компоненты: делите их на мелкие для уменьшения области перерисовки. Используйте fine-grained реактивность с помощью сигналов, селекторов или memoized stores, чтобы обновлялось только необходимое. Избегайте живых reflow, группируя измерения и изменения DOM.

Применяйте виртуализацию для рендеринга только видимых элементов в DOM. Используйте transform вместо top/left в CSS, избегайте тяжёлых эффектов и следите за структурой CSS. Для тяжёлой логики можно использовать Web Workers, перенося вычисления в основной поток и сохраняя отзывчивость UI.


📌 Render cost — это не про то, как быстро что-то рендерится, а про то, сколько стоит сделать изменения. Иногда, чтобы оптимизировать, нужно не ускорять рендеринг, а избегать ненужных действий. Оптимизация UI — это как правильно распределить ресурсы и убрать лишнее. Важно не только сделать рендеринг быстрее, но и чтобы он был предсказуемым и точным.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥52👍2👎2👀1
⬆️ Профилирование бандла: что скрыто внутри .map файлов

Когда размер вашего фронтенд-бандла начинает расти, вы, вероятно, используете такие инструменты, как Webpack Bundle Analyzer, чтобы увидеть, что именно увеличивает размер. Но на самом деле эти инструменты работают с .map файлами и тут скрывается гораздо больше информации, чем кажется на первый взгляд. Давайте разберемся, что лежит внутри этих файлов и как их использовать для глубокого профилирования.

Что такое .map файлы?

Файлы .map — это JSON-структуры, которые содержат полную информацию о вашем коде. В них хранятся ссылки на оригинальные файлы, сам исходный код, соответствие между минифицированными и оригинальными строками кода, а также список символов и имён.

Это не просто файлы для дебага, это своего рода словарь вашего кода, который позволяет анализировать и профилировать его работу.

Почему .map файлы полезны для профилирования?

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

Это важно для профилирования, так как неправильные UI-операции часто вызывают лаги и фризы на страницах с большими бандлами.

Что можно увидеть в .map файле?

С помощью .map файлов можно выявить различные проблемы. Например, они помогут понять, если вы случайно импортировали весь пакет lodash вместо конкретной функции или подключили слишком тяжёлый UI-кит, хотя использовали только одну кнопку. Также вы сможете найти дублирование модулей, если разные версии одной и той же библиотеки были добавлены в ваш проект.

В некоторых случаях .map файлы показывают подтягивание ненужных polyfills или «раздутые» функции, которые не были удалены после трешейкинга. Всё это можно обнаружить, если внимательно изучить .map файл.

Как читать .map файлы?

Для анализа .map файлов можно использовать специальные инструменты, такие как maps-codec, source-map-explorer или даже встроенные инструменты в браузере через DevTools. Эти инструменты помогут вам понять, что именно добавляет вес вашему бандлу и как это влияет на производительность.

Если вы хотите пройти путь профилирования вручную, можно использовать source-map-explorer, который визуализирует содержимое .map файла и помогает быстро найти проблемные места.

Когда вы работаете с .map файлами, стоит следовать нескольким простым рекомендациям

• Во-первых, всегда анализируйте source map на продакшн-сборке, так как staging-сборки могут иметь разные флаги, влияющие на результат.
• Во-вторых, используйте опцию hidden-source-map, чтобы скрыть карты от публичного доступа, но использовать их в CI.
• Также не забывайте отслеживать динамические импорты, ведь .map файл может показать, что именно попадало в ваши чанки.
• И, конечно, сравнивайте .map файлы между сборками, чтобы понять, что именно увеличивает размер бандла.


📌 Если научиться правильно читать и использовать эти файлы, можно не только понять, почему бандл растёт, но и выявить, что в него попало лишнего. Вы увидите, какие импорты раздувают код и, в конечном счёте, что на самом деле происходит в вашем toolchain.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72🔥2
Forwarded from xCode Journal
🤣 Гениальный план, как избавиться от бесящих коллег

💥 xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
😁362👀1
Forwarded from xCode Journal
Вот вам план на декабрь

Уже завтра выйдет ежегодный адвент-календарь с задачами и головоломками по программированию — Advent of Code. Календарь в этот раз рассчитан на 12 дней, так что каждый день почти полмесяца будут выходить новые задачи. Решать их можно на любом языке программирования.

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

P.S уже вышел

✖️ xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥1
💬 Event Loop в Node.js VS в браузере

Многие считают, что event loop в Node.js и браузере работает одинаково. Однако, несмотря на общие черты, существуют важные различия, которые влияют на асинхронное поведение и производительность приложения. Разобравшись с этими различиями, можно писать более эффективный асинхронный код и избежать лагов и задержек. Давайте разберемся, что именно отличает работу event loop в этих двух средах.

Браузер: всё о пользовательском интерфейсе

В браузере event loop сосредоточен на работе с пользовательским интерфейсом (UI). Его основная задача — обеспечить плавность рендеринга, быстроту реакции на события, выполнение JavaScript и обработку Web APIs.

В процессе работы с UI браузер использует несколько типов очередей задач. Это microtasks, такие как обработка Promise и queueMicrotask, и macrotasks, в которые попадают setTimeout, setInterval и MessageChannel. Также есть отдельная фаза для рендеринга. Браузер обязан поддерживать плавность UI, поэтому между макротасками он обязательно вставляет фазу рендеринга, что позволяет минимизировать задержки при обновлении интерфейса.

Node.js: event loop от libuv

В Node.js event loop работает на основе библиотеки libuv, которая используется для асинхронных операций, таких как работа с файловой системой, сетью и другими I/O операциями. В отличие от браузера, в Node.js есть несколько фаз, которые позволяют эффективно управлять этими операциями.

Node.js использует шесть фаз, включая Timers (setTimeout, setInterval), Poll (обработка I/O операций), Check (setImmediate) и другие. Основное отличие заключается в том, что Node.js управляет низкоуровневыми операциями с системой, такими как файлы и сеть, в то время как браузер сосредоточен на рендеринге и UI. Это позволяет Node.js быть более гибким в обслуживании серверных запросов и файловых операций.

Где начинается путаница

Существует несколько распространенных недопониманий между setTimeout и setImmediate. В браузере нет метода setImmediate, в то время как в Node.js он выполняется в фазе Check, а setTimeout — в фазе Timers. Это может привести к путанице, особенно при переносе кода между Node.js и браузером.

Также стоит отметить различие в работе microtasks. В браузере микротаски выполняются сразу после каждого макротаска, а в Node.js они выполняются после каждой фазы event loop, что позволяет их более эффективно управлять и избегать блокировки цикла.

Ещё одним важным отличием является рендеринг

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

Например, repaint может произойти между macrotask, microtask и снова macrotask, что важно учитывать при оптимизации производительности в браузере.

Что важно помнить разработчику

• В Node.js основное внимание уделяется I/O операциям, таким как работа с файлами, сетью и процессами. Эти задачи добавляют свои очереди и обрабатываются в разных фазах event loop.
• В браузере event loop синхронизирован с частотой кадров, что критически важно для обеспечения плавности UI.
• Microtasks в Node.js ведут себя агрессивнее, особенно process.nextTick, который может заблокировать переход между фазами event loop, если заспамить его слишком большим количеством задач.
• setImmediate и setTimeout — это не одно и то же. Порядок их выполнения в Node.js зависит от контекста и фазы event loop, в которой они находятся.


📌 Знание этих различий позволяет избежать лагов и писать эффективный асинхронный код, который будет работать предсказуемо как в браузере, так и в серверной среде Node.js.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥72👍2👀2
GPT-5.1-Codex-Max: Новый кодинг от OpenAI 🍆

OpenAI анонсировала новинку, которая может стать настоящим прорывом — GPT-5.1-Codex-Max. Выглядит как не просто шаг в ответ на бурю вокруг Gemini, а вполне себе уверенный шаг вперёд.

Что же интересного в этой версии? Давайте разберёмся.

Революция для Windows и Powershell
Теперь Codex не просто кодит как обычно. Он понял, как работать в среде Windows, и особенно с Powershell. Это означает, что модель теперь точно разбирается в особенностях файловой системы, путях и всем, что связано с Windows. Но это ещё не всё — появилась новая фича под названием "Agent mode". Эта штука позволяет модели работать автономно в терминале, выполняя задачи без постоянного контроля. Не забудьте, что доступ можно настроить, если надо.

Автономность на новом уровне
OpenAI заявляет, что модель способна работать более 24 часов без остановки. Можете себе представить? Правда, тут стоит напомнить про достижение Anthropic с их Sonnet 4.5, которая обещает 30 часов работы. Но всё равно впечатляет, правда?

Новая память — что это значит?
Модель теперь умеет работать с большими контекстами, благодаря новой фиче "compaction". Что это? Когда окно контекста близко к своему пределу, Codex сжимает старую информацию и переносит её в новое окно вместе с актуальной информацией. Как бы креативная версия краткосрочной и долгосрочной памяти, не так ли?

Результаты и метрики
GPT-5.1-Codex-Max показывает отличные результаты — 77.9% точности на SWE-bench Verified, что превосходит даже Gemini 3 и Sonnet 4.5 от Claude. К тому же, модель теперь тратит на 30% меньше токенов при среднем уровне рассуждений, но результаты всё те же.


Так что, эта версия уже доступна для использования в IDE и Codex CLI. Ждете API? Обещают скоро добавить.

Data Science
Please open Telegram to view this post
VIEW IN TELEGRAM
😁63👎2👀2
⚡️ Анти-паттерны больших фронтенд-проектов

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

ℹ️ «Глобальное всё»

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

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

ℹ️ «Компоненты-монолиты»

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

Решение: Для улучшения структуры и поддерживаемости кода необходимо разделить его на слои: UI, управление состоянием, доменная логика и взаимодействие с API.

ℹ️ «Push-архитектура»

Каждый компонент тянет данные сам и вот тут начинается хаос: дублирование запросов, гонки условий, зависимости на каждом шагу.

Решение: централизованный слой данных. Используйте query-клиенты, сервисы или модели для эффективного управления данными.

ℹ️ «Секретные зависимости»

Компоненты, которые используют скрытые зависимости, такие как localStorage, window, сторонние сервисы или скрытые контексты, не указаны явно.

Решение: всегда документируйте зависимости и явно описывайте их в коде. Это упростит тестирование и переносимость компонентов.

ℹ️ «Тяжёлые re-render цепочки»

Когда один компонент меняет state, и пол-страницы перерисовывается, вызывая лаги и замедление интерфейса.

Решение: используйте signals, selectors и fine-grained реактивность. Архитектурная изоляция поможет минимизировать лишние ререндеры.

ℹ️ «Всё через Redux / Context / глобальный стор»

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

Решение: минимизируйте использование глобального стейта. Локальные состояния должны храниться локально.

ℹ️ «Типизация по настроению»

Когда часть кода типизирована, а часть — нет, или используется any. В итоге типизация не защищает, а мешает.

Решение: установите единые правила типизации и используйте строгий линтинг для соблюдения этих правил.

ℹ️ «Сложность вместо простоты»

Когда для решения простых задач используются сложные абстракции, кастомные DI, самописные хуки и роутеры, что усложняет поддержку кода.

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

ℹ️ «Отсутствие архитектурных границ»

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

Решение: используйте feature-sliced или modular архитектуру, следите за слоями, внедрите статический анализ зависимостей и запретите пересечения между слоями.


📌 Большие проекты не рушатся на раз-два. Они как бы потихоньку «гниют», но если у вас хорошая архитектура, дисциплина и вы регулярно что-то улучшаете, то можно избежать многих проблем.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
12👍9👀1
JavaScript сегодня отмечает 30-летие 🎂

Именно 4 декабря 1995 года миру показали язык под знакомым нам названием — JavaScript.

Вот история именинника:

• У языка было три имени за пару месяцев.
Сначала его назвали Mocha, потом переименовали в LiveScript, и только затем закрепилось финальное — JavaScript.

• К Java он почти не имеет отношения.
Название выбрали скорее как маркетинговый ход: в середине 90-х вокруг Java был мощный хайп, и на эту волну просто запрыгнули.

• JS слепили всего за 10 дней.
Брендан Эйх в бешеном темпе собрал первую версию, когда в Netscape решили: «нам срочно нужен язык для скриптов в браузере».

• Создатель языка успел стать CEO Mozilla — и быстро лишиться должности.
Из-за скандала вокруг его гомофобных взглядов Эйху пришлось уйти с поста, хотя имя JavaScript уже навсегда вписано в историю.


🎉 Поздравляем старичка, который до сих пор двигает весь веб.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
27🔥103🐳2
📣 Синхронизация состояния между вкладками: BroadcastChannel, SharedWorker и localStorage

Когда пользователь открывает несколько вкладок одного приложения, часто возникает проблема синхронизации состояния. Например, пользователь может выйти из аккаунта в одной вкладке, но в других вкладках приложение продолжит считать его авторизованным. В 2025 году у нас есть несколько инструментов, которые помогают решить эту задачу: BroadcastChannel, SharedWorker и, для старых браузеров, localStorage.

BroadcastChannel — простое решение для синхронизации сообщений

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

Преимущества: простота, быстрая доставка, работа в фоновом режиме.
Ограничения: не поддерживает общее состояние и сложные операции.

SharedWorker — когда все вкладки работают как одно приложение

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

Преимущества: централизованное хранилище состояния, разделение ресурсов и снижение повторных API-запросов.
Ограничения: не поддерживается в Safari, требует сложного дебаггинга и продуманной архитектуры.

LocalStorage + storage event — старый, но работающий способ

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

Преимущества: простота реализации и широкая совместимость.
Ограничения: хранит только строки, событие storage срабатывает в других вкладках, а не в той, где произошли изменения, и может быть медленнее, чем BroadcastChannel.


Примеры:

// BroadcastChannel
const channel = new BroadcastChannel("session");

channel.onmessage = (e) => {
console.log("message:", e.data);
};

channel.postMessage({ loggedOut: true });

// SharedWorker
// main.js
const worker = new SharedWorker("worker.js");
worker.port.postMessage({ type: "ping" });
worker.port.onmessage = (e) => console.log(e.data);

// worker.js
onconnect = (e) => {
const port = e.ports[0];
port.onmessage = () => port.postMessage("pong");
};

// LocalStorage + storage event
window.addEventListener("storage", (e) => {
if (e.key === "logout") {
// синхронизация
}
});


📌 Для синхронизации состояния между вкладками используют BroadcastChannel для уведомлений (например, для событий входа/выхода), SharedWorker для разделения состояния в PWA и дашбордах, а в старых браузерах — localStorage с событием storage. У каждого инструмента своя фишка, и выбор зависит от того, насколько замороченный у тебя проект, какие браузеры поддерживаешь и с какими данными работаешь.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍113🔥1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4🐳3👎21
Forwarded from xCode Journal
🌎 Google не разрешает сотрудникам использовать свою же недавно выпущенную IDE Antigravity

И, видимо, не зря — реддитор рассказал, что ИИ-агент Antigravity случайно удалил весь его диск, пока пытался исправить баг:
«Я просматриваю журналы с предыдущего шага и с ужасом вижу, что команда, которую я выполнил для очистки кэша проекта (rmdir), по всей видимости, ошибочно указала на корень вашего диска D:, а не на конкретную папку проекта.
Мне очень, очень жаль.»


✖️ xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
😁21🐳1