Обновление безопасности (CSP)
Только сейчас узнал, что еще было добавлено в новой версии! Теперь Angular автоматически будет генерировать hash-based CSP, реализуя строгую политику безопасности. Необходимо добавить параметр в angular.json:
Hash-based CSP позволяет указывать хеши для каждого встроенного скрипта, что делает их безопасными для выполнения. Это означает, что только скрипты с известными хешами будут выполняться, и злоумышленники не смогут внедрить свой код без соответствующего хеша.
Сегодня вместо того, чтобы предоставлять список разрешений, из которого можно загружать скрипты, рекомендуется использовать строгий CSP, который бывает двух видов: nonce-based и hash-based. Первый требует генерации уникального идентификатора для каждого ответа, CSP на основе хэша - идеальный выбор для статически обслуживаемого контента без рендеринга на стороне сервера (SSR).
Подписывайся / Чат
#angular #js
Только сейчас узнал, что еще было добавлено в новой версии! Теперь Angular автоматически будет генерировать hash-based CSP, реализуя строгую политику безопасности. Необходимо добавить параметр в angular.json:
"security": {
"autoCSP": true
}Hash-based CSP позволяет указывать хеши для каждого встроенного скрипта, что делает их безопасными для выполнения. Это означает, что только скрипты с известными хешами будут выполняться, и злоумышленники не смогут внедрить свой код без соответствующего хеша.
Сегодня вместо того, чтобы предоставлять список разрешений, из которого можно загружать скрипты, рекомендуется использовать строгий CSP, который бывает двух видов: nonce-based и hash-based. Первый требует генерации уникального идентификатора для каждого ответа, CSP на основе хэша - идеальный выбор для статически обслуживаемого контента без рендеринга на стороне сервера (SSR).
Подписывайся / Чат
#angular #js
👍5🔥3
Я решил написать о типах, которые могут помочь в определенной ситуации и позволят не городить лишние велосипеды. Уверен, что многие из подписчиков знают об этом, но не все. А, если у вас есть, что дополнить, особенно преимущества/недостатки, пишите в комментах!
В примере выше тип
Преимущества:
1. Удобство и безопасность: автоматическое извлечение типа возвращаемого значения функции снижает вероятность ошибок и повышает читаемость кода.
2. Сокращение дублирования: не нужно вручную повторять тип возвращаемого значения, что облегчает рефакторинг и поддержку кода.
Есть и очевидный недостаток. Если функция не экспортируется/не видима, воспользоваться типом не получится.
Следующий тип -
Раньше это вызвало бы ошибку, т.к. тип
Что мы получаем? Точность типизации, что особенно полезно в сложных сценариях с generic типами.
В примере выше
#typescript
Подписывайся / Чат
ReturnType<T> — это Utility Type, который извлекает тип из возвращаемого значения любой функции. Может понадобится при работе с библиотекой, которая не экспортирует типы, но которые нам нужны. Другой пример: написание своей утилиты. Ну или какие-либо трудноизвлекаемые типы.// type Message = Message.TextMessage;
type Message = ReturnType<typeof bot.telegram.sendMessage>
async function getMessage() {
const res = await bot.telegram.sendMessage('Text');
}
В примере выше тип
Message будет точным типом, который используется в либе.Преимущества:
1. Удобство и безопасность: автоматическое извлечение типа возвращаемого значения функции снижает вероятность ошибок и повышает читаемость кода.
2. Сокращение дублирования: не нужно вручную повторять тип возвращаемого значения, что облегчает рефакторинг и поддержку кода.
Есть и очевидный недостаток. Если функция не экспортируется/не видима, воспользоваться типом не получится.
Следующий тип -
NoInfer<T> был добавлен относительно недавно - в TS 5.5. Нужен для вывода типов без сравнения с внутренними типами. Покажу на примере.const list = [1, 2, 3, undefined];
list
.filter((item) => item !== undefined)
.map((item) => {
...
item.toString();
})
Раньше это вызвало бы ошибку, т.к. тип
item в map() был number | undefined, не смотря на то, что в этой части кода undefined уже быть не может. В новых версиях данный пример отработает даже без каких-либо действий с нашей стороны. Параметр функции map() уже выведен корректно. Что мы получаем? Точность типизации, что особенно полезно в сложных сценариях с generic типами.
function createFSM<TState extends string>(config: {
initial: TState;
states: TState[];
}): TState;
const example = createFSM({
initial: "not-allowed",
states: ["open", "closed"],
});В примере выше
TState складывается из возможных значений initial и states: "not-allowed" | "open"| "closed". Но, если мы хотим, чтобы тип initial был взят только из допустимых значений states? В этом случае сработает добавление initial: NoInfer<TState>; Теперь "not-allowed" будет указан, как ошибочный, поскольку не находится в наборе допустимых. Добавляя тип, мы сможем контролировать набор значений, которые TS извлечет из generic типа. Здесь статья с подробными примерами.#typescript
Подписывайся / Чат
🔥3❤1
Active zone
Новая статья от Саши Инкина - разбор нетривиальной задачи и решения. На первый взгляд, что сложного в управлении кнопкой с выпадающим меню? Однако, по мере реализации, выясняется множество деталей, о которых и пойдет речь.
- Практические примеры из Taiga UI.
- Детальный разбор решения и пограничных случаев.
Подробности - по ссылке.
Подписывайся / Чат
#angular
Новая статья от Саши Инкина - разбор нетривиальной задачи и решения. На первый взгляд, что сложного в управлении кнопкой с выпадающим меню? Однако, по мере реализации, выясняется множество деталей, о которых и пойдет речь.
- Практические примеры из Taiga UI.
- Детальный разбор решения и пограничных случаев.
Подробности - по ссылке.
Подписывайся / Чат
#angular
Хабр
Самая сложная директива Taiga UI
Часто необходимо знать, с какой областью страницы взаимодействует пользователь. Например, если вы создаете выпадающее меню, нужно понять, когда его закрывать. Наивная реализация будет просто слушать...
👍1
JS Import Attributes
Не так давно данный пропозал был включен в стандарт EcmaScript.
В чем суть?
Раньше, при импорте модулей, JS не предоставлял возможности явного указания типа загружаемого ресурса. Это создавало проблемы безопасности и функциональности. Например, можно было случайно или намеренно загрузить файл, как JS модуль, хотя на самом деле это был JSON и т.д. Что в результате могло привести к выполнению нежелательного кода. Может показаться очевидным, что файл, заканчивающийся на .js, будет соответствовать файлу
Import Attributes (ранее назывался Import Assertions) позволяет явно указать тип модуля. Если что-то пойдет не так, то вернется ошибка.
Ниже пример использования с импортом JSON. Без
Если вы помечаете модуль типом:
Преимущества
📌 Безопасность: Предотвращение выполнения некорректного кода.
📌 Явное указание. Повышает читаемость кода. Вне зависимости от контекста считаю плюсом.
📌 Расширяемость: Возможность поддержки новых типов ресурсов в будущем.
Ссылка на детали пропозала.
Подписывайся / Чат
#js
Не так давно данный пропозал был включен в стандарт EcmaScript.
В чем суть?
Раньше, при импорте модулей, JS не предоставлял возможности явного указания типа загружаемого ресурса. Это создавало проблемы безопасности и функциональности. Например, можно было случайно или намеренно загрузить файл, как JS модуль, хотя на самом деле это был JSON и т.д. Что в результате могло привести к выполнению нежелательного кода. Может показаться очевидным, что файл, заканчивающийся на .js, будет соответствовать файлу
application/javascript. На практике в вебе широко распространено несоответствие между расширением файла и заголовком HTTP Content Type. Здесь описано более детально, можете ознакомиться. Import Attributes (ранее назывался Import Assertions) позволяет явно указать тип модуля. Если что-то пойдет не так, то вернется ошибка.
Ниже пример использования с импортом JSON. Без
with { type: 'json' } файл мог быть интерпретирован как JS, что привело бы к ошибкам. А теперь есть некий контракт между вашим кодом и runtime. Вы явно объявляете, какой тип модуля вы ожидаете:import json from './data.json' with { type: 'json' };
console.log(json);Если вы помечаете модуль типом:
json, вы гарантированно получите либо данные JSON, либо ошибку, но не исполняемый код. Преимущества
📌 Безопасность: Предотвращение выполнения некорректного кода.
📌 Явное указание. Повышает читаемость кода. Вне зависимости от контекста считаю плюсом.
📌 Расширяемость: Возможность поддержки новых типов ресурсов в будущем.
Ссылка на детали пропозала.
Подписывайся / Чат
#js
👍4🔥4
Разница SRI и CSP
Недавно писал об улучшении политики безопасности CSP в Angular. И в комментариях получилось обсуждение о его отличиях с SRI. Вот решил чуть подробнее раскрыть тему и лучше разобраться самому.
Subresource Integrity (SRI) – механизм проверки целостности контента при загрузке с сервера. Он позволяет убедиться, что файл не был изменен во время передачи или хранения. Что особенно важно при использовании CDN или других сервисов для загрузки JS, CSS и другой статики.
Как работает SRI? При загрузке ресурса с использованием тега
Content Security Policy (CSP) – набор политик безопасности. Это указание браузеру, из каких источников загружать ресурсы (скрипты, шрифты и тд) и запрет на выполнение скриптов (unsafe-inline). CSP указывается в виде http-заголовка или мета-тега и состоит из различных директив, управляющих разрешениями для соответствующих ресурсов / функций браузера. Функции дополнялись в каждой версии, сейчас актуальной является 3. Пример политики CSP:
Например, директива connect-src ограничивает, с какими доменами можно устанавливать соединения. Это предотвращает утечку данных через расширения, которые пытаются получить доступ к данным.
Коротко о разнице:
SRI
- Используется для проверки целостности конкретных ресурсов.
- Работает на уровне отдельных ресурсов. Для каждого внешнего файла указывается хэш-сумма, которая проверяется браузером перед загрузкой.
- Применяется только к внешним ресурсам, загружаемым через теги <script> и <link>.
- Требует указания конкретной хэш-суммы для каждого ресурса, что делает его менее гибким при изменении содержимого файлов.
CSP
- Контролирует источники, откуда могут загружаться ресурсы и ограничивает тип контента для выполнения.
- Определяет общие правила для всех ресурсов страницы. Политики применяются ко всем ресурсам определенного типа (скрипты, стили и тд).
- Может применяться ко всему контенту страницы, включая внутренние и внешние ресурсы.
- Позволяет гибко настраивать политику безопасности, например, разрешать загрузку ресурсов с определенных доменов или запрещать определенные типы контента.
Оба инструмента эффективно дополняют друг друга, улучшая безопасность приложения. Механизмы снижают часть рисков и не являются достаточными. Например, CSP является дополнительным способом защиты от XSS, что было сказано в 2 версии спеки. Важно применять комплексный подход к защите и регулярно проводить аудит безопасности приложений.
Подписывайся / Чат
Недавно писал об улучшении политики безопасности CSP в Angular. И в комментариях получилось обсуждение о его отличиях с SRI. Вот решил чуть подробнее раскрыть тему и лучше разобраться самому.
Subresource Integrity (SRI) – механизм проверки целостности контента при загрузке с сервера. Он позволяет убедиться, что файл не был изменен во время передачи или хранения. Что особенно важно при использовании CDN или других сервисов для загрузки JS, CSS и другой статики.
Как работает SRI? При загрузке ресурса с использованием тега
<script> или <link>, указывается хэш-сумма файла в атрибуте integrity. Браузер вычисляет хэш загруженного файла и сравнивает с указанным значением. Если совпадают, ресурс считается безопасным и загружается; если нет – браузер блокирует загрузку. Пример использования SRI:<script src="https://cock.com/script.js"integrity="sha384-0aJk+WbYjC...WLWHLl" crossorigin="anonymous"></script>
Content Security Policy (CSP) – набор политик безопасности. Это указание браузеру, из каких источников загружать ресурсы (скрипты, шрифты и тд) и запрет на выполнение скриптов (unsafe-inline). CSP указывается в виде http-заголовка или мета-тега и состоит из различных директив, управляющих разрешениями для соответствующих ресурсов / функций браузера. Функции дополнялись в каждой версии, сейчас актуальной является 3. Пример политики CSP:
Content-Security-Policy: default-src 'self'; script-src 'self'; script-src-elem 'self'; style-src 'none'; img-src 'none'; connect-src 'self'; font-src 'none'; object-src 'none'; media-src 'none'; frame-src 'none'; child-src 'none'; form-action 'none'; worker-src 'none'; manifest-src 'none'; navigate-to 'none';
Например, директива connect-src ограничивает, с какими доменами можно устанавливать соединения. Это предотвращает утечку данных через расширения, которые пытаются получить доступ к данным.
Коротко о разнице:
SRI
- Используется для проверки целостности конкретных ресурсов.
- Работает на уровне отдельных ресурсов. Для каждого внешнего файла указывается хэш-сумма, которая проверяется браузером перед загрузкой.
- Применяется только к внешним ресурсам, загружаемым через теги <script> и <link>.
- Требует указания конкретной хэш-суммы для каждого ресурса, что делает его менее гибким при изменении содержимого файлов.
CSP
- Контролирует источники, откуда могут загружаться ресурсы и ограничивает тип контента для выполнения.
- Определяет общие правила для всех ресурсов страницы. Политики применяются ко всем ресурсам определенного типа (скрипты, стили и тд).
- Может применяться ко всему контенту страницы, включая внутренние и внешние ресурсы.
- Позволяет гибко настраивать политику безопасности, например, разрешать загрузку ресурсов с определенных доменов или запрещать определенные типы контента.
Оба инструмента эффективно дополняют друг друга, улучшая безопасность приложения. Механизмы снижают часть рисков и не являются достаточными. Например, CSP является дополнительным способом защиты от XSS, что было сказано в 2 версии спеки. Важно применять комплексный подход к защите и регулярно проводить аудит безопасности приложений.
Подписывайся / Чат
👍5
Немного слов о State of JS
По графикам прошедшего опроса можно увидеть, как возросли показатели Angular. Обновленная дока и увеличение числа обучающих материалов сделали его более доступным для новичков. Снижение порога входа, к которому стремились разработчики, существенно повлияло на показатели. Значительное улучшение удовлетворенности определенно благодаря сигналам и многому другому! Команда Angular уверенно идет к цели!
+12% retention
+5% usage
+5% positivity
Показатели все равно немного синтетические. На мой взгляд, опрос не отражает тренды всего сообщества, а показывает среднюю температуру..., поскольку срез делается по весьма небольшому количеству участников.
Что касается React, то он продолжает уверенно удерживать лидирующие позиции. Но отмечается потребность в более простых подходах, поскольку API стал более неоднозначным, особенно с его RSC.
А вот самым используемым и с высоким уровнем удовлетворенности стал Vite и Vitest соответственно. И неудивительно с его количеством интеграций в различные инструменты.
Посмотреть подробности, поиграть с фильтрами здесь.
Подписывайся / Чат
#js
По графикам прошедшего опроса можно увидеть, как возросли показатели Angular. Обновленная дока и увеличение числа обучающих материалов сделали его более доступным для новичков. Снижение порога входа, к которому стремились разработчики, существенно повлияло на показатели. Значительное улучшение удовлетворенности определенно благодаря сигналам и многому другому! Команда Angular уверенно идет к цели!
+12% retention
+5% usage
+5% positivity
Показатели все равно немного синтетические. На мой взгляд, опрос не отражает тренды всего сообщества, а показывает среднюю температуру..., поскольку срез делается по весьма небольшому количеству участников.
Что касается React, то он продолжает уверенно удерживать лидирующие позиции. Но отмечается потребность в более простых подходах, поскольку API стал более неоднозначным, особенно с его RSC.
А вот самым используемым и с высоким уровнем удовлетворенности стал Vite и Vitest соответственно. И неудивительно с его количеством интеграций в различные инструменты.
Посмотреть подробности, поиграть с фильтрами здесь.
Подписывайся / Чат
#js
🔥5
После принятого разработчиками Angular решения в 19 версии сделать компоненты standalone по умолчанию, продолжаем ждать, когда же ChangeDetection: OnPush стратегия будет также по умолчанию включена.🤔
Да, на любом проекте мы сразу добавляем в схематик свойство генерировать компоненты с такой стратегией, но все же этот выбор дается нам.
Особенно актуально с ребрендингом:
ChangeDetection >> Synchronization.
Подписывайся / Чат
#angular
Да, на любом проекте мы сразу добавляем в схематик свойство генерировать компоненты с такой стратегией, но все же этот выбор дается нам.
Особенно актуально с ребрендингом:
ChangeDetection >> Synchronization.
Подписывайся / Чат
#angular
👍6👏1
А мы возвращаемся и продолжаем стримить новости фронтенда! 🎉🎉🎉
Недавно вышла статья, повествующая о вариантах применения
Признаться, у меня в коде есть пример, похожий на этот из статьи. Это компонент, который выполняет четко определенную функцию и почти не имеет других зависимостей. В результате есть скрытая зависимость, сложности с тестированием. Радует, что это временное решение, которое было написано из-за ошибки с проектированием.
Советую ознакомиться, потому что важно знать, к каким потенциальным проблемам это может привести и разумно применять существующие подходы. База, как говорится:) Особенно, когда Angular стал предоставлять все больше случаев возможностей реализации для одного и того же.
#angular
Недавно вышла статья, повествующая о вариантах применения
inject(). И в каких случаях ваша реализация может быть реализацией антипаттерна Service Locator.Признаться, у меня в коде есть пример, похожий на этот из статьи. Это компонент, который выполняет четко определенную функцию и почти не имеет других зависимостей. В результате есть скрытая зависимость, сложности с тестированием. Радует, что это временное решение, которое было написано из-за ошибки с проектированием.
export class RiskyService {
private injector: Injector;
// This creates a hidden dependency outside of construction
performAction() {
runInInjectionContext(this.injector, () => {
// Service locator pattern: Looking up service on demand
const analyticsService = inject(AnalyticsService);
analyticsService.track(data);
});
}
}Советую ознакомиться, потому что важно знать, к каким потенциальным проблемам это может привести и разумно применять существующие подходы. База, как говорится:) Особенно, когда Angular стал предоставлять все больше случаев возможностей реализации для одного и того же.
#angular
riegler.fr
The inject function is not a service locator
Except when you make one of it
👍4
Input signals - production-ready
В 19 версии были добавлены схематики, позволяющие произвести миграцию
Сейчас команда Angular выпустила заметку в своем блоге, где говорит о переходе сигнальных Input в статус production-ready. Основная причина перехода - типобезопасность, которая позволит разработчикам, например, не писать лишний раз non-null assertions. И отказаться от
Заметка простая, но интересно, что команда намекает о необходимости перехода на новое API. Подчеркивается, что комбинация с
Сейчас как раз планирую взять задачу по тех долгу, в которой, помимо декомпозиции и прочего, реализовать функционал на новом API.👍🏻
#angular
В 19 версии были добавлены схематики, позволяющие произвести миграцию
Input на декораторах на сигнальные. О чем я писал в заметке.ng generate @angular/core:signal-input-migration
ng generate @angular/core:signal-queries-migration
Сейчас команда Angular выпустила заметку в своем блоге, где говорит о переходе сигнальных Input в статус production-ready. Основная причина перехода - типобезопасность, которая позволит разработчикам, например, не писать лишний раз non-null assertions. И отказаться от
ngOnChanges().Заметка простая, но интересно, что команда намекает о необходимости перехода на новое API. Подчеркивается, что комбинация с
computed() улучшит читаемость и тд. Сейчас как раз планирую взять задачу по тех долгу, в которой, помимо декомпозиции и прочего, реализовать функционал на новом API.👍🏻
#angular
👍2
Несовершенства TS
На неделе заметил интересный issue в репозитории Typescript. В нем обсуждается предложение добавить новый модификатор
Основная идея в том, чтобы позволить разработчикам указывать, что функция возвращает неизмененное и равное по ссылке значение, которое должно быть сужено до конкретного типа при каждом вызове (если бы это было простое значение, а не результат функции).
Если добавить чуть больше контекста для понимания, то автор обеспокоен тем, что сигналы нужно проверять на наличие
В комментариях весьма интересно, можно почитать здесь.
#typescript
Подписывайся / Чат
На неделе заметил интересный issue в репозитории Typescript. В нем обсуждается предложение добавить новый модификатор
identity для функций. Основная идея в том, чтобы позволить разработчикам указывать, что функция возвращает неизмененное и равное по ссылке значение, которое должно быть сужено до конкретного типа при каждом вызове (если бы это было простое значение, а не результат функции).
Если добавить чуть больше контекста для понимания, то автор обеспокоен тем, что сигналы нужно проверять на наличие
undefined, потому что TS не может нормально сузить тип, который возвращается в value(). А использование этого ключевого слова позволило бы избежать необходимости писать лишние проверки.declare const value: () => string | undefined;
if (value() !== undefined) {
console.log(value().toUpperCase()); // Ошибка компиляции
}
В комментариях весьма интересно, можно почитать здесь.
#typescript
Подписывайся / Чат
👍1
В коде часто замечаю, что разработчики предпочитают
-
- свойство
Преимущества
- Типобезопасность: предоставляет конкретный тип контрола, позволяя избегать необходимости уточнять тип (type assertion). В случае с
- Улучшенная работа language services: подсказки IDE работают более точно.
Интересно, насколько изменится API при переходе на сигнальные формы?🤔
#angular
Подписывайся / Чат
.get() для получения доступа к Form control. Я бы рекомендовал использовать более типо-безопасную альтернативу.FormGroup предоставляет 2 способа получения доступа к контролу (вдруг читают новички):-
get() - возвращает AbstractControl.- свойство
controls - возвращает конкретную реализацию AbstractControl - FormControl, FormGroup, FormRecord, FormArray.Преимущества
.controls перед .get():- Типобезопасность: предоставляет конкретный тип контрола, позволяя избегать необходимости уточнять тип (type assertion). В случае с
FormArray, сразу можно работать с методами массива.- Улучшенная работа language services: подсказки IDE работают более точно.
Интересно, насколько изменится API при переходе на сигнальные формы?🤔
#angular
Подписывайся / Чат
👍9
Полезное для Angular
После выхода 19 версии были добавлены предупреждения о неиспользуемых импортах, но удалять их приходилось вручную. Сейчас достаточно выполнить команду:
Но для этого придется обновиться на версию 19.1.
Что же, очередные бонусы от перехода на standalone components. Сокращаем размер бандла👍🏻
#angular
Подписывайся / Чат
После выхода 19 версии были добавлены предупреждения о неиспользуемых импортах, но удалять их приходилось вручную. Сейчас достаточно выполнить команду:
ng generate @angular/core:cleanup-unused-imports
Но для этого придется обновиться на версию 19.1.
Что же, очередные бонусы от перехода на standalone components. Сокращаем размер бандла👍🏻
#angular
Подписывайся / Чат
🔥8
Ресурсы и httpClient
Вы знаете, что в 19 версии был добавлен resource API. Это способ работы с запросами, работающий с Promise и интегрированный с сигналами.
Resource имеет тип
📌 конвертировать результат работы в
📌 отклонять предыдущий запрос, если значение сигнала изменилось. Семантика
Подробности можно прочитать по ссылке.
Я предполагал, что core команда предложит отдельный
На выходных увидел заметку с другими планами. В первом комментарии разработчики заявляют о работе над примитивом
Как я понял,
Пока что на уровне слухов, никакого RFC, которое может рассказать гораздо больше, от команды не было. Ждем обновлений!
#angular
Подписывайся / Чат
Вы знаете, что в 19 версии был добавлен resource API. Это способ работы с запросами, работающий с Promise и интегрированный с сигналами.
Resource имеет тип
Resource<T>, который включает сигналы для хранения текущего состояния. WritableResource расширяет Resource<T>, чтобы позволить преобразования resource через значение сигнала (двусторонняя привязка). Кроме того, API позволяет:📌 конвертировать результат работы в
Observable,📌 отклонять предыдущий запрос, если значение сигнала изменилось. Семантика
switchMap().Подробности можно прочитать по ссылке.
Я предполагал, что core команда предложит отдельный
httpClient , который будет предоставлять аналогичный api, но работать с сигналами и ресурсами. Условно, client.get() на промисах.На выходных увидел заметку с другими планами. В первом комментарии разработчики заявляют о работе над примитивом
httpResource, который основывается на текущем httpClient.Как я понял,
httpResource это замена rxResource + Angular Http Stack (включая interceptors) на базе httpClient. Пока что на уровне слухов, никакого RFC, которое может рассказать гораздо больше, от команды не было. Ждем обновлений!
#angular
Подписывайся / Чат
👍3🔥1
Преобразование CommonJS в ESM
Сначала стоит коротко сказать о форматах модулей.
AMD. Используются в браузерах, для определения модулей применяется функция
CommonJS. Предназначены для NodeJS и используют для определения зависимостей и модулей
Потом все скрипты стали использовать UMD формат. По сути, это заголовок, описывающий, как работать. Условно,
В 2015 году с выходом ES6 впервые появились ES модули.
Надеюсь, стало понятнее, как работают модули разного типа в JS. Сегодня в чистом виде их используют редко.
С переходом на ES Modules многие сталкиваются с необходимостью переписывания существующих библиотек и модулей.
ES Modules имеют ряд преимуществ:
1. Могут загружаться асинхронно, что улучшает производительность приложений.
2. Поддерживают статический анализ, что позволяет инструментам сборки быть более эффективными. Что происходит благодаря статической структуре импорта, где зависимости явно указаны в начале файла.
3. В ESM код автоматически работает в строгом режиме.
4. Поддержка браузерами напрямую.
5. Безопасная работа с циклическими зависимостями. Импортированные переменные инициализируются только после полной загрузки всех модулей.
Никита Ульянов в своей статье рассказал о форматах библиотек и в каких случаях и для каких сред применения какие форматы лучше использовать. Кроме того, автор рассказывает о создании типизированного API для библиотек, приводит рекомендуемые сетапы для разных случаев: браузер, серверная среда.
Если сейчас нет необходимости работать с модулями, статья может показаться сложной, но для общего представления стоит ознакомиться.
#js
Подписывайся / Чат
Сначала стоит коротко сказать о форматах модулей.
AMD. Используются в браузерах, для определения модулей применяется функция
define. При этом нода их не может импортировать. Строго говоря, AMD - это спецификация. RequireJS это непосредственно реализация AMD-спецификации.define(['f1', 'f2'], function (f1, f2) {
return function () {};
});CommonJS. Предназначены для NodeJS и используют для определения зависимостей и модулей
require и module.exports. Синхронные, использовать их в браузере нельзя, ведь это было бы странно, если бы при импорте jQuery мы ждали, пока он загрузится, блокируя инициализацию кода. Каждый файл, согласно спецификации, это отдельный модуль.var dep1 = require('./dep1');
var dep2 = require('./dep2');
module.exports = function(){}Потом все скрипты стали использовать UMD формат. По сути, это заголовок, описывающий, как работать. Условно,
if browser использовать AMD формат. if (typeofmodule === 'object' && module.exports) тогда используем CommonJS среду для работы с Node.В 2015 году с выходом ES6 впервые появились ES модули.
Надеюсь, стало понятнее, как работают модули разного типа в JS. Сегодня в чистом виде их используют редко.
С переходом на ES Modules многие сталкиваются с необходимостью переписывания существующих библиотек и модулей.
ES Modules имеют ряд преимуществ:
1. Могут загружаться асинхронно, что улучшает производительность приложений.
2. Поддерживают статический анализ, что позволяет инструментам сборки быть более эффективными. Что происходит благодаря статической структуре импорта, где зависимости явно указаны в начале файла.
3. В ESM код автоматически работает в строгом режиме.
4. Поддержка браузерами напрямую.
5. Безопасная работа с циклическими зависимостями. Импортированные переменные инициализируются только после полной загрузки всех модулей.
Никита Ульянов в своей статье рассказал о форматах библиотек и в каких случаях и для каких сред применения какие форматы лучше использовать. Кроме того, автор рассказывает о создании типизированного API для библиотек, приводит рекомендуемые сетапы для разных случаев: браузер, серверная среда.
Если сейчас нет необходимости работать с модулями, статья может показаться сложной, но для общего представления стоит ознакомиться.
#js
Подписывайся / Чат
❤2👍1
Полезное для Angular
Интерфейс NgZoneOptions включает в себя два параметра
Оказывается, параметры давно присутствуют в фреймворке. Просто лично мне не приходилось применять.
А вот с 18 версии первый из них включен по умолчанию
Event Coalescing - помогает уменьшить количество срабатываний механизма ChangeDetection, объединяя несколько событий и, повышая общую производительность приложения, особенно при частых взаимодействиях с пользователем, таких как клики, ввод текста и т.д. или асинхронных операциях.
В официальной доке приводят такой пример.
При срабатывании клика по кнопке, затем срабатывает клик по div элементу (event bubbling). ZoneJS перехватывает события, запускает CD, который срабатывает дважды. А с 19 версии, при включенном параметре, будет только один вызов механизма.
Run Coalescing - объединяет несколько запусков
#angular
Подписывайся / Чат
Интерфейс NgZoneOptions включает в себя два параметра
eventCoalescing и runCoalescing.Оказывается, параметры давно присутствуют в фреймворке. Просто лично мне не приходилось применять.
А вот с 18 версии первый из них включен по умолчанию
provideZoneChangeDetection({ eventCoalescing: true }) , поэтому тоже считаю важным об этом написать.Event Coalescing - помогает уменьшить количество срабатываний механизма ChangeDetection, объединяя несколько событий и, повышая общую производительность приложения, особенно при частых взаимодействиях с пользователем, таких как клики, ввод текста и т.д. или асинхронных операциях.
В официальной доке приводят такой пример.
<div (click)="doSomething()">
<button (click)="doSomethingElse()"></button>
</div>
При срабатывании клика по кнопке, затем срабатывает клик по div элементу (event bubbling). ZoneJS перехватывает события, запускает CD, который срабатывает дважды. А с 19 версии, при включенном параметре, будет только один вызов механизма.
Run Coalescing - объединяет несколько запусков
NgZone в один, что также оптимизирует процесс обнаружения изменений.#angular
Подписывайся / Чат
🔥6👍2
На MDN опубликовали статью о Temporal. Постоянные читатели канала могли заметить, что я не пропускаю новости о данном пропозале.
Кто не знает, это новый объект для работы с датой, который призван прийти на замену Date и решить большинство неудобств при работе с временем и часовыми поясами, конвертацией, нахождением разницы между датами и тд, продолжать можно долго. А пока можно поэкспериментировать и ознакомиться.
На странице пропозала на TC39 можно поиграться прямо в консоли, там включен полифилл.
А вот до полноценной поддержки браузерами далеко. Сейчас впереди всех Firefox, причем Nightly сборка.
#js
Подписывайся / Чат
Кто не знает, это новый объект для работы с датой, который призван прийти на замену Date и решить большинство неудобств при работе с временем и часовыми поясами, конвертацией, нахождением разницы между датами и тд, продолжать можно долго. А пока можно поэкспериментировать и ознакомиться.
На странице пропозала на TC39 можно поиграться прямо в консоли, там включен полифилл.
А вот до полноценной поддержки браузерами далеко. Сейчас впереди всех Firefox, причем Nightly сборка.
#js
Подписывайся / Чат
🔥2
Observable API
Через пару версий в Chrome планируют добавить примитив Observable.
Основная идея пропозала заключается в предоставлении более удобного способа управления данными. Вместо императивного подхода с использованием callback функций, который неудобен при работе с большим количеством асинхронных операций, предлагается использовать Observables. Кроме того, в отличие от Promise, они имеют ряд преимуществ, включая возможность обработки множественных значений, отмену подписки и гибкое управление потоком. В общем, все то, к чему мы привыкли, используя RxJs.
Большим преимуществом нативного Observable является интеграция с
Изначально было предложено добавить метод
Пример работы:
Есть вероятность, что обновят DevTools для удобства дебаггинга. Или решат, что существующих инструментов в нем достаточно. Сейчас, по ответам разработчиков, понятно, что разбираться с этим планируют позже.
Пока примитив добавляют в браузерные движки, Deno тоже решил не отставать и тоже реализовать данный API.
Ссылка на спеку и репозиторий для желающих узнать другие детали.
#js
Подписывайся / Чат
Через пару версий в Chrome планируют добавить примитив Observable.
Основная идея пропозала заключается в предоставлении более удобного способа управления данными. Вместо императивного подхода с использованием callback функций, который неудобен при работе с большим количеством асинхронных операций, предлагается использовать Observables. Кроме того, в отличие от Promise, они имеют ряд преимуществ, включая возможность обработки множественных значений, отмену подписки и гибкое управление потоком. В общем, все то, к чему мы привыкли, используя RxJs.
Большим преимуществом нативного Observable является интеграция с
EventTarget. Предлагаемый метод when(), который возвращает Observable, является заменой стандартному addEventListener().Изначально было предложено добавить метод
.on() в EventTarget. Оказалось, что есть риск коллизии имен с существующим (пользовательским) кодом. Поскольку это посчитали значительным, API метод решили переименовать.Пример работы:
// Filtering and mapping:
element
.when('click')
.filter((e) => e.target.matches('.foo'))
.map((e) => ({ x: e.clientX, y: e.clientY }))
.subscribe({ next: handleClickAtPoint });
Есть вероятность, что обновят DevTools для удобства дебаггинга. Или решат, что существующих инструментов в нем достаточно. Сейчас, по ответам разработчиков, понятно, что разбираться с этим планируют позже.
Пока примитив добавляют в браузерные движки, Deno тоже решил не отставать и тоже реализовать данный API.
Ссылка на спеку и репозиторий для желающих узнать другие детали.
#js
Подписывайся / Чат
🔥6👍2
Type stripping
Вы слышали, что недавно в Node.js появилась возможность запускать TS-файлы при помощи удаления типов (type stripping). Здесь интересно написано, какие проблемы есть в текущем решении, для чего это в принципе нужно и в каком направлении, вероятно, будет развиваться эта фича Node.js.
Если коротко, то сталкивается стабильность ноды и минусы TS в виде отсутствия спеки, отказа от следования semver, вкупе с частыми обновлениями, возможностью встраивания tsconfig.json в проект и его соответствие типу модуля. Кроме того, большой размер tsc также не добавляет плюсов.
Работает следующим образом: в ноду добавляется SWC (написан на Rust) в виде скомпилированного для WASM бинарника. TS файлы прогоняются через SWC и все.
Работа еще продолжается, в TS 5.7 был добавлен флаг
Очень советую к прочтению roadmap.
#typescript
Подписывайся / Чат
Вы слышали, что недавно в Node.js появилась возможность запускать TS-файлы при помощи удаления типов (type stripping). Здесь интересно написано, какие проблемы есть в текущем решении, для чего это в принципе нужно и в каком направлении, вероятно, будет развиваться эта фича Node.js.
Если коротко, то сталкивается стабильность ноды и минусы TS в виде отсутствия спеки, отказа от следования semver, вкупе с частыми обновлениями, возможностью встраивания tsconfig.json в проект и его соответствие типу модуля. Кроме того, большой размер tsc также не добавляет плюсов.
Работает следующим образом: в ноду добавляется SWC (написан на Rust) в виде скомпилированного для WASM бинарника. TS файлы прогоняются через SWC и все.
Enum и namespace, при этом, можно использовать, только при включенном флаге —experimental-transform-types. Что, на мой взгляд, хорошо. namespace вообще редко кто использует, а в чем недостатки enum я писал здесь.Работа еще продолжается, в TS 5.7 был добавлен флаг
rewriteRelativeImportExtensions для изменения расширения с .ts на .js, что ускорит генерацию файлов и, как следствие, сборку. А в следующей версии уже добавили erasableSyntaxOnly, который сообщает компилятору о необходимости выключить несовместимые фичи Enum, experimentalDecorators, namespaces, parameter properties Очень советую к прочтению roadmap.
#typescript
Подписывайся / Чат
👍1
Нововведения 19.2, новые подходы и RFC
httpResource. Пока в статусе experimental.
Self-closing tags. Добавлены схематики, позволяющие произвести миграцию на self-closing tags (даже не знаю, как это нормально перевести, поэтому буду использовать так).
Сейчас команда Angular обновила раздел в документации. Интересно, почему сразу не обновили до selector-less варианта.😅
Исправлен баг при работе с FormRecord. При объявлении формы с non-nullable значениями типы оборачивались в Partial, из-за чего и возникала ошибка.
#angular
И еще кое-что интересное!
В следующей версии готовятся представить two-way binding, который позволит считывать значения с input без использования FormsModule.
Пример:
Похоже, сигналы дают такую возможность.
Ссылка на МР, рекомендую ознакомиться.
Новые Resource RFC!
На прошлой неделе команда поделилась RFC, которые описывают
- Архитектурный подход
- API
Первый из них о том, что
Рассматривают два паттерна, которые позволяют включать асинхронные источники в синхронные реактивные системы с сигналами:
- Resource (явная асинхронность, где ресурсы представляют асинхронные операции и имеют статус загрузки и значение).
- Suspense ("скрытая" асинхронность, когда чтение значений приостанавливается (suspend), пока не станут доступными. Другими словами, "async signals").
#angular
Подписывайся / Чат
httpResource. Пока в статусе experimental.
Self-closing tags. Добавлены схематики, позволяющие произвести миграцию на self-closing tags (даже не знаю, как это нормально перевести, поэтому буду использовать так).
ng generate @angular/core:self-closing-tag
Сейчас команда Angular обновила раздел в документации. Интересно, почему сразу не обновили до selector-less варианта.😅
Исправлен баг при работе с FormRecord. При объявлении формы с non-nullable значениями типы оборачивались в Partial, из-за чего и возникала ошибка.
#angular
И еще кое-что интересное!
В следующей версии готовятся представить two-way binding, который позволит считывать значения с input без использования FormsModule.
Пример:
input [(value)]="name">
<input type="number" [(valueAsNumber)]="age">
<input type="date" [(valueAsDate)]="birthday">
<input type="file" [(files)]="files" />
<input type="checkbox" [(checked)]="isHappy">
Похоже, сигналы дают такую возможность.
Ссылка на МР, рекомендую ознакомиться.
Новые Resource RFC!
На прошлой неделе команда поделилась RFC, которые описывают
- Архитектурный подход
- API
Первый из них о том, что
resource рассматривается, как основной примитив для работы с асинхронностью. Как я понял, цель в том, чтобы предложить разработчикам удобный способ интеграции асинхронных данных в синхронную модель UI. Это позволит компонентам иметь возможность показывать состояния загрузки или ошибок до получения данных.Рассматривают два паттерна, которые позволяют включать асинхронные источники в синхронные реактивные системы с сигналами:
- Resource (явная асинхронность, где ресурсы представляют асинхронные операции и имеют статус загрузки и значение).
- Suspense ("скрытая" асинхронность, когда чтение значений приостанавливается (suspend), пока не станут доступными. Другими словами, "async signals").
Resource призваны дополнить сигналы, расширяя реактивную систему Angular для поддержки асинхронных сценариев.#angular
Подписывайся / Чат
👍4❤1🎉1
Немного в продолжение темы новых API
Почитав представленные RFC, отметил для себя особо интересные пункты и решил добавить к сообщению следующее:
Suspense паттерн позволяет работать с асинхронными данными в синхронном режиме, будто они уже доступны, несмотря на то, что загрузка в фоновом режиме еще продолжается.
Если данных в сигнале еще нет (не загружены), срабатывает флаг (на самом деле, выбрасывается исключение).
Suspense API отлавливает это состояние и отображает спиннер.
После того, как данные загрузились, флаг меняет состояние, "suspense boundary" повторяет попытку рендеринга и отображает полученные данные.
Нет необходимости писать кучу дополнительных флагов и собственных велосипедов.
Если добавят prefetch стратегии, которые будут подгружать данные перед инициализацией компонента (кнопки, части UI, например, наведение указателем мыши пользователя на ссылку, прокрутка области просмотра), это привнесет существенное улучшение DX.
Есть и недостатки. Не всегда может быть очевидно, почему часть приложения не загрузилась или UI выглядит не так, как нужно. С отладкой тоже пока непонятно. Dev tools планируют обновить, но гораздо позже.
httpResource
Судя по RFC, это обертка над httpClient, захватывает весь HTTP-стек Angular, включая интерсепторы и утилиты тестирования. Есть отличия:
- запрос инициируется сразу, подписка не нужна.
- интегрирован с сигналами. Если исходный сигнал изменяется, будет сделан новый HTTP-запрос.
- возвращает экземпляр
Пример конфигурации:
Одна из целей
Пример интеграции с Zod:
Планы у команды Angular грандиозные, пока можно изучить планируемые обновления. Ссылки я скинул в предыдущем сообщении:)
#angular
Подписывайся / Чат
Почитав представленные RFC, отметил для себя особо интересные пункты и решил добавить к сообщению следующее:
Suspense паттерн позволяет работать с асинхронными данными в синхронном режиме, будто они уже доступны, несмотря на то, что загрузка в фоновом режиме еще продолжается.
userData: Signal = asyncComputed(async () => fetch(/api/user/${currentUserId()}));
@suspense {
<user-profile [data]="userData()" />
} @fallback {
<loading-spinner />
}Если данных в сигнале еще нет (не загружены), срабатывает флаг (на самом деле, выбрасывается исключение).
Suspense API отлавливает это состояние и отображает спиннер.
После того, как данные загрузились, флаг меняет состояние, "suspense boundary" повторяет попытку рендеринга и отображает полученные данные.
Нет необходимости писать кучу дополнительных флагов и собственных велосипедов.
Если добавят prefetch стратегии, которые будут подгружать данные перед инициализацией компонента (кнопки, части UI, например, наведение указателем мыши пользователя на ссылку, прокрутка области просмотра), это привнесет существенное улучшение DX.
Есть и недостатки. Не всегда может быть очевидно, почему часть приложения не загрузилась или UI выглядит не так, как нужно. С отладкой тоже пока непонятно. Dev tools планируют обновить, но гораздо позже.
httpResource
Судя по RFC, это обертка над httpClient, захватывает весь HTTP-стек Angular, включая интерсепторы и утилиты тестирования. Есть отличия:
- запрос инициируется сразу, подписка не нужна.
- интегрирован с сигналами. Если исходный сигнал изменяется, будет сделан новый HTTP-запрос.
- возвращает экземпляр
HttpResourceRef, который содержит дополнительные данные.Пример конфигурации:
results = httpResource({
url: '/api/query',
method: 'POST',
body: {...},
params: {
'rowLimit': 100,
},
});Одна из целей
httpResource - улучшение типо-безопасности. По умолчанию возвращается "raw type", для JSON unknown, для остальных возвращается объектный тип с указанием Blob, string и тд. Что более интересно, планируется добавить функцию parse, позволяющую преобразовать значение в любой тип, добавив валидацию.Пример интеграции с Zod:
const User = zod.object({
id: zod.number(),
name: zod.string(),
// ... other fields ...
});
const user = httpResource(..., {parse: User.parse});Планы у команды Angular грандиозные, пока можно изучить планируемые обновления. Ссылки я скинул в предыдущем сообщении:)
#angular
Подписывайся / Чат
👍4