Как стать автором
Обновить
253.11

JavaScript *

Прототипно-ориентированный язык программирования

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

⚛️ React 19 — useOptimistic

useOptimistic — новый хук, который позволяет отобразить “оптимистичное” состояние. Оно называется “оптимистичным”, потому что мы надеемся, что запрос не свалится с ошибкой и после его выполнения состояние будет выглядеть именно так.

❓Как используется

  • В useOptimistic передаётся реальное состояние и функцию-reducer

  • Компонент использует “оптимистичное” состояние для рендера

  • Перед выполнением запроса обновляется “оптимистичное” состояние

  • Когда запрос завершился, нужно обновить реальное состояние

  • Как только реальное состояние обновилось, оптимистичное состояние обновится автоматически, так как оно передано в useOptimistic первым параметром.

  • Если запрос упал с ошибкой, нужно откатить изменения в оптимистичном состоянии.

ℹ️ Первый вопрос, которым я задался, а в чём отличие от обычного setState, путём экспериментов, вот что удалось найти:

  • useOptimistic работает с формами. Работать с обычной кнопкой в SPA мне не удалось, обновление происходило только после завершения запроса

  • useOptimistic работает только внутри асинхронного обработчика, что логично. Если убрать async/await, обновление произойдёт только после завершения запроса

  • Параметр в useState используется только для инициализации, и игнорируется в последующих рендерах. useOptimistic будет сихронизироваться со значением со значением переданным первым параметром.

В любом случае, пока useOptimistic выглядит каким-то низкоуровневым API. Надеюсь скоро появится больше Best Practices.

https://t.me/cherkashindev/184

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

⚛️ React 19 — use(Promise)

use — новый хук, который позволяет считывать данные из промиса и при этом интегрирован с Suspense и ErrorBoundary.

Основные моменты:

  • На этот хук не распространяются правила хуков — его можно использовать внутри циклов и условных операторов.

  • Если мы используем хук use(Promise), то где-то в родительском компоненте мы должны положить сам промис (не данные как мы делали раньше) в стейт (useState). Это позволяет избавиться от useEffect’а, который был нужен, чтобы запросить данные при первом рендере.

  • Хук интегрирован с Suspense, поэтому пока промис не разрезолвится — будет показан fallback объявленный в ближайшем Suspense.

  • Если промис зареджектился, то будет показан fallback объявленный в ближайшем ErrorBoundary.

Материалы

https://t.me/cherkashindev/182

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

Состоялся релиз системы для создания отказоустойчивых рабочих процессов Restate 0.8. Код проекта опубликован на GitHub под лицензией Put Restate under Business Source License от Restate Software.

Согласно пояснению разработчиков проекта, Restate отлично подходит для создания:

  • рабочих процессов типа Lambda как код (Lambda Workflows as Code);

  • транзакционных обработчиков RPC;

  • обработки событий с помощью Kafka.

В версии Restate 0.8 разработчики уделили большое внимание доработке API, учтя отзывы пользователей, чтобы уменьшить трудности при создании сервисов Restate. Также там добавлены комбинаторы промисов (Promise combinators), которые позволяют детерминированно комбинировать промисы. Например, если вы хотите дождаться вызова службы A или вызова службы B, то Restate позаботится о записи того, какой из промисов был выполнен первым, и в конечном итоге воспроизведёт этот выбор, когда это необходимо. В новой версии проекта доступны все комбинаторы стандартной библиотеки JavaScript.

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

Весна, TypeScript, A?.Frontend Community #6 ?

21 марта состоится уже 6-я встреча сообщества A?.Frontend, на которой мы подробно поговорим о TypeScript, сравним его с JS, определим плюсы и минусы использования. Кратко о программе.

? TypeScript: Введение в мир надежного программирования

Александр Чернов, Frontend-разработчик в Альфа-Банке, расскажет, как при помощи TypeScript сделать код надёжнее. 

? Переход на TypeScript: плавные перемены и непредвиденные сложности

