NG Stream
248 subscribers
85 photos
4 videos
2 files
465 links
Авторский канал об Angular и новостях фронтенда. Мы рассказываем о том, с чем сталкиваемся в процессе разработки, делимся полезными, на наш взгляд, статьями.

Made by devs for 🅰️ devs

Авторы:
- @antoonG
- @basters

Чат: https://t.me/+JYGeE7HekO04Y2My
Download Telegram
Я наконец-то добрался до возможности написать заметки в канал. Месяц выдался напряженным.

Тем временем уже опубликованы предрелизные и RC сборки 21.0.0. Одной из самых ожидаемых фичей является Signal forms. В канале уже есть заметки, собранные по dev notes команды Angular. А вы пробовали превью сигнальных форм? Понятно, что реализация пока не рекомендуется для enterprise проектов. Я немного поковырял на пет проекте и заметил, что DX заметно подрос!

Рассмотрим стандартный сценарий - форма заказа товара, соответствующая OrderForm.

interface OrderForm {
information: FormGroup<InformationGroupControls>,
cost: FormGroup<CostGroupControls>,
additionalDetail?: FormGroup<AdditionalDetailControls>
}


📌 Reactive Forms состоят из нескольких sub FormGroups. И некоторые из них добавляются по специфичной бизнес логике. Для жонглирования синхронизации UI и модели данных приходится использовать addControl и removeControl. На прктике все это обрастает значительным количеством логики, которая потом сложна для восприятия.

📌 Signal forms. Если еще не разобрались, задам контекст. Эти формы строятся на основе готового объекта (модели данных). В нашем случае представим объект, соответствующий интерфейсу OrderForm. И здесь для управления отображением формы предусмотрен немного другой API. Есть 2 подхода. В зависимости от того, надо ли отображать модель на UI.

1 случай. Когда пользователь может захотеть добавить в форму заказа дополнительные данные, например, через чекбокс. В этом случае доп поля должны отобразиться на странице. В этом случае пользуемся свойством hidden(). При этом:

- поля присутствуют в модели, но скрыты
- сохраняется и отрабатывает валидация
- состояние сохраняется при скрытии/показе

2 случай. Данные не нужно отображать. В этом случае поля опциональны в модели, а валидация стоит применять через applyWhenValue().

orderForm = form(this.orderModel, order => {
// 1 случай. Добавлена валидация для additionalDetail:
apply(order.additionalDetail, orderDetailSchema);

// ИЛИ
// 2 случай. Добавить валидацию, если представлены данные
applyWhenValue(
order.additionalDetail,
(detail) => detail !== undefined,
orderDetailSchema,
);

// Пользователь не должен видеть часть формы, пока не отмечен checkbox
hidden(order.additionalDetail, ({valueOf}) => valueOf(order.showAdditionalDetail));
});


Еще на Q&A сессии с разработчиками говорилось, что перед созданием формы возможно объединить несколько сигналов. Например, использовать linkedSignal().

selectedItem = signal("Phone");
quantity = linkedSignal({
source: this.selectedItem,
computation: () => 1,
});


Если состояние формы инициализируется из resource(), то linkedSignal() может указать, как должно обновляться состояние формы, когда сервер присылает новое значение. Поскольку он получает старое и новое значение от сервера и знает текущее состояние, может выполнить "3-way merge". Пока что звучит непонятно и нужно смотреть детали.

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

📌 Производительность без необходимости ручной оптимизации. Нет лишних проверок изменений.
📌 Совместимость с сигналами и предсказуемое управление состоянием. Самый очевидный плюс, теперь формы вписываются картину всего приложения, поскольку при первом внедрении сигналов переключения доставляли неудобства.
📌 Композиция и переиспользование. За счет schema для построения и валидации (о чем писал раньше), linkedSignal, композиция сложных форм становится более интуитивной.
📌 Типобезопасность. Типизация форм стала лучше, меньше потребности в приведении типов, как это было, например, с FormRecord<T> для динамических форм.

#angular #angular21 #signal_forms

NgStream / Чат
🔥7
На улице осень, близится релиз Angular, который мы сможем заценить в течение пары недель.

