Нововведения и ожидания Angular 20
Уже на 29 мая (четверг) в 19:00 MSK анонсирован Angular Developer Event.
🌵 Следующие фичи изменили статус на stable:
🛠 Помечены как deprecated:
*
Добавлена поддержка оператора in в шаблонах. Его работа аналогична
Интересно, что в 19 версии была добавлена поддержка
И в конце ссылка на Angular CanIUse. А чего ждете вы от предстоящего релиза?
#angular
NgStream / Чат
Уже на 29 мая (четверг) в 19:00 MSK анонсирован Angular Developer Event.
🌵 Следующие фичи изменили статус на stable:
linkedSignal, withI18nSupport, PendingTasks, afterEveryRender*, afterNextRender, toSignal, toObservable, withIncrementalHydration.🛠 Помечены как deprecated:
ngIf, ngFor, ngSwitch, HammerJS integration, platformServerTesting, ServerTestingModule.*
afterRender переименован в afterEveryRender. Предназначен для выполнения кода после рендеринга всех компонентов на странице.Добавлена поддержка оператора in в шаблонах. Его работа аналогична
in в TS. Проверка, что свойство есть в объекте (не значение свойства). {{ 'name' in user }}
@if ('name' in user) {}
[disabled]="'name' in user"Интересно, что в 19 версии была добавлена поддержка
typeof в шаблоне, в 20 оператор in. Получается, что команда решила постепенно сокращать расстояние между TS и Angular.И в конце ссылка на Angular CanIUse. А чего ждете вы от предстоящего релиза?
#angular
NgStream / Чат
❤🔥5👍2
В 20 версии
📌 computed - сигнал, который рассчитывает своё значение на основе зависимых сигналов. Представьте себе реактивную формулу, которая всегда синхронизирована со своими зависимостями.
Основные особенности:
- Readonly: Вы не можете изменить значение.
- Lazily evaluated: Срабатывает при обращении к нему.
- Memoized: Значение закэшировано, пока зависимость не изменится.
- Dynamic dependencies: Отслеживает только то, что необходимо для выполнения.
📌 linkedSignal - writable сигнал, связывает сигналы, обновляет состояние, в зависимости от значений, но сохраняет возможность ручных изменений.
- Writable. Может быть обновлён вручную
- Reactive. Автоматически обновляется на основе переданных сигналов
- Access to previous values. Доступ к предыдущему значению, полезно для продвинутых механизмов синхронизации состояния.
- No memoization. Всегда рассчитывается повторно, кеш отсутствует.
Здесь
Можно привязать состояние пагинации к строке поиска, обеспечивая синхронный и предсказуемый сброс. Здесь гарантируется, что сброс пагинации произойдет тогда, когда действительно изменится строка ввода.
И коротко добавлю еще:
📌 effect - выполняется асинхронно, планируется и разрешается фреймворком, поэтому конкретное время для выполнения не определено. Предназначен для side-effects, например, для логирования, выполнения API запросов. Не для обновления других сигналов, это может привести с цикличным перерасчетам.
📌 untracked - позволяет сделать сигнал неотслеживаемым внутри определённого контекста выполнения. То есть даже если сигнал меняется, контекст всё равно не будет уведомляться, однако будет иметь доступ к актуальному значению. Может быть использован для изменения состояния сигнала внутри
#angular
NgStream / Чат
linkedSignal() станет stable. Поэтому сегодня посмотрим его отличия от computed().📌 computed - сигнал, который рассчитывает своё значение на основе зависимых сигналов. Представьте себе реактивную формулу, которая всегда синхронизирована со своими зависимостями.
Основные особенности:
- Readonly: Вы не можете изменить значение.
- Lazily evaluated: Срабатывает при обращении к нему.
- Memoized: Значение закэшировано, пока зависимость не изменится.
- Dynamic dependencies: Отслеживает только то, что необходимо для выполнения.
📌 linkedSignal - writable сигнал, связывает сигналы, обновляет состояние, в зависимости от значений, но сохраняет возможность ручных изменений.
listOfItems = signal(['item1', 'item2', 'item3']);
countOfItems = linkedSignal(() => this.listOfItems().length);
- Writable. Может быть обновлён вручную
.set() или .update().- Reactive. Автоматически обновляется на основе переданных сигналов
- Access to previous values. Доступ к предыдущему значению, полезно для продвинутых механизмов синхронизации состояния.
- No memoization. Всегда рассчитывается повторно, кеш отсутствует.
// Можем сделать вот так
changeTheCountOfItems() {
this.countOfItems.set(0);
}
// Есть еще одна форма записи
const countOfItems = linkedSignal({
source: this.listOfItems,
computation: (items) => items.length,
});
Здесь
linkedSignal принимает ссылку на сигнал, и, когда значение изменится, вызовется computation функция. Пример, где пригодилась бы эта функция, есть здесь, можно ознакомиться подробнее. Покажу более простой. Можно привязать состояние пагинации к строке поиска, обеспечивая синхронный и предсказуемый сброс. Здесь гарантируется, что сброс пагинации произойдет тогда, когда действительно изменится строка ввода.
const search = signal('');
const page = linkedSignal({
source: search,
computation: () => 1,
});linkedSignal хорошо использовать для синхронных обновлений состояния.И коротко добавлю еще:
📌 effect - выполняется асинхронно, планируется и разрешается фреймворком, поэтому конкретное время для выполнения не определено. Предназначен для side-effects, например, для логирования, выполнения API запросов. Не для обновления других сигналов, это может привести с цикличным перерасчетам.
📌 untracked - позволяет сделать сигнал неотслеживаемым внутри определённого контекста выполнения. То есть даже если сигнал меняется, контекст всё равно не будет уведомляться, однако будет иметь доступ к актуальному значению. Может быть использован для изменения состояния сигнала внутри
effect(), но делать это не рекомендуется.#angular
NgStream / Чат
🔥6🤪2👍1
Microsoft анонсировала TypeScript Native Previews. Это история, которую они сообщили в марте о портировании компилятора на Go.
Теперь команда разработчиков говорит о промежуточных результатах, в частности, за счет быстрой работы Go и использования параллельных вычислений существенно возросла скорость инкрементальной сборки и IntelliSense.
Попробовать можно уже сейчас:
Позже планируют заменить tsgo на tsc и эта реализация станет стандартом, заменяя текущую Node.js-реализацию.
Мне кажется, что VS Code получит самый большой буст, особенно с автокомплитом, потому что идет работа над улучшением language server, переходу с TSServer на LSP. Обещают в этом году показать более полную версию, включая улучшенную работу в редакторах. Первые сборки будут после релиза 7 версии.
#typescript
NgStream / Чат
Теперь команда разработчиков говорит о промежуточных результатах, в частности, за счет быстрой работы Go и использования параллельных вычислений существенно возросла скорость инкрементальной сборки и IntelliSense.
Попробовать можно уже сейчас:
npm install -D @typescript/native-preview
// Включить нативный режим в VS Code "typescript.tsserver.useNativeWatcher": true
npx tsgo --project ./src/tsconfig.json
Позже планируют заменить tsgo на tsc и эта реализация станет стандартом, заменяя текущую Node.js-реализацию.
Мне кажется, что VS Code получит самый большой буст, особенно с автокомплитом, потому что идет работа над улучшением language server, переходу с TSServer на LSP. Обещают в этом году показать более полную версию, включая улучшенную работу в редакторах. Первые сборки будут после релиза 7 версии.
#typescript
NgStream / Чат
❤🔥2👍2
Как замерить developer experience для разработчиков
Некоторое время назад решил сформулировать, как замерить DX? На основе каких параметров мы можем, насколько это возможно точно сделать замеры.
Опросы и обратная связь для получения объективной картины?🤔 Может быть весьма сомнительно. Вопросы касательно удобства инструментов, документации, скорости развертывания, на мой взгляд, не покажут картину целиком, ну или составить будет весьма сложно.
Команда DevOps Research and Assessment (DORA) из Google Cloud придумали 4 главные метрики разработки. Если коротко, это термометр, который показывает, где всё 🔥, а где ещё можно подкрутить.
📌 Lead Time for Changes (LTFC): Время от внесения изменения в код до релиза.
📌 Deployment Frequency (DF): Как часто релизим.
📌 Mean Time to Restore (MTTR): Среднее время восстановления системы после сбоя.
📌 Change Failure Rate (CFR): Количество багов на релиз.
Эти метрики помогают оценить зрелость и эффективность DevOps практик в команде. Недавно добавили еще одну Reliability, но это лежит в плоскости operational excellence.
Так в чем связь?
1. Улучшение LTFC. При работе в среде с отличным DX, можно быстрее внедрять изменения, благодаря настроенным инструментам и процессам. Это сокращает LTFC, т.к. вы разработатываете приложение, а не тратите время на настройку окружения и борьбу с инфраструктурой.
2. Частота развертываний (DF). Если мы уверены в способности быстро и надежно релизить, частота развертываний увеличивается (кэп). Автотесты, стабильный CI/CD и понятная дока уменьшают страх перед изменениями и позволяют команде/компании чаще выпускать новые фичи. Если еще и работаете по TBD, с фича-флагами, то вообще песня:)
3. Быстрое восстановление (MTTR). Для этого необходимо наличие инструментов мониторинга и диагностики, чтобы быстрее выявлять и устранять инциденты. Описанные процессы по устранению и реагированию тоже дадут плюс. Но это можно отнести к пункту про хорошую документацию.
4. Низкий CFR. Автотесты, тщательная проверка кода и ясность процессов минимизируют риски ошибок.
Метрики подобраны таким образом, чтобы их было сложно накрутить, т.е., по сути, каждая команда вынуждена искать какое-то оптимальное значение для себя. Например, если без изменения процессов просто начать релизить каждый коммит в продакшен, то deployment frequency увеличится. Супер, мы улучшили метрику! Но без хорошо построенных процессов тестирования, скорее всего, сильно просядет change fail rate.
У ребят много интересных материалов:
- Тест, насколько команда перформит круче других.
- Подробнее о метриках
- Как влиять на каждую из метрик.
#нетехзаметки
NgStream / Чат
Некоторое время назад решил сформулировать, как замерить DX? На основе каких параметров мы можем, насколько это возможно точно сделать замеры.
Опросы и обратная связь для получения объективной картины?🤔 Может быть весьма сомнительно. Вопросы касательно удобства инструментов, документации, скорости развертывания, на мой взгляд, не покажут картину целиком, ну или составить будет весьма сложно.
Команда DevOps Research and Assessment (DORA) из Google Cloud придумали 4 главные метрики разработки. Если коротко, это термометр, который показывает, где всё 🔥, а где ещё можно подкрутить.
📌 Lead Time for Changes (LTFC): Время от внесения изменения в код до релиза.
📌 Deployment Frequency (DF): Как часто релизим.
📌 Mean Time to Restore (MTTR): Среднее время восстановления системы после сбоя.
📌 Change Failure Rate (CFR): Количество багов на релиз.
Эти метрики помогают оценить зрелость и эффективность DevOps практик в команде. Недавно добавили еще одну Reliability, но это лежит в плоскости operational excellence.
Так в чем связь?
1. Улучшение LTFC. При работе в среде с отличным DX, можно быстрее внедрять изменения, благодаря настроенным инструментам и процессам. Это сокращает LTFC, т.к. вы разработатываете приложение, а не тратите время на настройку окружения и борьбу с инфраструктурой.
2. Частота развертываний (DF). Если мы уверены в способности быстро и надежно релизить, частота развертываний увеличивается (кэп). Автотесты, стабильный CI/CD и понятная дока уменьшают страх перед изменениями и позволяют команде/компании чаще выпускать новые фичи. Если еще и работаете по TBD, с фича-флагами, то вообще песня:)
3. Быстрое восстановление (MTTR). Для этого необходимо наличие инструментов мониторинга и диагностики, чтобы быстрее выявлять и устранять инциденты. Описанные процессы по устранению и реагированию тоже дадут плюс. Но это можно отнести к пункту про хорошую документацию.
4. Низкий CFR. Автотесты, тщательная проверка кода и ясность процессов минимизируют риски ошибок.
Метрики подобраны таким образом, чтобы их было сложно накрутить, т.е., по сути, каждая команда вынуждена искать какое-то оптимальное значение для себя. Например, если без изменения процессов просто начать релизить каждый коммит в продакшен, то deployment frequency увеличится. Супер, мы улучшили метрику! Но без хорошо построенных процессов тестирования, скорее всего, сильно просядет change fail rate.
У ребят много интересных материалов:
- Тест, насколько команда перформит круче других.
- Подробнее о метриках
- Как влиять на каждую из метрик.
#нетехзаметки
NgStream / Чат
👏2👍1
На прошлой неделе представили Angular 20
Я заработался и только на выходных познакомился с обновлением. Поэтому кратко для тех, кто еще не в курсе изменений.
📌 На презентации много говорили об
📌 SSR. Incremental Hydration в статусе stable. Очень мощный инструмент, позволяющий через Control flow задавать логику для гидрации элемента на странице. Ниже пример с
📌 Динамическое создание компонентов. Функция
📌 Добавлена возможность использовать:
- оператор in в шаблоне
- untagged template literals. Что особенно удобно для кастомизации и работы с классами.
📌 Помечены как deprecated:
📌 Обновили генерацию элементов через CLI после изменений в style guide. Теперь при создании нового проекта не будут добавляться суффиксы для компонентов, директив, pipes и сервисов. Для существующих проектов генерация будет включена в
📌 Добавили инструменты и примеры для интеграции AI. Теперь можно легко подключать LLM, такие как Gemini, OpenAI, Anthropic и другие для создания функций вроде чата, генерации текстов, анализа изображений, рекомендаций и т.д.
📌 Также добавили, что стоит двигаться в сторону zoneless приложений. Через пару версий, мне кажется, сделают stable. А пока стоит провести предварительную работу, если еще не сделали. А именно, перевести компоненты на OnPush, уходить от модулей (по крайней мере, новые части кода писать на standalone). Кто не знал, zone.js довольная тяжеловесная библиотека и отказ от нее положительно повлияет на бандл приложения.
📌 Кроме того, проверка производительности будет доступна в chrome dev tools, не нужно скачивать дополнительные расширения! Достаточно обновиться на 20 версию и Chrome 136, вызвать в консоли
Ну, и на десерт, говорилось о выборе маскотов, показали немного упоротые варианты.😆 В официальном анонсе по ссылке посмотрите, если еще не видели:)
#angular
NgStream / Чат
Я заработался и только на выходных познакомился с обновлением. Поэтому кратко для тех, кто еще не в курсе изменений.
📌 На презентации много говорили об
httpResource. Это, по сути, обертка над httpClient, но с сигналами. Еще в experimental, поэтому пока не рекомендуется к использованию.📌 SSR. Incremental Hydration в статусе stable. Очень мощный инструмент, позволяющий через Control flow задавать логику для гидрации элемента на странице. Ниже пример с
defer, а в разделе на сайте написано подробнее.@defer (hydrate on <<trigger>>) {
<deferred-component />
} 📌 Динамическое создание компонентов. Функция
createComponent позволяет делать это с меньшим количеством действий. В параметрах указывается сам компонент, привычные input/output, даже директивы.createComponent(MyDialog, {
bindings: [
// Bind a signal to the `canClose` input.
inputBinding('canClose', canClose),
outputBinding<Result>('onClose', result => {}),
twoWayBinding('title', title),
],
directives: [
FocusTrap,
{
type: HasColor,
bindings: [inputBinding('color', () => 'red')]
}
]
});📌 Добавлена возможность использовать:
- оператор in в шаблоне
- untagged template literals. Что особенно удобно для кастомизации и работы с классами.
<div [class]="`layout col-${colWidth}`"></div>📌 Помечены как deprecated:
ngIf, ngFor, ngSwitch, HammerJS integration, platformServerTesting, ServerTestingModule.📌 Обновили генерацию элементов через CLI после изменений в style guide. Теперь при создании нового проекта не будут добавляться суффиксы для компонентов, директив, pipes и сервисов. Для существующих проектов генерация будет включена в
angular.json.📌 Добавили инструменты и примеры для интеграции AI. Теперь можно легко подключать LLM, такие как Gemini, OpenAI, Anthropic и другие для создания функций вроде чата, генерации текстов, анализа изображений, рекомендаций и т.д.
📌 Также добавили, что стоит двигаться в сторону zoneless приложений. Через пару версий, мне кажется, сделают stable. А пока стоит провести предварительную работу, если еще не сделали. А именно, перевести компоненты на OnPush, уходить от модулей (по крайней мере, новые части кода писать на standalone). Кто не знал, zone.js довольная тяжеловесная библиотека и отказ от нее положительно повлияет на бандл приложения.
📌 Кроме того, проверка производительности будет доступна в chrome dev tools, не нужно скачивать дополнительные расширения! Достаточно обновиться на 20 версию и Chrome 136, вызвать в консоли
ng.enableProfiling().Ну, и на десерт, говорилось о выборе маскотов, показали немного упоротые варианты.😆 В официальном анонсе по ссылке посмотрите, если еще не видели:)
#angular
NgStream / Чат
👍3👏1
В недавнем обновлении Angular были представлены async redirects. И я пропустил этот пункт мимо ушей. Поэтому сегодня коротко о том, что этот апдейт нам дает. Возможно, многие, как и я, тоже пропустили строку в changelogs...
Мы привыкли в массиве
Теперь редирект может происходить позже, как только
Довольно полезное нововведение, поскольку зачастую нужно ждать асинхронного выполнения/дополнить какой-либо бизнес логикой и затем уже принимать решение о редиректе. В общем, защита от набрасывания собственных велосипедов в приложении.
#angular
NgStream / Чат
Мы привыкли в массиве
Routes передавать примерно следующий конфиг, в котором есть два способа указания редиректа: с помощью строки или синхронной функции, которая может возвращать строку или UrlTree.export const routes: Routes = [
{
path: 'user',
// redirectTo: '/cock',
redirectTo: () => '/cock',
pathMatch: 'full'
}
];
Теперь редирект может происходить позже, как только
Promise/Observable вернет значение.Довольно полезное нововведение, поскольку зачастую нужно ждать асинхронного выполнения/дополнить какой-либо бизнес логикой и затем уже принимать решение о редиректе. В общем, защита от набрасывания собственных велосипедов в приложении.
#angular
NgStream / Чат
👍7
Сегодня в обществе слова токсичный и требовательный часто подменяют, используют как синонимы. Однако эти понятия принципиально разные: одно разрушает взаимоотношения, а другое может способствовать росту. Разберёмся, где проходит граница.
Требовательный человек ставит высокие требования к себе и своим сотрудникам, коллегам, но при этом старается давать обратную связь (лучше корректирующую. Об этом расскажу в отдельной заметке.) При этом без перехода на личности, что важно, и не вызывая чувство вины. Такой коллега/руководитель/ментор объясняет, что не так и предлагает пути улучшения. Причем фокусируется на результате и оценивает не только ошибки, но и успехи.
Токсичный человек тоже может многого требовать, но конструктивной коммуникации от него не дождешься. «Всё плохо, переделывай» и не объясняет как. В этом случае, когда на тебя "наезжают", как тебе кажется без причины (а это может быть не так и недочеты могут быть), хочется стукнуть, а не слушать. И в итоге плохо всем.
Почему их путают? Потому что и в том, и в другом случае человек требует, критикует, проявляет строгость. Присутствует субъективность восприятия. Требовательный человек может казаться «токсичным», если его слова звучат резко или если у твоего собеседника травматичный опыт.
Важно стараться услышать друг друга и уметь давать/принимать обратную связь.
#нетехзаметки
NgStream / Чат
Требовательный человек ставит высокие требования к себе и своим сотрудникам, коллегам, но при этом старается давать обратную связь (лучше корректирующую. Об этом расскажу в отдельной заметке.) При этом без перехода на личности, что важно, и не вызывая чувство вины. Такой коллега/руководитель/ментор объясняет, что не так и предлагает пути улучшения. Причем фокусируется на результате и оценивает не только ошибки, но и успехи.
Токсичный человек тоже может многого требовать, но конструктивной коммуникации от него не дождешься. «Всё плохо, переделывай» и не объясняет как. В этом случае, когда на тебя "наезжают", как тебе кажется без причины (а это может быть не так и недочеты могут быть), хочется стукнуть, а не слушать. И в итоге плохо всем.
Почему их путают? Потому что и в том, и в другом случае человек требует, критикует, проявляет строгость. Присутствует субъективность восприятия. Требовательный человек может казаться «токсичным», если его слова звучат резко или если у твоего собеседника травматичный опыт.
Важно стараться услышать друг друга и уметь давать/принимать обратную связь.
#нетехзаметки
NgStream / Чат
👍6❤🔥1
Недавно Selectel Team поделился популярными постами/темами из моего канала, а теперь — я делюсь интересным контентом из канала нашей компании
В канале много полезного контента. Особенно я бы порекомендовал ознакомиться с лекцией Вячеслава Дубынина, нейробиолога, преподавателя МГУ о стрессе и работе с ним. Мне пригодились знания о том, как возникает стресс, какой вообще бывает и как с ним работать! Выступление очень познавательное и все рассказано простым языком!
А также в канале можно встретить анонсы митапов по тимлидству, как внутренние, так и внешние. Из последнего, крайне рекомендую посмотреть о ZBP(Zero Bug Policy), бирюзовых компаниях(это где не нужны менеджеры, а решает самоуправление команд. О реальности же происходящего было выступление). И на десерт, о том, должны ли разработчики погружаться в продуктовый контекст.
Как вы видите, контент весьма разнообразен. В общем подписывайтесь, кто хочет быть в курсе митапов и новостей!)
В канале много полезного контента. Особенно я бы порекомендовал ознакомиться с лекцией Вячеслава Дубынина, нейробиолога, преподавателя МГУ о стрессе и работе с ним. Мне пригодились знания о том, как возникает стресс, какой вообще бывает и как с ним работать! Выступление очень познавательное и все рассказано простым языком!
А также в канале можно встретить анонсы митапов по тимлидству, как внутренние, так и внешние. Из последнего, крайне рекомендую посмотреть о ZBP(Zero Bug Policy), бирюзовых компаниях(это где не нужны менеджеры, а решает самоуправление команд. О реальности же происходящего было выступление). И на десерт, о том, должны ли разработчики погружаться в продуктовый контекст.
Как вы видите, контент весьма разнообразен. В общем подписывайтесь, кто хочет быть в курсе митапов и новостей!)
👍4❤🔥1❤1🔥1
В дополнение к посту об уже добавленных async redirects. Команда планирует добавить пару довольно полезных фичей в Angular Router 🎉.
Первое это добавление поддержки
И второе добавление injection context для
На данный момент некоторые разработчики используют workaround по обращению к injection context в
Существенное улучшение DX на подходе!🎉
#angular
NgStream / Чат
Первое это добавление поддержки
canDeactivateChild, о котором просили лет 9 назад. MR с ссылкой на issue.И второе добавление injection context для
loadComponent/loadChildren callback, что является решением архитектурных ограничений. На практике означает, что мы сможем инжектить сервисы напрямую в функцию загрузки, динамически подгружать необходимые компоненты, опираясь, например, на состояние в сервисе, на работу с фича флагами/на основе ролевой модели приложения. В общем, возможность реализовать кастомную логику загрузки и не писать велосипеды. Да, подчеркну это и здесь!На данный момент некоторые разработчики используют workaround по обращению к injection context в
loadChildren, который был предложен Игорем Кацубой. И ссылка на feature request, с которым можно ознакомиться более детально.Существенное улучшение DX на подходе!🎉
#angular
NgStream / Чат
🔥6
Небольшая новость. Со следующей версии Angular в тестах можно будет использовать input bindings. Пару недель назад влили МР, добавляющий данную функциональность для TestBed.
Теперь при вызове
Честно говоря, я думал, что такое уже есть. Дело в том, что уже длительное время пользуюсь spectator, где этот вопрос решается через
Метод изменяет значение
Очень удобно. Есть и минусы с тем, что получаем разные подходы при написании, одни делают через
А какие инструменты для написания тестов используете вы? Если пишете, конечно;) Как решаете вопрос с тестированием input, output?
#angular
NgStream / Чат
Теперь при вызове
TestBed.createComponent можно указать input, который хотели протестировать. Это избавляет от необходимости фигачить wrappers для каждого компонента. Кроме того, сохраняется консистентность между тестами.Честно говоря, я думал, что такое уже есть. Дело в том, что уже длительное время пользуюсь spectator, где этот вопрос решается через
spectator.setInput().it('should...', () => {
spectator.setInput('className', 'link');
...
});Метод изменяет значение
@Input() и вызывает хук ngOnChanges(). Очень удобно. Есть и минусы с тем, что получаем разные подходы при написании, одни делают через
TestBed, другие с Spectator. Вызовы перемешиваются и выглядит не очень. Еще и не всегда могут корректно взаимодействовать друг с другом. Но это другая история.А какие инструменты для написания тестов используете вы? Если пишете, конечно;) Как решаете вопрос с тестированием input, output?
#angular
NgStream / Чат
👍4🔥3
Премия Тьюринга
В этом году Andrew Barto и Richard Sutton получили премию за вклад в развитие обучения с подкреплением(RL). Эти ученые заложили основы технологии, используемой в Google DeepMind, системах для обнаружения мошенничества, разработке алгоритмов для автономных машин. Их исследования позволили создать модели, которые обучаются на основе проб и ошибок.
Премия Тьюринга - это аналог Нобелевской премии в нашей индустрии. Награду вручает АСМ за фундаментальные открытия в Computer Science. Спонсирует Google. Считаю важным рассказать о некоторых открытиях и именах, изменивших индустрию!
1966 Алан Перлис - награжден за подходы к разработке компиляторов. Благодаря ему мы делаем платформонезависимые языки, описывая их формальными грамматиками. "Языки должны быть понятны и людям, и ЭВМ, хороший язык - не только инструмент, но и средство общения."
1968, Ричард Хэмминг - за способ кодирования, который позволяет исправлять ошибки при передаче данных. Сеть, hdd, ram используют коды Хэмминга по сей день.
1972, Эдсгер Дейкстра - за фундаментальный вклад в разработку структурного программирования. Критика использования оператора GOTO, популяризация концепции "слабого связывания". Заложил основы написания чистого и поддерживаемого кода.
1973, Чарльз Бахман - за разработку концепции сетевых баз данных и создание Integrated Data Store (IDS), первой промышленной СУБД в истории. Его мысли приведут нас к sql и orm, но позже.
1974, Дональд Кнут. Его труд "Искусство программирования" знают многие. Изощряй ум алгоритмами, но помни: "Преждевременная оптимизация ‐ корень всех зол".
1976, Майкл Рабин и Дана Скотт. Введение концепции недетерминированных конечных автоматов (NFA) и доказательство его эквивалентности детерминированному. Основа для современных регулярных выражений, алгоритмов поиска и верификации ПО.
1977, Джон Бэкус. Введение BNF-нотации для описания синтаксиса языков. Автор языка Фортран – первый массовый ЯП высокого уровня, используется до сих пор, а очередная версия вышла в 2023.
Данные работы заложили фундамент всей современной computer science — от компиляторов до искусственного интеллекта. Без этих открытий не существовало бы Google, блокчейна, OpenAI или даже обычных мобильных приложений.
Это первый из серии постов об исторических личностях, повлиявших на нашу индустрию.
#людиЦелиДостижения
NgStream / Чат
В этом году Andrew Barto и Richard Sutton получили премию за вклад в развитие обучения с подкреплением(RL). Эти ученые заложили основы технологии, используемой в Google DeepMind, системах для обнаружения мошенничества, разработке алгоритмов для автономных машин. Их исследования позволили создать модели, которые обучаются на основе проб и ошибок.
Премия Тьюринга - это аналог Нобелевской премии в нашей индустрии. Награду вручает АСМ за фундаментальные открытия в Computer Science. Спонсирует Google. Считаю важным рассказать о некоторых открытиях и именах, изменивших индустрию!
1966 Алан Перлис - награжден за подходы к разработке компиляторов. Благодаря ему мы делаем платформонезависимые языки, описывая их формальными грамматиками. "Языки должны быть понятны и людям, и ЭВМ, хороший язык - не только инструмент, но и средство общения."
1968, Ричард Хэмминг - за способ кодирования, который позволяет исправлять ошибки при передаче данных. Сеть, hdd, ram используют коды Хэмминга по сей день.
1972, Эдсгер Дейкстра - за фундаментальный вклад в разработку структурного программирования. Критика использования оператора GOTO, популяризация концепции "слабого связывания". Заложил основы написания чистого и поддерживаемого кода.
1973, Чарльз Бахман - за разработку концепции сетевых баз данных и создание Integrated Data Store (IDS), первой промышленной СУБД в истории. Его мысли приведут нас к sql и orm, но позже.
1974, Дональд Кнут. Его труд "Искусство программирования" знают многие. Изощряй ум алгоритмами, но помни: "Преждевременная оптимизация ‐ корень всех зол".
1976, Майкл Рабин и Дана Скотт. Введение концепции недетерминированных конечных автоматов (NFA) и доказательство его эквивалентности детерминированному. Основа для современных регулярных выражений, алгоритмов поиска и верификации ПО.
1977, Джон Бэкус. Введение BNF-нотации для описания синтаксиса языков. Автор языка Фортран – первый массовый ЯП высокого уровня, используется до сих пор, а очередная версия вышла в 2023.
Данные работы заложили фундамент всей современной computer science — от компиляторов до искусственного интеллекта. Без этих открытий не существовало бы Google, блокчейна, OpenAI или даже обычных мобильных приложений.
Это первый из серии постов об исторических личностях, повлиявших на нашу индустрию.
#людиЦелиДостижения
NgStream / Чат
www.acm.org
Andrew Barto and Richard Sutton are the recipients of the 2024 ACM A.M. Turing Award for developing the conceptual and algorithmic…
In a series of papers beginning in the 1980s, Barto and Sutton introduced the main ideas, constructed the mathematical foundations, and developed important algorithms for reinforcement learning—one of the most important approaches for creating intelligent…
❤3🔥1
Обновления инструментов разработчика
🛠 В 20 версии было заявлено об улучшении DevTools и внутреннем партнерстве с Chrome. И, как результат, добавили Angular - Custom track в разделе Performance. С ним проще отслеживать рендеринг компонентов, CD, обработку событий. Раньше приходилось переключаться между DevTools и браузерными инструментами, что усложняло анализ.
Для включения надо обновиться и вызвать в консоли
В Angular - Custom track (performance) показываются данные, которых нет в Angular DevTools (Это немного разное, не путаться!). Например, создание провайдеров. В доку в раздел best-practices также добавили раздел c пояснениями.
🛠 А в 20.1 дополнят DevTools инструментом Signal graph. Он будет доступен в experimental режиме. Для работы с ним переходим в Angular DevTools, Settings, выбираем компонент в дереве и справа "Show Signal Graph".
Какие улучшения сможем увидеть? В первую очередь, взаимосвязь между сигналами, разновидности используемых в компоненте сигналов (signal(), computed(), linkedSignal(), effect()). По клику на каждый можно перейти в код, просмотреть имя, значение, тип и epoch - сколько раз было изменено значение.
Для отслеживания изменений неплохо, но хотелось бы вручную изменять значения в самом инструменте. Фичу, конечно, планируют улучшать. В любом случае хорошо, что есть движение в сторону развития DevTools.
#angular
NgStream / Чат
🛠 В 20 версии было заявлено об улучшении DevTools и внутреннем партнерстве с Chrome. И, как результат, добавили Angular - Custom track в разделе Performance. С ним проще отслеживать рендеринг компонентов, CD, обработку событий. Раньше приходилось переключаться между DevTools и браузерными инструментами, что усложняло анализ.
Для включения надо обновиться и вызвать в консоли
ng.enableProfiling();В Angular - Custom track (performance) показываются данные, которых нет в Angular DevTools (Это немного разное, не путаться!). Например, создание провайдеров. В доку в раздел best-practices также добавили раздел c пояснениями.
🛠 А в 20.1 дополнят DevTools инструментом Signal graph. Он будет доступен в experimental режиме. Для работы с ним переходим в Angular DevTools, Settings, выбираем компонент в дереве и справа "Show Signal Graph".
Какие улучшения сможем увидеть? В первую очередь, взаимосвязь между сигналами, разновидности используемых в компоненте сигналов (signal(), computed(), linkedSignal(), effect()). По клику на каждый можно перейти в код, просмотреть имя, значение, тип и epoch - сколько раз было изменено значение.
Для отслеживания изменений неплохо, но хотелось бы вручную изменять значения в самом инструменте. Фичу, конечно, планируют улучшать. В любом случае хорошо, что есть движение в сторону развития DevTools.
#angular
NgStream / Чат
👍9
Signal-based формы - заметки команды
Те, кто уже вовсю использует сигналы в приложениях, задались вопросом, как удобно, просто и без костылей взаимодействовать с формами. Я на неделе решил посмотреть, что команда angular готовит с сигнальными формами. Для желающих ознакомиться подробнее - прикрепляю ссылку. Отмечу, что все это еще очень ранний прототип и многое могут изменить. Поэтому кратко хочу отметить основные отличия.
📌 Как я понял, ключевой принцип в том, что форма не будет хранить данные внутри - они будут храниться в модели, а форма, по сути, обертка для удобной работы с хранением статуса, валидацией и тд. Единый источник правды - модель. Изменения идут через форму, а она меняет модель.
📌 Форма это дерево из объектов
📌 Следующее отличие - отсутствие
📌 Декларативное определение логики полей через
📌
📌 Для кросс-валидации предполагается обращаться к другим полям либо в родительской схеме, либо использовать
📌 Заменой асинхронным валидаторам являются функции
📌 Синхронизация состояния. Для связи модели и шаблона используется директива
Вывод: интересные мысли и немногословный, декларативный, типобезопасный подход с использованием всех преимуществ сигналов. Но пока ничего не сказано о миграции и почти ничего об интерфейсе
#angular #signal_forms
NgStream / Чат
Те, кто уже вовсю использует сигналы в приложениях, задались вопросом, как удобно, просто и без костылей взаимодействовать с формами. Я на неделе решил посмотреть, что команда angular готовит с сигнальными формами. Для желающих ознакомиться подробнее - прикрепляю ссылку. Отмечу, что все это еще очень ранний прототип и многое могут изменить. Поэтому кратко хочу отметить основные отличия.
📌 Как я понял, ключевой принцип в том, что форма не будет хранить данные внутри - они будут храниться в модели, а форма, по сути, обертка для удобной работы с хранением статуса, валидацией и тд. Единый источник правды - модель. Изменения идут через форму, а она меняет модель.
📌 Форма это дерево из объектов
Field, которые хранят состояние. Для получения состояния обращаемся к инстансу Field. Он возвращает FieldState, который хранит value, errors, disabled и т.д. Каждый из них это сигнал, который не устанавливается напрямую, а возвращает значение, исходя из логики, которая описана через Schema.// Create a model containing the initial form data.
userModel = signal<User>({name: '', username: ''});
// Create the form, linking it to the model.
userForm = form(this.userModel);
📌 Следующее отличие - отсутствие
FormArray. Т.к. форма это, грубо говоря, ссылка на модель данных, взаимодействие будет с обычными массивами модели.model = signal<Order>({
...
items: [
{ description: 'item', quantity: 1 },
]
});
orderForm: Field<Order> = form(this.model);
itemsField = this.orderForm.items;📌 Декларативное определение логики полей через
Schema. Это набор правил - функций: валидаторов, условий для установки disabled, required, error и тд. Schema выполняется единожды при создании формы и предназначена для определения структуры логики полей и вычислений.const userSchema = schema((path) => {
disabled(path.username, () => true, 'Username cannot be changed');
required(path.name);
error(path.age, ({value}) => value() < 18, 'Must be 18 or older');
});
userForm = form(this.user, userSchema);📌
valueChanges заменен на computed(), effect() и прочие signal API.📌 Для кросс-валидации предполагается обращаться к другим полям либо в родительской схеме, либо использовать
valueOf(). Также можно делать композицию правил валидации, объединяя логику из нескольких схем, используя apply() или applyEach() для работы с элементами массива. А applyWhen() / applyWhenValue() для добавления логики вокруг контролов. Подразумевается, что это более удобный и декларативный вариант, заменяющий if (…) { addControl() }.📌 Заменой асинхронным валидаторам являются функции
validateHttp()/validateAsync(), вызываемые в "схеме". Во время валидации срабатывает встроенный pending state.validateHttp(name, {
request: () => `/api/check?${name}`,
errors: (data) => {
if (data === 'OK') return [];
return [{kind: 'error', message: data}];
}
});📌 Синхронизация состояния. Для связи модели и шаблона используется директива
[control]. Она обеспечивает "two-way binding" между состоянием элемента формы (value, disabled, touched, aria-attributes) и UI.Вывод: интересные мысли и немногословный, декларативный, типобезопасный подход с использованием всех преимуществ сигналов. Но пока ничего не сказано о миграции и почти ничего об интерфейсе
ControlValueAccesssor.#angular #signal_forms
NgStream / Чат
🔥14
В следующей версии (20.2) Zoneless стратегия перейдет из developer preview в статус stable! Соответствующий МР был опубликован. Это означает, что Zone.js больше не будет участвовать в механизме обнаружения изменений. С использованием сигналов получится добиться наилучшей производительности. По крайней мере, так заявляют разработчики Angular team.
📌 Несмотря на всю свою мощь, Zone.js - это архитектурный компромисс, который дает удобство в обмен на свободу и производительность. Из недостатков:
- расходы на постоянный перехват асинхронных операций. Проверки происходят чаще, чем необходимо.
- увеличенный размер бандла. И, как следствие, большее время запуска приложения.
- совместимость с экосистемой. Некоторые функции, например,
📌 Изменение принципа работы
В новом подходе ввели понятие Local Change Detection. Если при OnPush стратегии при изменениях в компоненте флагом помечается часть дерева view от текущего до верхнего, а изменения идут от root сверху вниз, то с использованием Signal API используются новые флаги:
При генерации новых приложений через schematic по умолчанию будет исключена зависимость Zone. Но не забываем об enterprise решениях, которые могут быть завязаны на сторонние либы с zone внутри. Получается, обновление будет не для всех… Или нет?
📌 Миграция
1. Первоначальная задача, в этом случае, сделать аудит зависимостей, выделив части, которые полагаются в расчетах на Zone и поэтапно переписать. Для них решением будет создание оберток. Обертка - компонент, с
2. Подготовка команды. Разработчики должны уметь работать с новой парадигмой. Любителям использовать
Миграция требует экспертизы, но окупается за счёт снижения затрат на поддержку и погашение технического долга. И успешный переход возможен только при наличии заинтересованной команды и стратегического взгляда на развитие проекта.
Гайд по Zoneless
#angular
NgStream / Чат
📌 Несмотря на всю свою мощь, Zone.js - это архитектурный компромисс, который дает удобство в обмен на свободу и производительность. Из недостатков:
- расходы на постоянный перехват асинхронных операций. Проверки происходят чаще, чем необходимо.
- увеличенный размер бандла. И, как следствие, большее время запуска приложения.
- совместимость с экосистемой. Некоторые функции, например,
async/await не могут быть эффективно пропатчены и требуют дополнительных преобразований. Неявная связь между любым setTimeout и CD.📌 Изменение принципа работы
В новом подходе ввели понятие Local Change Detection. Если при OnPush стратегии при изменениях в компоненте флагом помечается часть дерева view от текущего до верхнего, а изменения идут от root сверху вниз, то с использованием Signal API используются новые флаги:
RefreshView и HasChildViewsToRefresh. Компонент, в котором изменился сигнал, помечается RefreshView, а все его родительские флагом HasChildViewsToRefresh. В этом случае будет проверен и обновлен только компонент с RefreshView, а все остальные будут пропущены.При генерации новых приложений через schematic по умолчанию будет исключена зависимость Zone. Но не забываем об enterprise решениях, которые могут быть завязаны на сторонние либы с zone внутри. Получается, обновление будет не для всех… Или нет?
📌 Миграция
1. Первоначальная задача, в этом случае, сделать аудит зависимостей, выделив части, которые полагаются в расчетах на Zone и поэтапно переписать. Для них решением будет создание оберток. Обертка - компонент, с
input() для передачи данных. Внутри обертки прослушиваем события библиотеки и вручную отслеживаем изменения.2. Подготовка команды. Разработчики должны уметь работать с новой парадигмой. Любителям использовать
Promise и addEventListener, вместо реактивного подхода, придется отказаться и все же перейти на Signal API и RxJS.Миграция требует экспертизы, но окупается за счёт снижения затрат на поддержку и погашение технического долга. И успешный переход возможен только при наличии заинтересованной команды и стратегического взгляда на развитие проекта.
Гайд по Zoneless
#angular
NgStream / Чат
🔥8❤1❤🔥1🎉1🍓1
В прошлом месяце Evan You анонсировал выход rolldown-vite. Это пакет, который призван в будущем заменить текущий сборщик vite(на основе Rollup и esbuild).
В чем суть?
Rolldown — новый Rust-сборщик для Vite, входит в Oxc (JavaScript Oxidation Compiler, набор инструментов для JS/TS, включающий парсер, линтер и минификатор). Обещают значительное ускорение сборки в 3–16 раз и снижение потребления памяти до 100 раз. Что-то довольно оптимистичные заявления😅
📌 Т.к. все преобразования и минификация теперь выполняются через Oxc, это устраняет зависимость от esbuild (если только её не требуют плагины).
📌 Я заметил, что переход довольно простой - "drop-in replacement", достаточно заменить пакет vite на rolldown-vite в package.json и все. Сейчас его можно попробовать на своих пет-проектах.
📌 Из минусов пока отметил бы:
- Совместимость: еще не все плагины протестированы и могут потребовать доработок.
- Стабильность: форк пока еще в бете, для использования в нормальном проекте стоит подождать Phase 2, когда rolldown-vite перейдет в статус stable и будет объединен с основной кодовой базой).
- Кривая обучения: если кастомизировали сборку Vite, возможно, придётся адаптировать конфиги.
Возможно, где-то ошибаюсь, т.к. ковырять плагины не приходилось. Если есть что сказать, welcome в комментарии)
Что касается Angular, то CLI с 16 версии перешел на esbuild-based систему сборки. Мы получили поддержку Vite - для dev режима, esbuild для dev и prod сборки. Как мне кажется, есть вероятность, что в будущем мы можем получить еще более улучшенную по времени и по памяти сборку, если все-таки rolldown-vite заменит основной сборщик.
#js #angular
NgStream / Чат
В чем суть?
Rolldown — новый Rust-сборщик для Vite, входит в Oxc (JavaScript Oxidation Compiler, набор инструментов для JS/TS, включающий парсер, линтер и минификатор). Обещают значительное ускорение сборки в 3–16 раз и снижение потребления памяти до 100 раз. Что-то довольно оптимистичные заявления😅
📌 Т.к. все преобразования и минификация теперь выполняются через Oxc, это устраняет зависимость от esbuild (если только её не требуют плагины).
📌 Я заметил, что переход довольно простой - "drop-in replacement", достаточно заменить пакет vite на rolldown-vite в package.json и все. Сейчас его можно попробовать на своих пет-проектах.
📌 Из минусов пока отметил бы:
- Совместимость: еще не все плагины протестированы и могут потребовать доработок.
- Стабильность: форк пока еще в бете, для использования в нормальном проекте стоит подождать Phase 2, когда rolldown-vite перейдет в статус stable и будет объединен с основной кодовой базой).
- Кривая обучения: если кастомизировали сборку Vite, возможно, придётся адаптировать конфиги.
Возможно, где-то ошибаюсь, т.к. ковырять плагины не приходилось. Если есть что сказать, welcome в комментарии)
Что касается Angular, то CLI с 16 версии перешел на esbuild-based систему сборки. Мы получили поддержку Vite - для dev режима, esbuild для dev и prod сборки. Как мне кажется, есть вероятность, что в будущем мы можем получить еще более улучшенную по времени и по памяти сборку, если все-таки rolldown-vite заменит основной сборщик.
#js #angular
NgStream / Чат
👍3
И дополнение темы сборки. Команда Angular влила МР, заявив о переходе на Rolldown вместо Rollup, что позволит оптимизировать работу сборщика и будет плюсом при загрузке приложения, т.к. потребуется загружать меньше chunks.
При этом фича пока что в статусе experimental и находится под флагом, соответственно, не будет использоваться по умолчанию для всех проектов.
#angular
NgStream / Чат
При этом фича пока что в статусе experimental и находится под флагом, соответственно, не будет использоваться по умолчанию для всех проектов.
#angular
NgStream / Чат
👍5🔥1
Deep signals
Еще одно нововведение сигналов планируется к внедрению командой Angular! Посмотрим недавно опубликованный draft.
Сравним с другими сигналами:
📌 computed
- Автоматически вычисляет значение на основе родительских сигналов.
- Запрещены ручные изменения.
📌 linkedSignal
- Значение берется от родителя ИЛИ задается вручную.
- Меняет только локальное значение, не изменяя родительский сигнал.
📌 deepSignal
- Чтение и запись родительского сигнала. Но только указанного свойства!
Производительность
Если представить структуру графа, то изменение сигнала на верхнем уровне приведёт к изменению всех зависимых сигналов.
Оба сигнала еще в статусе draft и реализация, соответственно, может измениться. Предположу, что это будет дополнением к прототипу, в котором команда Angular описывала будущее сигнальных форм. Я делал заметки по документу здесь.
Как мы видим, набор инструментов, на котором могут быть сделаны сигнальные формы, дополняется. Для желающих ознакомиться подробнее - прикреплена ссылка выше.
#angular
NgStream / Чат
Еще одно нововведение сигналов планируется к внедрению командой Angular! Посмотрим недавно опубликованный draft.
deepSignal - это WritableSignal, который отслеживает значение только указанного свойства из родительского сигнала. Если перезаписать значение, то оно обновится в родительском сигнале. Сочетает вывод значения и обновление значения в родителе, что отлично подходит для работы с иерархической структурой.const model = signal({user: {name: 'Alex'}, company: 'Google'});
const user = deepSignal(model, 'user');
console.log(user()); // {name: 'Alex'}
// Updating `user` updates the parent.
user.set({name: 'Bob'});
console.log(model()); // {user: {name: 'Bob'}, company: 'Google'}Сравним с другими сигналами:
📌 computed
- Автоматически вычисляет значение на основе родительских сигналов.
- Запрещены ручные изменения.
📌 linkedSignal
- Значение берется от родителя ИЛИ задается вручную.
- Меняет только локальное значение, не изменяя родительский сигнал.
📌 deepSignal
- Чтение и запись родительского сигнала. Но только указанного свойства!
Производительность
Если представить структуру графа, то изменение сигнала на верхнем уровне приведёт к изменению всех зависимых сигналов.
deepSignal решают эту проблему, используя информацию о том, какое именно свойство изменяется в родительском значении. Кроме того, на основе deepSignal появилась возможность конструировать еще один тип сигналов.structuralSignal - это «ленивая» версия computed, которая не реагирует на точечные изменения (свойств) в deepSignal. А реагирует только на полную замену значения родителя.const addressForm = deepSignal({ street: 'Цветочная', city: 'SPB' });
const formChanges = structuralSignal(addressForm);
addressForm.set(v => { v.street = 'Московский' });
addressForm.set({ street: 'Садовая', city: 'RND' });Оба сигнала еще в статусе draft и реализация, соответственно, может измениться. Предположу, что это будет дополнением к прототипу, в котором команда Angular описывала будущее сигнальных форм. Я делал заметки по документу здесь.
Как мы видим, набор инструментов, на котором могут быть сделаны сигнальные формы, дополняется. Для желающих ознакомиться подробнее - прикреплена ссылка выше.
#angular
NgStream / Чат
👍5🤪3🤔1
Давайте поговорим еще об одном инструменте из TypeScript:
Это вывод типов (
Для примера определим массив и через
Сейчас тип это массив объектов с полями
В этом случае мы говорим вывести все свойства объекта, доступ к которым осуществляется через numeric key.
Важно задекларировать исходный массив
Пример использования:
Прикрепляю ссылку с примерами использования deriving types.
#typescript
NgStream / Чат
T[number]. Это вывод типов (
derived types) с использованием indexed access types. Данный подход может пригодиться для объявления типа вместо enum. О минусах работы с ним я писал здесь. Для примера определим массив и через
typeof получим тип.const possibleResponses = [
{
status: 200,
body: 'Success',
},
{
status: 404,
body: 'Not found',
},
];
type Responses = typeof possibleResponses;
// type Responses = { status: number, body: string }[];
Сейчас тип это массив объектов с полями
status,body. Попробуем убрать массив из типа и получить тип самого объекта. Применим решение с T[number].type Responses = possibleResponses[number];
В этом случае мы говорим вывести все свойства объекта, доступ к которым осуществляется через numeric key.
Важно задекларировать исходный массив
as const, что заставит вывести буквальные значения массива. Иначе TS извлечет тип string[]. Пример использования:
const roles = ['admin', 'editor'] as const;
type RolesType = typeof roles;
type Role = RolesType[number];
// type Role = 'admin' | 'editor';
Прикрепляю ссылку с примерами использования deriving types.
#typescript
NgStream / Чат
❤5🤔1
Новости предстоящего обновления
📌 В версии 20.2 появится возможность указывать алиас
Вы можете заметить некоторые пересечения с использованием в шаблоне директивы
В чем же разница?
-
-
📌 Свойство
Это изменение улучшает консистентность с системой реактивности Angular и делает состояние роутера более удобным для работы в реактивном контексте. Кроме того, такой подход более декларативный и нет необходимости в ручной подписке на изменения.
Ожидаем обновлений с переходом остальных элементов Router на сигналы!
📌 Разработчики улучшили вывод типов при работе с событиями DOM. Т.к. тип
Теперь для
Ссылка на МР.
#angular
NgStream / Чат
📌 В версии 20.2 появится возможность указывать алиас
as в блоке else if, что немного упростит чтение кода. Соответствующий МР появился на прошлой неделе.@if (template) {
template 1
} @else if (loaderTemplate(); as state) {
<skeleton [loading]="state.loading">
}Вы можете заметить некоторые пересечения с использованием в шаблоне директивы
@let, добавленной пару версий назад. Если посмотреть на CanIUse, то статус stable с 18.2. Но сходство заметно только на первый взгляд.В чем же разница?
-
@let позволяет задать полученное значение на более широкий контекст. Например, на весь шаблон.-
as все-таки предназначен для случаев, когда значение требуется только в одном блоке. В общем, у него меньше зона покрытия. Эту идею стоит учитывать при выборе инструмента.📌 Свойство
lastSuccessfulNavigation из Router API станет сигналом.// 20.1
const navigation = this.router.lastSuccessfulNavigation;
// 20.2
const navigation = this.router.lastSuccessfulNavigation();
Это изменение улучшает консистентность с системой реактивности Angular и делает состояние роутера более удобным для работы в реактивном контексте. Кроме того, такой подход более декларативный и нет необходимости в ручной подписке на изменения.
Ожидаем обновлений с переходом остальных элементов Router на сигналы!
📌 Разработчики улучшили вывод типов при работе с событиями DOM. Т.к. тип
EventTarget | null слишком общий, он доставляет некоторые неудобства при обработке и получении value c input. При этом не всегда возможно сделать cast типов (as HTMLInputElement). Например, в шаблоне.Теперь для
void элементов, например, <input>, <img>, <br>, где всплытие невозможно, тип $event.target будет определяться автоматически. Это уменьшит количество ошибок TypeScript и не будет необходимости писать лишние проверки.Ссылка на МР.
#angular
NgStream / Чат
🔥9❤1
Новости signal-based forms
Команда Angular обновила прототип сигнальных форм, перетащила в отдельный пакет
Насколько я понял, на данном этапе пакет не будет доступен (нет package.json) и он с пометкой, что дизайн API еще в разработке и может измениться. МР с кодом, большим количеством тестов и документацией можно посмотреть по ссылке.
Как и в заметках, показанных ранее для ознакомления, подчеркиваются основные идеи:
📌 Формы состоят из 4 основных блоков:
📌 Ключевой принцип в том, что форма не хранит данные внутри. По сути, это ссылка на модель. Единый источник правды хранится в
📌 Как и с другими сигналами,
Заметки команды, показанные ранее, я разбирал в канале. Тогда в них не было ничего сказано об интерфейсе
🛠 Сейчас в коде я нашел класс, обеспечивающий interop. Отмечено, что это заглушка
🛠 Директива
В общем, видно, что переход на сигналы еще активно разрабатывается и полная картина, включая миграцию проекта с Reactive/Template форм, пока не совсем ясна. Ждем обновлений!
#angular #signal_forms
NgStream / Чат
Команда Angular обновила прототип сигнальных форм, перетащила в отдельный пакет
@angular/forms/signals и планирует влить в master.Насколько я понял, на данном этапе пакет не будет доступен (нет package.json) и он с пометкой, что дизайн API еще в разработке и может измениться. МР с кодом, большим количеством тестов и документацией можно посмотреть по ссылке.
Как и в заметках, показанных ранее для ознакомления, подчеркиваются основные идеи:
📌 Формы состоят из 4 основных блоков:
Data Model, Field State, Field Logic, UI Controls.📌 Ключевой принцип в том, что форма не хранит данные внутри. По сути, это ссылка на модель. Единый источник правды хранится в
WritableSignal. При обновлении модели обновляется сигнал в форме и, наоборот, при обновлении формы обновится модель.userModel = signal<User>({name: '', username: ''});
userForm = form(this.userModel);📌 Как и с другими сигналами,
form() требуется объявлять в injection context или передав ссылку на контекст.private readonly injector = inject(Injector);
...
const form = form(this.userModel, {injector: this.injector});
Заметки команды, показанные ранее, я разбирал в канале. Тогда в них не было ничего сказано об интерфейсе
ControlValueAccessor. 🛠 Сейчас в коде я нашел класс, обеспечивающий interop. Отмечено, что это заглушка
NgControl для обеспечения совместимости с текущей версией контролов. Он реализует только часто используемые свойства и методы настоящего NgControl. Этот класс используется, например, в директиве [control].🛠 Директива
[control] связывает поле формы (FieldState) и шаблон (UI), обеспечивая двустороннюю привязку данных и состояние формы. Из описания видно, что она может работать с CVA, но только в режиме совместимости для реактивных форм и стоит предпочесть сигнальный FormValueControl, нативный html элемент. Получается, что для сигнальных форм необходимости в CVA не будет, а для разработки собственных контролов предполагается реализовывать интерфейс FormValueControl. А NgControl, скорее всего, будет помечен, как deprecated через какое-то время после релиза.В общем, видно, что переход на сигналы еще активно разрабатывается и полная картина, включая миграцию проекта с Reactive/Template форм, пока не совсем ясна. Ждем обновлений!
#angular #signal_forms
NgStream / Чат
🔥8❤2❤🔥1👍1
В ESLint 9.34.0 будет доступен многопоточный линтинг
📌 По заявлениям команды ожидается прирост примерно в 1.5 - 3 раза для крупных проектов. Добиться ускорения получилось за счёт использования механизма worker threads из Node.js API.
📌 Ранее, задачи, которые больше всего нагружали CPU - парсинг AST дерева, работа сложных правил, выполнялись в одном потоке Event Loop, что могло приводить к его блокировке. Теперь main thread становится менеджером - он создает пул worker threads, управляет задачами, перенаправляя их в другие потоки и агрегирует данные.
📌 Основная проблема была в том, что worker threads обмениваются данными с главным потоком через механизм structured clone, что не позволяло передать довольно сложную конфигурацию, включающую кастомные правила, инстансы плагинов и тд. Решить этот вопрос позволяют Options Modules. Вместо передачи конфига каждый worker клонирует его и работает с независимой копией.
📌 Также было ограничение с обработкой только одного файла, теперь появилась возможность параллельного выполнения.
📌 На примере показано объявление ECMAScript модуля и создание инстанса через
📌 Команда предупреждает, что еще возможны баги с некоторыми конфигами/плагинами, их будут фиксить. Кроме того, пока остается проблема для случаев, когда правил слишком много или у них долгая инициализация. В своей заметке еще делятся советами по настройке и использованию, ознакомиться можно по ссылке.
NgStream / Чат
📌 По заявлениям команды ожидается прирост примерно в 1.5 - 3 раза для крупных проектов. Добиться ускорения получилось за счёт использования механизма worker threads из Node.js API.
📌 Ранее, задачи, которые больше всего нагружали CPU - парсинг AST дерева, работа сложных правил, выполнялись в одном потоке Event Loop, что могло приводить к его блокировке. Теперь main thread становится менеджером - он создает пул worker threads, управляет задачами, перенаправляя их в другие потоки и агрегирует данные.
📌 Основная проблема была в том, что worker threads обмениваются данными с главным потоком через механизм structured clone, что не позволяло передать довольно сложную конфигурацию, включающую кастомные правила, инстансы плагинов и тд. Решить этот вопрос позволяют Options Modules. Вместо передачи конфига каждый worker клонирует его и работает с независимой копией.
📌 Также было ограничение с обработкой только одного файла, теперь появилась возможность параллельного выполнения.
📌 На примере показано объявление ECMAScript модуля и создание инстанса через
ESLint.fromOptionsModule(), передав в нее ссылку на конфиг.const configURL = new URL("./my-eslint.config.js", import.meta.url).href;
const optionsModuleText = `
import config from ${JSON.stringify(configURL)};
export default {
concurrency: "auto",
overrideConfig: config,
overrideConfigFile: true,
stats: true,
};
const optionsURL = new URL(`data:text/javascript,${encodeURIComponent(optionsModuleText)}`);
const eslint = await ESLint.fromOptionsModule(optionsURL);📌 Команда предупреждает, что еще возможны баги с некоторыми конфигами/плагинами, их будут фиксить. Кроме того, пока остается проблема для случаев, когда правил слишком много или у них долгая инициализация. В своей заметке еще делятся советами по настройке и использованию, ознакомиться можно по ссылке.
NgStream / Чат
🔥12🤔2