Рустам Султанбеков, Middle Frontend-разработчик в Авито, поделится опытом перевода существующего приложения на TypeScript и поможет понять, стоит ли это делать. 

? Генерируй – типизируй

Александр Серов, Senior Frontend-разработчик в UULA, объяснит, как пользоваться продвинутыми возможностями TypeScript. 

? Generics – Что? Где? Когда?

Тёма Сенюков, старший разработчик интерфейсов в Яндексе, расскажет, как пользоваться Generics, чтобы избежать дублирования кода и ошибок. 

Митап пройдёт 21 марта (четверг) в 18:30 онлайн. Регистрируйтесь на митап по ссылке. Также ссылку на трансляцию мы опубликуем в нашей группе в Телеграмм, присоединяйтесь.

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

Состоялся релиз TypeScript 5.4. В новой версии языка программирования, построенного на основе JavaScript и позволяющего объявлять и описывать типы, в Microsoft поработали над производительностью языка, добавили новые возможности автодополнения кода для редакторов и упростили способы переподключения библиотек. Типы также используются в инструментах редактора TypeScript, таких как автодополнение, навигация по коду и рефакторинг, которые доступны в Visual Studio и VS Code. Проект доступен через NuGet или npm (npm install -D typescript).

В TypeScript 5.4 появился новый тип утилиты NoInfer, добавлена поддержка вызовов require() в пакете --moduleResolution и --module save, быстрое исправление при добавлении отсутствующих параметров, поддержка автоматического импорта для подпутей, исправлены ранее обнаруженные ошибки.

С выходом TypeScript 5.4 Microsoft продолжает работу над TypeScript 5.5. Согласно дорожной карте, бета-версия этого проекта должна выйти 16 апреля, релиз-кандидат — 4 июня, а финальный релиз — 18 июня.

Также стало возможно запускать тестовые ночные сборки TypeScript 5.4 Nightlies через npm, которые выпускаются каждый день в полночь (npm install -D typescript@next) для VS Code, Visual Studio, Sublime Text и IntelliJ.

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

7 марта 2024 года состоялся релиз Boa v0.18 — экспериментального лексера, парсера и компилятора Javascript, а также движка ECMAScript, написанного на языке программирования Rust.

Исходный код проекта выложен на GitHub под лицензией MIT License.

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

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

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

Впервые проект Boa был представлен на конференции JSConf EU 2019 разработчиком Джейсоном Уильямсом.

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

Фишки Google Apps Script

Недавно мы выпустили большую статью про полезные фишки Google Apps Script. Делимся одним из примеров, как с помощью API-запроса можно тянуть данные из таск-трекера и CMS (у нас Bitrix) и интегрировать их в любые таблички. Пример в формате JS:

/** Функция обращения к таск трекеру по API */
function taskTrackerAuth() {


 const sourceUrl = 'https://your_taskTracker_url/rest/tempo-timesheets/4/worklogs/search';
 const options = {
   'headers': { 'Authorization': 'Basic *******************' },
   'method': 'post',
   'contentType': 'application/json',
   'Accept': 'application/json',
   /** Полезная нагрузка настраивается индивидуально, то что указано тут можно очистить */
   'payload': JSON.stringify({'from': [],'to': [], 'worker': [], 'projectKey': [], 'taskKey': [], 'filterId': [] }),
 }


 const taskTrackerResponse = UrlFetchApp.fetch(sourceUrl, options);
 const data = JSON.parse(taskTrackerResponse.getContentText());


 //Вывод сообщения о получении данных
 if (data.length > 0) {
   SpreadsheetApp.getActiveSpreadsheet().toast('Данные Timesheets получены', '(V)_O_o_(V)', 2);
 } else {
   SpreadsheetApp.getActiveSpreadsheet().toast('Данные Timesheets не получены', '(V)_O_o_(V)', 2);
 }
}

Этот запрос обращен на получение данных из таск-трекера. Если его немного переделать, можно получить запрос и в другие системы и выудить данные через API откуда угодно.

Больше примеров — найдете в статье. А еще мы много пишем про разработку в нашем телеграм-канале.

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