С 21 версии Vitest будет использоваться как test runner по умолчанию для новых проектов. Но пока что под флагом experimental.

Дело в том, что в 2023 году Karma стала deprecated и вставал вопрос, на какой инструмент переходить. Кстати, в течение года команда Karma все еще правила баги, критические уязвимости и тд. В итоге был выбран Vitest, который обладает мощным API, по сравнению с Jasmine и даже Jest. Кроме того, включает browser mode, что означает запуск тестов в реальном окружении. Vitest работает на базе Vite.

📌 Преимущества Vitest
- Ускорение благодаря ES-модулям;
- Нативная поддержка TypeScript;
- Встроенная поддержка моков и spies;

📌 Async-oriented API?
Новые инструменты разработаны с учетом обратной совместимости - работа с TestBed и существующими утилитами.
Одна из приглянувшихся мне фичей - Test Context, которая позволяет задать контекст тестирования. На первый взгляд, похоже на DI для тестов. Будет удобнее работать, например, с фича флагами, передавая конкретный контекст для теста. Есть и другие интересные инструменты - Polling Feature, Soft Assertions.

📌 При чем тут ZoneJS?
Zone.js патчит setTimeout, setInterval и тд, что позволяет отслеживать асинхронные операции. Однако нативные Promise оставались вне зоны контроля. Сейчас есть некоторые проблемы с долгим ожиданием таймеров и непредсказуемым поведением в сложных сценариях.

С 21 версии zoneless является стандартом. Это означает, что
- fakeAsync() и waitForAsync() перестают работать без явного включения Zone.js
- Существующие тесты требуют переписывания асинхронных частей.
Vitest и Jest предлагают собственные механизмы контроля времени:

// Включение fake timers
vi.useFakeTimers();

// Запуск всех таймеров (включая setInterval)
vi.runAllTimers();

// Запуск только ожидающих таймеров
vi.runOnlyPendingTimers();


📌 Недавно был влит MR, добавляющий возможность выбора между vitest (default) и karma и установку соответствующего билдера со всеми зависимостями.

📌 Разработчики предполагают постепенную миграцию. Стоит начать с добавления Vitest параллельно с существующей конфигурацией, затем постепенно переносить наиболее медленные тесты, заменять fakeAsync() на fake timers. И полностью перейти на новую инфраструктуру.

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

#angular #angular21

NgStream / Чат
🔥6❤‍🔥11
Developer Event, на котором будет представлен Angular v21 со всеми нововведениями, анонсирован на 20 ноября.

Стрим пройдет в 22:00. 👾

Кстати, на сайте теперь есть раздел с dev events. Может я не замечал раньше🤔

Что больше всего ожидаете от релиза?

📌 Новые инструменты Angular MCP Server для улучшения AI-рабочих процессов и генерации кода.
📌 Signal Forms - новый, упрощенный подход к формам.
📌 Новые детали о пакете Angular ARIA. Неужели увидим a11y инструменты?

#angular #angular21

NgStream / Чат
🔥51❤‍🔥1
Оптимизации @defer

Defferable views, добавленные в Angular 17, позволяют лениво загрузить данные по определенному условию. Для определения момента, когда пользователю необходимо загрузить и показать блок на странице, используются триггеры (triggers). Некоторые из них и были улучшены.

@defer {
<large-component />
} @placeholder {
<p>Placeholder content</p>
}


📌 В текущей реализации использование триггера prefetch on viewport немного не логично - если @placeholder уже находится в области viewport и bundle уже загружен, стоит уже отображать компонент, а не использовать prefetch. Это означает, что prefetch on viewport имеет смысл только при использовании с target, который появляется перед @defer, но есть нюанс - легко забыть обновить target при перемещении или переиспользовании компонентов.

Резюмируя, была добавлена поддержка offset параметра IntersectionObserver для триггеров on viewport, prefetch on viewport и hydrate on viewport, который будет активировать загрузку до того, как элемент достигнет viewport.

@defer(on viewport; prefetch on viewport(200)) {
<component />
}


📌 Из плюсов можно отметить меньшее время ожидания пользователем, т.к. предзагрузка начнется до того, как пользователь увидит placeholder. И более оптимальное использование сетевых ресурсов.