Вышли корректирующие выпуски JavaScript-платформы Node.js 21.6.2, 20.11.1, 18.19.1, в которых исправлено 8 уязвимостей (4 из них с высоким уровнем опасности):

  • CVE-2024-21892 — возможность подстановки непривилегированным пользователем кода, наследующего расширенные привилегии, с которыми выполняется рабочий процесс;

  • CVE-2024-22019  — отказ в обслуживании через исчерпание доступных ресурсов (нагрузка на CPU и расходование пропускной способности) при обработке встроенным HTTP-сервером специально оформленных chunked-запросов;

  • CVE-2024-21896 — выход за границу базового каталога в файловых путях, уязвимость позволяет обойти нормализации файловых путей при помощи path.resolve() в случае передачи пути с использованием класса Buffer;

  • CVE-2024-22017 — вызов setuid() не сбрасывал все привилегии;

  • CVE-2023-46809 — уязвимость в API privateDecrypt(), допускающая применение атаки Marvin для расшифровки RSA на основе измерения времени операций;

  • CVE-2024–21 891 — возможность обхода модели прав доступа при использовании пользовательских обработчиков нормализации файловых путей;

  • CVE-2024-21890 — некорректная обработка масок в параметрах "--allow-fs-read" и "--allow-fs-write";

  • CVE-2024-22025 — отказ в обслуживании через израсходование ресурсов при декодировании сжатых данных в формате Brotli, полученных через вызов fetch().

Источник: OpenNET.

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

React — Compound Components

Как-то я уже упоминал паттерн Compound Components (Составные компоненты) для React, теперь остановимся на нём немного подробнее.

ℹ️ Compound components — это подход позволяет объединить несколько компонентов в единую сущность, которая неявно имеет общее состояние. Эти компоненты тесно взаимодействуют друг с другом и работают как единое целое, представляя собой полноценный UI компонент.

? Основные характеристики:

  • Используется React контекст, чтобы управлять состоянием

  • Должен быть главный компонент, в котором хранится состояние и объявляется React контекст

  • Все дочерние компоненты используют состояние через React контекст

ℹ️ Он состоит из 2 простых подходов React:

  1. Композиция компонентов

  2. Паттерн “Провайдер” — использование контекста React 

? Вначале рассмотрим подходы по отдельности

1️⃣ Что такое композиция?

Вместо вот этого 

<Tile count={money} title="Стоимость" icon={<MoneyIcon/>}/>

Мы пишем вот так

<Tile>
  <Title>{title}</Title>
  <Number>{count}</Number>
  <Icon>{icon}</Icon>
</Tile>

2️⃣ Паттерн “Провайдер” 

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

? Если объединить два этих подхода, то сможем реализовать паттерн Compound Components. Как пример, можно использовать компонент табов из библиотеки material-ui.

https://t.me/cherkashindev/166

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

Явное управление ресурсами в TypeScript — using

Недавно, когда я рассказывал, как мы пишем тесты, я уже упоминал, что в TypeScript’е появилось новое ключевое слово using. Оно позволяет нам сделать код чище и более линейным, избавившись от try/finally. 

Но мы можем использовать using не только, когда открываем файл или подключение к базе данных, иначе его использование ограничилось бы исключительно сервером. 

Мне нравится рассматривать using, как Undo/Redo только наоборот, сперва мы выполняем какое-то действие, а в конце отменяем его:

- создали объект, удалили

- показали спиннер и скрыли, когда получили данные

Причем отмена удобно происходит в самом конце функции, даже если мы используем async/await.

Вот простой пример, как можно использовать using, чтобы показывать/скрывать спиннер в React коде.

useEffect(() => {
  (async () => {
    using manager = new LoadingManager(setIsLoading);
    await Promise.resolve().then(() => console.log("promise.resolve"));
  })();
 }, []);

/**
 * Класс, который управляет состоянием спиннера
 */
class LoadingManager {
  constructor(private setIsLoading: (value: boolean) => any) {
    this.setIsLoading(true);
    console.log("constructor");
  }