Подробности по ссылке.

#angular #angular21 #signal_forms

NgStream / Чат
❤‍🔥43
Скорее всего, в Angular 21 будет расширен набор возможных типов ViewEncapsulation. Причем, на фоне разговоров о формах про него молчат!

Сейчас, как мы знаем, доступны три типа (enum ключа).
- Emulated. Применяется по умолчанию. Стили изолированы для компонента
- None. Стили становятся глобальными и применяются ко всему приложению.
- ShadowDom. Стили полностью скрыты нативным способом в ShadowDOM. Хорошо подходит для написания виджетов в приложении, нотификаций или веб-компонентов.

Будет добавлен ViewEncapsulation: IsolatedShadowDom. Пока в статусе experimental.

Он похож на ShadowDom, но, в отличие от него, строго гарантирует, что в шаблоне будут применены только стили самого компонента, а внешние стили проигнорированы. Будет довольно удобным, например, для написания электронных писем, когда не хотите, чтобы внешние стили влияли на элементы (текст, изображения).

#angular #angular21

NgStream / Чат
👍10
В новой версии Angular 21 в составе CLI-инструментов для MCP появится коллекция из 18 готовых примеров, которые наглядно показывают, как работать с сигнальными формами. Что такое MCP, я рассказывал выше.

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

Примеры включают
- Core concepts and basic setup
- Built-in and cross-field validation
- Dynamic and conditional form structures
- Custom form controls and reusable validators
- Asynchronous operations and third-party integrations (Zod)
- Best practices for testing, accessibility, and styling

Что еще любопытно, разработчики сразу добавляют ARIA атрибуты для валидации форм. Например, aria-describedby="email-errors" и aria-errormessage, говорящий о том, что за ошибка произошла в конкретном контроле.

#angular #angular21

NgStream / Чат
👍4
Angular 21 вышел!

Причем еще на прошлой неделе. И самое время посмотреть, какие нововведения были добавлены. Я подчеркнул, на мой взгляд, основные фичи и указал статус для лучшего восприятия.

📌 Signal Forms. Experimental. Модель формы определяется через сигнал, который автоматически синхронизируется с привязанными к нему полями формы через директиву [field]. Schema-based валидация. ControlValueAccessor теперь optional, работает в режиме обратной совместимости.

📌 Angular Aria. Developer Preview. Это набор headless-директив, которые реализуют распространённые WAI-ARIA паттерны доступности. Они обрабатывают клавиатурные события, ARIA-атрибуты, управление фокусом и поддержку скринридеров. Пока не совсем понятны детали и как применять на практике. Интересно, что у Angular свой инструмент, наверняка вдохновленный Material.

📌 MCP Server. На презентации Developer Event большой акцент был сделан на развитии инструментов. В частности, показали автоматическую миграцию на zoneless с пошаговым планом.

📌 Vitest. Test runner по умолчанию для новых проектов. Подробнее писал здесь. Также в документации посвящена отдельная страница по миграции.

📌 Zoneless. Stable. Включен по умолчанию. Из преимуществ - улучшение Core Web Vitals, нативная поддержка async-await, уменьшение размера бандла, упрощение отладки и лучший контроль за изменениями.

Кроме того:

📌 HttpClient будет добавлен в приложение по умолчанию. Нет необходимости указывать provideHttpClient().

📌 Добавили поддержку регулярных выражений в шаблонах. Выглядит сомнительно, на мой взгляд. Шаблон должен отвечать за отображение, а не наброс логики, которую зачем-то вытащили из класса.

@let isValidNumber = /\d+/.test(someValue);

@if (!isValidNumber) {
<p>{{someValue}} is not a valid number!</p>
}


📌 SimpleChanges теперь generic! Раньше был указан any для previousValue и currentValue , по факту означает отключение типизации.

Использование ngClass не рекомендуется. Вместо него стоит использовать class. Добавлен schematic.

ng generate @angular/core:ngclass-to-class 


[style]="{ 'border-color': borderColor() }"


📌 Обновлена страница Angular Can I Use со списком фичей и их статусами. Почему-то плохо открывается, только через vpn.

В общем, обновление получилось интересным с значительными улучшениями. Если еще не обновились и есть возможность - самое время! Представленные изменения существенно улучшают DX и направлены на повышение производительности приложений.

Кстати, отдельно хочется отметить необычную подачу с видеоигрой на Developer Event. Ну, круто же!)

Заметка в блоге с подробностями.

#angular #angular21

NgStream / Чат
🔥6👍2
В новой версии, как многие заметили, изменился подход к созданию custom control.
Почему-то многие говорят о том, что создание контролов через ControlValueAccessor было неудобным, много бойлерплейта… Я так не считаю, не вижу сложности в реализации интерфейса в несколько строк кода. Несравнимо с какими-нибудь сторами… Но не спорю, что стало еще проще. Нет необходимости указывать каждый раз provide: NG_VALUE_ACCESSOR токен, реализовывать методы.

В общем, теперь интерфейс ControlValueAccessor будет использоваться преимущественно при написании custom control для Template-Driven и Reactive Forms. Но совместим с signal forms!

Пока что CVA не помечается, как deprecated, просто сигнальные формы рекомендованы для использования:) Скорее всего, сделано на время перехода, которое может быть долгим.
А для создания signal custom control необходимо реализовать интерфейс FormValueControl<T> , который обязывает объявить только поле value:ModelSignal<T> = model(). При необходимости добавить disabled input. Для реализации switchers/toggles нужен, соответственно, FormCheckboxControl<T>. И тот, и другой наследуются от FormUiControl, который содержит все необходимые свойства: touched, dirty, required, pending, hidden, errors и тд.

Для вставки самого компонента используется директива [field].

На мой взгляд, улучшение больше направлено на новичков для уменьшения порога входа. Как считаете вы? Если не согласны, пишите в комментариях свое мнение!

#angular #angular21

NgStream / Чат
🔥6
В декабре появились новости об уязвимостях в Angular

И здесь в чате об этом писали, спасибо @ngxSamurai за новость👍🏻

📌 Сначала в репозитории опубликовали сообщение о CSRF уязвимости.
Суть в том, что URL, начинающиеся с //, обрабатываются некорректно. Рекомендуется проверить приложение на наличие динамически формируемых URL, особенно с участием пользовательских данных.

📌 Но об этом уже многие слышали, но на прошлой неделе добавилась XSS уязвимость, которая возникает из-за недостаточной проверки URL-атрибутов: Схема безопасности некорректно классифицирует некоторые атрибуты, которые могут содержать URL (например, xlink:href в SVG). Это позволяет передавать в них javascript: URL, которые не блокируются.

📌 Уязвимость в SVG: Атрибут attributeName в элементах SVG-анимации ( , и др.) не проверялся должным образом. Злоумышленник может динамически назначить этот атрибут как "href" и передать в values вредоносный javascript: URL, что также обходит санитизацию.

Команда Angular рекомендует обновить приложения до следующих версий:
- Angular v19: обновиться до 19.2.17
- Angular v20: обновиться до 20.3.15
- Angular v21: обновиться до 21.0.2

#angular

NgStream / Чат
👍41👏1
Перегрузка функций

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

📌 Ключевое правило - более специфичные сигнатуры должны быть выше, общие (any, unknown) - ниже. TypeScript использует первую подходящую перегрузку сверху вниз.

// Хорошо
declare function fn(el: HTMLDivElement): string;
declare function fn(el: HTMLElement): number;
declare function fn(el: unknown): unknown;

// Плохо
declare function fn(el: unknown): unknown;
declare function fn(el: HTMLElement): number;


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

unknown ⊃ any ⊃ HTMLElement ⊃ HTMLDivElement
// где ⊃ означает "является супертипом"

Несмотря на то, что union types безопаснее, перегрузки функций обеспечивают лучший DX для других разработчиков через автодополнение. Пишите в комментарии, если тоже сталкивались или есть другой подобный опыт:)

#typescript

NgStream / Чат
👍5❤‍🔥1
Обновление OWASP

Впервые с 2021 года обновился Top 10 - опрос о категориях уязвимостей, которые чаще всего встречаются в индустрии.