  [Symbol.dispose]() {
    this.setIsLoading(false);
    console.log("disposer")
  }
}

// В консоли будет выведено в следующем порядке
// constructor

Код можно открыть в песочнице.

К сожалению, нельзя опустить переменную manager, но это лучше, чем лепить везде try/finally.

https://t.me/cherkashindev/164

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

Вышел проект Bun Shell для запуска кроссплатформенных скриптов на JavaScript и TypeScript.

Оболочки для bash или sh существуют уже несколько десятилетий. Но они плохо работают в JavaScript. macOS (zsh), Linux (bash) и Windows (cmd) имеют немного разные оболочки с разным синтаксисом и разными командами. Команды, доступные на каждой платформе в итоге там разные, также одна и та же команда может иметь разные флаги при запуске и поведение после активации.

Bun Shell — это новый экспериментальный встроенный язык и интерпретатор Bun, который позволяет запускать кроссплатформенные скрипты на JavaScript и TypeScript. Проект работает на Windows, macOS и Linux. Там уже реализованы множество общих команд и функций, таких как подстановка, переменные среды, перенаправление, конвейерная обработка и многое другое.

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

VKADSKIP - расширение промотает рекламу в видео VK за вас⁠⁠!

VKADSKIP - это бесплатное расширение для браузеров Google Chrome, Яндекс.Браузер, Opera и Firefox.

Как это выглядит?

Когда пользователь VK Видео откроет видеоролик, по которому в базе данных уже есть размеченные участки, в плеере на полосе таймлайна появятся цветные сегменты, которые будут автоматически пропускаться во время просмотра. После пропуска участка отобразится уведомление о пропущенном участке с возможностью отмотать обратно. Также рядом с переключателем звука будет кнопка "Реклама в видео", где можно просмотреть подробную информацию и добавить новый сегмент для автопропуска.

Пример демонстрации на видео

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

Пользователи (и команда асессоров) сами размечают на видеороликах участки с рекламой и другими типами лишнего контента. У всех других пользователей на тех же видеороликах появятся сегменты для автопропуска.

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

Загрузить расширение бесплатно:

Для браузера Google Chrome

Для браузера Яндекс.Браузер

Для браузера Opera

Для браузера Mozilla Firefox

Больше информации и возможность поддержать проект на сайте:

https://vkadskip.star-tech.dev/

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

Выводим Мурыча на чистую воду

Топ перлов:

  • В JS нет переменных и присваивания, но есть потоки

  • Все числа выделяются в куче

  • TS не годится для разработки

  • let и const - главные перфоманс ботлнеки

Упоминаемые материалы:

Мета-сслыки:

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

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

Продолжается перевод книги Vue.js 3 Design Patterns and Best Practices

На данный момент переведено 6 глав:

  • Глава 1, Фреймворк Vue 3

  • Глава 2, Принципы и шаблоны проектирования программного обеспечения

  • Глава 3, Создание рабочего проекта

  • Глава 4, Композиция пользовательского интерфейса с помощью компонентов

  • Глава 5, Одностраничные приложения

  • Глава 6, Прогрессивные веб-приложения

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

​​?️️️️️️ Array.prototype.sort

Как будет отсортирован следующий массив [-1, 0, 1, 2, -1, -4, -2, -3, 3, 0, 4].sort()

? Предыстория

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

Я написал решение, подебажил на бумаге — всё работает, отправляю код на проверку — не работает ?‍♂️. Перепроверяю всё глазами — ну должно же работать! 

Сдаюсь и начинаю дебажить в VS Code и вижу, что сортировка массива работает не так как я ожидал.

ℹ️ Объяснение

Если перейти на MDN и прочитать документацию Array.prototype.sort(), то станет всё понятно.

Метод sort() в JavaScript преобразует элементы в строки и затем сравнивает их последовательности значений кодов UTF-16. Это означает, что при сортировке числа рассматриваются как строки.

Таким образом, числа в данном случае сортируются на основе их строкового представления. Например, '-10' будет идти перед '-2', потому что строка '10' идет перед строкой '2' в лексикографическом порядке.