📌 О чем вообще речь?

OWASP - сообщество, которое создает открытые стандарты, инструменты и документацию по безопасности веб-приложений.

📌 Сначала коротко о самых известных инструментах.

- OWASP Cheat Sheet - руководства по конкретным темам (аутентификация, криптография, защита от SQL-инъекций и тд).
- OWASP Application Security Verification Standard - описывает требования безопасности и используется для проведения аудитов. При проектировании приложения позволяет не забыть о валидации данных на клиенте, работе с токенами, защите от CSRF.
- OWASP Zed Attack Proxy (ZAP) - инструмент для динамического тестирования безопасности (DAST), который помогает автоматически находить уязвимости в работающем приложении.

📌 Теперь об отчете.

Самым интересным кажется появление в рейтинге supply chain атак. Если кратко, то это тип атак через любой из компонентов цепочки поставки – сторонние библиотеки, инфраструктура сборки, хранения кода, мониторинга. При этом риск охватывает и инструменты разработки на основе ИИ, которые сами становятся вектором атаки (небезопасный сгенерированный код, уязвимости в самих помощниках).

Благодаря ORM и санитизации injections перестают быть острой проблемой и сместились с третьего места на пятое по частоте возникновения.

Broken Access Control сохраняет за собой первое место, подчеркивая его фундаментальную и повсеместную опасность. Статистика указывает на всеобъемлющую проблему, которая может усугубиться с развитием ИИ агентов.

При этом, ИИ рассматривают и как решение для обнаружения сложных логических уязвимостей и снижения ложных срабатываний.

📌 Общий тренд говорит о том, что от организаций требуется смещение фокуса с проверки кода на обеспечение безопасности всего жизненного цикла разработки и эксплуатации.

NgStream / Чат
👍3
В сообществе опять вернулись к вопросу переключения на стратегию Onpush по умолчанию. Эта идея давно обсуждалась, но после миграции компонентов на standalone вернулись снова.

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

Ранее предлагались варианты глобальной настройки (через angularCompilerOptions или angular.json), но отказались, так как их сложнее контролировать и понимать при работе с конкретным компонентом.

Сейчас же обсуждается вариант с автоматической миграцией, аналогичной переходу на stabdalone. Может даже миграцией по шагам. В общем, недавно выкатили proposal, за который можно проголосовать.

#angular

NgStream / Чат
4👍3
Скоро новогодние праздники, кто-то уже взял отпуск и отдыхает, кто-то радуется снегу:)

Всех поздравляю с наступающим Новым годом и Рождеством!🎄🎉🎉🎉🎉🎉
Вернемся к новостям уже в следующем!

Спасибо, что подписаны! Хотим пожелать нам всем профессионально развиваться и не забывать отдыхать!
112🎄4
Пока вы догуливаете последние дни каникул, команда Angular, спустя 8 лет, начала работу над поддержкой стрелочных функций прямо в шаблонах!

📌 планируется поддержка только implicit returns, это должно будет предотвратить миграцию сложных функций, содержащих бизнес-логику, в шаблоны

📌 внутри этих функций нельзя будет использовать pipes, но результат работы этих функций можно будет передавать в pipe через конвеер
{{ (a, b) => a + b | currency }}


в комментах Manfred Steyer предложил также избавиться от магической переменной $event и добавить возможность использовать явный параметр (click)="(e) => doStuff(e)"

По сути, это всё будет in-place решением для функций-компараторов, например для trackBy, либо же:
<select [compareWith]="(a, b) => a.id === b.id"/>

<mat-autocomplete [displayWith]="option => option.name"/>

<button (click)="someSignal.update(prev => prev + 1)"/>


А что с производительностью?
Заявлено, что если функция ссылается только на свои собственные параметры, то она будет автоматически выноситься в top-level константу и не будет пересоздаваться при каждом Change Detection.
А в случаях, когда функция ссылается на контекстные переменные шаблона – она будет сохранена в текущем View, после чего будет подставляться где необходимо.

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

А что вы думаете об этом?

#angular

NgStream / Чат
🔥10👍21
Команда Angular добавит контроль за очисткой инжекторов при переходе с одного route на другой.

📌 Когда для маршрута определяются провайдеры (через providers в Route или lazy загрузку модуля), Angular создает для этого маршрута отдельный EnvironmentInjector. И инжекторы никогда не уничтожаются, даже если пользователь перешел на другой route.
В этом состоит основная проблема, что приводит накоплению неиспользуемых инжекторов в памяти, неосвобождаемым подпискам и ресурсам компонентов и, в результате, росту потребления памяти в приложениях. Для современных SPA это критично.

Для пояснения следующего пункта нужно пояснить, кто не знает.

RouteReuseStrategy - стратегия управления жизненным циклом компонентов роутов. Если чуть упростить, то механизм, который позволяет кешировать роуты, а именно инстанс компонента и относящийся к нему DOM, чтобы впоследствии (при повторном обращении к route) достать из кеша.

Получается, стратегия определяет:
- Уничтожать и пересоздавать компоненты при навигации (поведение по умолчанию) или

- Сохранять в памяти и переиспользовать компоненты с их состоянием.


📌 При использовании этой стратегии объекты DetachedRouteHandle сохранялись в памяти. Если пользователь больше не возвращался на сохраненный route, компоненты не уничтожались и не отписывались от Observable, что постепенно замедляло работу приложения. В этом состоит вторая проблема.

📌 Обновление вводит механизмы для автоматической и ручной очистки ресурсов. Для этого используется алгоритм "mark and sweep", который выявляет неиспользуемые инжекторы и освобождает ресурсы.
Для автоматической очистки рекомендуется использовать withExperimentalAutoCleanupInjectors().

export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withExperimentalAutoCleanupInjectors())
]
};


📌 Обновление RouteReuseStrategy
В стратегию добавлены новые методы - shouldDestroyInjector и retrieveStoredRouteHandles, которые дают более тонкий контроль над тем, когда именно нужно очищать ресурсы.

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

МР

#angular

NgStream / Чат
❤‍🔥6👍3
Angular tip

Как вы знаете, в обновленном Style guide, направленном на обеспечение единообразия кода, основное внимание уделяется стандартам именования файлов. Начиная с 21 версии для новых проектов предполагается новый формат.

Функциональные единицы теперь не должны использовать суффикс. Например, для компонента UserProfile файлы должны называться user-profile.ts, user-profile.html и user-profile.scss.

Фишка в том, что добавлен флаг для сохранения текущего подхода.

--file-name-style-guide=2016


В этом случае компоненты, сервисы и другие элементы получат классические суффиксы.

#angular

NgStream / Чат
👍8🤔1
Вокруг vibe coding и всевозможных LLM не стихает информационный шум.

📌 Читая заголовки выступлений на митапах и конференциях, по ощущениям, половина о том, как подружиться с ИИ, как внедрить, управлять…, организовать процесс vibe coding…

📌 Вдруг, кто не знает, vibe coding - разработка, где человек, в основном, описывает задачу на естественном языке, а LLM генерирует код. Я решил написать свое отношение к теме vibe coding.

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

📌 Особенно остро этот вопрос касается джунов. ИИ делает хуже им, предоставляя готовые ответы, которые не позволяют набирать нужный опыт. Чем решение хорошо/плохо? Почему такое решение? Подобный подход подталкивает брать готовое решение и не разбираться в вопросе самостоятельно. А на первых этапах особенно важно походить по граблям и набить шишки.
В общем, я бы сказал, что внедрять джунам AI нужно не бездумно, а подкреплять его нормальными инженерными практиками, помощью коллег.

📌 Сложно спорить, есть очевидные плюсы

- Прототипирование возможных решений. Существенная экономия времени.
- Объемная и рутинная работа. Написать CRUD или что-то аналогичное. Быстро, удобно доставить бизнес-ценность.

📌 Но за эту скорость мы платим тем, что постепенно утрачивается навык самостоятельно решать задачу, навык глубокой отладки. В общем, мы перестаем меньше писать. Это же то, за чем многие пришли в разработку! Наша ценность всегда была в глубоком понимании, а не просто в умении производить код.