Чтобы выполнить числовую сортировку массива, нужно предоставить функцию сравнения методу sort(), как показано здесь:

[-1, 0, 1, 2, -1, -4, -2, -3, 3, 0, 4].sort((a, b) => a - b);

Это даст вам [-4, -3, -2, -1, -1, 0, 0, 1, 2, 3, 4] — числовую сортировку.

https://t.me/cherkashindev/136

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

⚛️ Атомарные обновления в Zustand

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

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

Zustand сравнивает по ссылке предыдущее и текущее значение, возвращаемое из useStore(), и если объект изменился — происходит ре-рендер. 

❌ В следующем примере у нас всегда будет возвращаться новый объект, и ре-рендер произойдёт даже если изменился только age, а lastName и firstName не изменились

const {firstName, lastName} = useStore(({firstName, lastName}) => ({firstName, lastName}));

Аналогичное поведение будет и в следующем случае

const {firstName, lastName} = useStore();

✅ Есть три варианта использования значений из стейта, которые поддерживают атомарные обновления:

1️⃣ Одиночные селекторы

const firstName = useStore((state) => state.firstName)

const lastName = useStore((state) => state.lastName)

2️⃣ Селектор, который возвращает объект + shallow - функция сравнения предыдущего и нового стейтов

const {firstName, lastName} = useStore(({firstName, lastName}) => ({

    firstName, 

    lastName

}), shallow);

3️⃣ Автосгенерированных селекторы

const firstName = useStore.use.firstName();

const lastName = useStore.use.lastName();

Накидал небольшую демку в Codesandbox

#frontend #react #statemanagement #zustand

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

​​?️️️️️️ Каррирование и частичное применение

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

И частичное применение, и каррирование, реализуются как функции, принимающие в качестве параметра другую функцию.

Частичное применение — функция partialApply, принимающая первым параметром функцию — fn, а остальные параметры — часть параметров функции fn. Функция partialApply возвращает функцию, которая в качестве параметров принимает недостающие аргументы функции fn.

Каррирование — функция curry, которая принимает единственный параметр — функцию fn, и возвращает каррированную функцию fn.  Можно сказать, что каррированная функция fn — функция аккумулятор, которая будет накапливать переданные аргументы до тех пор, пока не будет передано достаточно параметров для вызова исходной функции. Параметры можно передавать в любом количестве.

Подробнее

https://t.me/cherkashindev/132

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

⬇️ Проваливание промисов

Когда вы передаете в then() что-то отличное от функции (например, промис), это интерпретируется как then(null) и в следующий по цепочке промис «проваливается» результат предыдущего.

Подробнее о промисах в статье "У нас проблемы с промисами".

https://t.me/cherkashindev/131

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

Amazon опубликовала компилятор jsii 1.90, представляющий собой модификацию компилятора TypeScript, позволяющую извлечь из компилируемых модулей информацию об API и сгенерировать универсальное представление данного API для обращения к JavaScript-классам из приложений на различных языках программирования. Код проекта написан на TypeScript и распространяется под лицензией Apache 2.0.

Jsii даёт возможность создавать на языке TypeScript библиотеки классов, которые могут использоваться в проектах на языках C#, Go, Java и Python, благодаря трансляции в родные для этих языков модули, предоставляющие тот же самый API. Инструментарий используется в AWS Cloud Development Kit для поставки библиотек для разных языков программирования, формируемых из одной кодовой базы. В новой версии jsii реализовано кэширование списка классов для каждой сборки и документировано, как можно превратить обязательное свойство в необязательное.

Источник: OpenNET.

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

Препарируем Nano Stores и находим родовые травмы
https://youtu.be/Q2rzPc7EEa8

Крайне малые размеры, но..

  • Лишние вычисления и сайд-эффекты

  • Медленная работа: и архитектурно, и по реализации

  • Только статические зависимости с ручным приводом

  • Нестабильность поведения

  • Автор без этических ограничений

Поблагодарить, Обсудить, Бенчмарки, $mol_wire.

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