Я использую llm для генерации документации, иногда для написания тестов. С правками получается неплохо. Не всегда, правда😅

📌 Вывод в том, что ИИ, на мой взгляд, это усилитель навыков, а не замена разработчика. Как молоток не делает из человека плотника, так и ИИ не делает из новичка senior-разработчика. ИИ требует осознанности, важно оценивать качество сгенерированного кода, а не просто копировать. Соблюдать баланс, еще одна важная часть нашей экспертизы.

А какие ИИ инструменты используете вы в разработке? Добавлю небольшой опрос. Если есть мысли, пишите в комментариях, интересно будет узнать!

NgStream / Чат
👍3
TypeScript 6.0. И никаких компромиссов.

Если предыдущие версии старались сохранять максимальную обратную совместимость, то версия 6.0 нацелена на решительное избавление от legacy и установку новых стандартов «по умолчанию».

Что изменится в новой версии?

📌 Strict Mode теперь обязателен. Это не просто изменение одного флага, а глубокая смена логики наследования настроек. Теперь такие критические проверки, как noImplicitAny и strictNullChecks, становятся стандартом. Также по умолчанию будет подразумеваться директива "use strict"
📌 target es5 deprecated. Минимально возможный стандарт теперь ES2015. Отказ от ES5 позволит команде упростить внутреннюю логику. Возможно, ускорит процесс сборки.
📌 Включение параметра noUncheckedSideEffectImports по умолчанию. Позволит улучшить существующие конфиги и выявлять некорректные импорты в IDE.

Значительная часть работы посвящена удалению старых опций для упрощения конфигурации. Помечены deprecated baseUrl, --outFile, а также module resolutions node10 и classic .

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

24 февраля 2026 - RC Release.
17 марта 2026 - Final Release.

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

Подробнее здесь. Typescript Iteration Plan.

#typescript

NgStream / Чат
👍7🔥4
Forwarded from katsuba.dev
Команда Angular официально предложила сделать OnPush дефолтом для компонентов! Это значит, что лучший практический подход к Change Detection в Angular теперь будет включён по-умолчанию — никаких лишних настроек в каждом компоненте. Это огромный шаг к ещё более предсказуемому и быстрому взаимодействию UI и данных.

https://github.com/angular/angular/discussions/66779
🍾5👍4🔥1
Команда Angular в последнем релизе все же представила новый вид селекторов. Точнее, selectorless подход. Эта функциональность не просто перешла в stable режим, но и была установлена как режим по умолчанию.

Суть подхода в обращении к классу компонента напрямую, минуя использование строковых селекторов, которые задаются в свойстве selector.


На мой взгляд, изменение вида селекторов - весьма спорное нововведение по нескольким причинам.

🛠 Несоответствие стандарту HTML. Как я понимаю, selectorless раньше не внедряли специально для следования стандарту. Спецификация определяет void-элементы (например, <img>, <br>), которые не могут иметь содержимого и не требуют закрывающего тега (но в конце ставят /> , например: <img />). Поэтому формально для соответствия стандарту HTML именно Angular берет на себя задачу превращения этих инструкций в валидные DOM элементы с открывающими и закрывающими тегами. Однако, если вы попытаетесь использовать такой синтаксис напрямую в html файле без предварительной компиляции (например, через innerHTML в браузере), парсер браузера может интерпретировать это неверно, так как по стандарту HTML пользовательские элементы (custom elements) обязательно должны иметь закрывающий тег и не могут быть void-элементами.

🛠 Медленная адаптация в enterprise. Многие пользователи Angular это крупные компании и обычно изменения внедряются постепенно. Поскольку плюсы не видны (по крайней мере пока что), то просто так переписывать код не очень разумно.

🛠 Сложнее поиск компонента в дереве селекторов в devtools и в коде, если использовать имя компонента.

🛠 Самое интересное, зачем текущий html-like синтаксис превращать в JSX? (кто не знает, в Angular не html, а чуть другой формат) Мы привыкаем ко всему, но это определенно делает Angular непривычным и никаких причин для внедрения, кроме "modern Angular code", я не нашел в тексте МР.

#angular

NgStream / Чат
👍7🤔2👎1