Telegram Web Link
assistant-ui

Assistant-ui набор компонентов для быстрой реализации чатов с AI. Есть клишка, которая поможет инициализировать проект с простым чатом. Есть несколько базовых примеров использования библиотеки для реализации простого функцинала

https://github.com/Yonom/assistant-ui

#development #javascript #react #ai
Ultimate Express

Ultimate Express - http сервер с полной совместимостью с express, но реализованный на µWebSockets (это веб-сервер написанный на С++). Основная фича (помимо скорости работы) - что это drop-in замена обычному экспрессу. Если вы используется 4 экспресс, все что нужно, это поставить новый пакет npm install ultimate-express и затем по всему коду заменить express на ultimate-express.

Есть несколько ограничений и отличий от обычного express, но они минимальны.

На странице в гитхабе представлены 2 бенчмарка перформанса - в одном сравнивается обычный express и ultimate-express. В нем ускорение составляет от 4 до 12 раз. Другой бенчмарк от bun. В этом бенче ultimate-express занимает 3 место среди замеров на node.js (в общем списке он где-то 12)

Крутая либа по нескольким причинам. Во первых, чуваки сделали быстрый http-сервер. Во вторых, они сделали полную поддержку API express, что позволяет переехать, заменив только импорты (ну вообще можно и без замены импортов обойтись, поправив алиасы для импортов).

https://github.com/dimdenGD/ultimate-express

#development #javascript #express #httpServer
Дайджест за 2024-10-21 - 2024-10-25

Unleash JavaScript's Potential with Functional Programming
Еще одна статья про функциональное программирование в JS. Данная статья представляет собой гайд, который погружает вас в функциональное программирование шаг за шагом.

Объяснение начинается с определений - что такое примитив, что такое композируемая сущность, что такое функция и из чего она состоит и тд и тп. Заканчивается все применением каррирования.

⭐️SVG Coding Examples: Useful Recipes For Writing Vectors By Hand
Огромный гайд по рисованию SVG в JS на Smashing Magazine.

Начинается все с основ: что за поле используется в SVG, как управлять его размером, что с единицами измерения. Затем гайд переходит в варианты создания простых svg примитивов (линии, квадраты, окружности, овалы) в JS, затем переходит к более сложным техникам (полигоны, паттерны).

How Bun supports V8 APIs without using V8 (part 1)
Команда разработки Bun рассказывают, как они поддерживают API V8 (движок гугл хрома) без использования V8. Bun стремиться быть совместимым с nodejs API, чтобы любой nodejs код можно было запускать в bun. Если nodejs для каких-то операций использует С++ библиотеки, то bun тоже их использует (или их аналоги). Сложнее обстоят дела с теми кейсами, когда реализация nodejs сделана через вызов V8. В Bun используется не V8 а JavaScriptCore (движок, используемый в safari). Поэтому прост так взять и использовать тоже самое не получается - надо либо найти аналог в JSC и убедиться что он работает также, либо написать свою имплементацию

Собственно про это и статья. В статье рассказывается про подводные камни такого подхода. 2 практических идентичных куска кода на С++ будут вести к разным результатам при использовании V8 и JSC. Статья подробно рассказывает про часть этих подводных камней с примерами С++ кода.

assistant-ui
Assistant-ui набор компонентов для быстрой реализации чатов с AI. Есть клишка, которая поможет инициализировать проект с простым чатом. Есть несколько базовых примеров использования библиотеки для реализации простого функцинала

https://github.com/Yonom/assistant-ui

Ultimate Express
Ultimate Express - http сервер с полной совместимостью с express, но реализованный на µWebSockets (это веб-сервер написанный на С++). Основная фича (помимо скорости работы) - что это drop-in замена обычному экспрессу. Если вы используется 4 экспресс, все что нужно, это поставить новый пакет npm install ultimate-express и затем по всему коду заменить express на ultimate-express.

Есть несколько ограничений и отличий от обычного express, но они минимальны.

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂
pretty-print

pretty-print - библиотека для удобного вывода в консоль любых JS-значений. Когда делаешь обычный console.log по большим объектам, то там легко наступить на кейс, когда в каком-нибудь поле выведется [Object object]. Эта "проблема" решается с помощью JSON.stringify, но либа предлагает еще кучу всякого и удобного

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

https://www.npmjs.com/package/@parischap/pretty-print

#development #javascript #library #console
Inverse Assertions

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

Логично сделать что-то типа expect(notification).not.toBeInTheDocument(). Но что, если нотификашка появляется не сразу?

Можно поставить какой-нибудь sleep. Лично я во всех проектах делаю утилку const wait = (msec) => new Promise(resolve => setTimeout(resolve, msec)), который, по сути, и есть sleep и вызывается как await wait(1000). Проблема с таким подходом, что мы либо подбираем эмпирически нужное значение ожидания, либо завязываемся на детали реализации (т.е. должны знать через сколько примерно появляется нотификашка)

Как же делать правильно. В testing-library есть waitFor - функция резолвнет промис, как только её колбек пройдет

Например
await waitFor(() => {  
expect(notification).toBeVisible()
})


Сам waitFor в данном случае очень полезен - мы просто пишем что ожидаем какого-то условия и это позволяет нам отвязаться от деталей реализации, а также гарантирует что мы не будем ждать лишнее время (как в случае со sleep)

Но тут нам мешает, что waitFor ожидает успешного колбека. Т.е. если мы напишем

await waitFor(() => {
expect(notification).not.toBeInTheDocument()
})


То waitFor завершится сразу же, хотя нотификашка может появиться позже.

Решение здесь - инвертировать проверку

const notificationVisiblePromise = waitFor(() => {
expect(notification).toBeVisible()
})

// Assert that the notification promise has, eventually, rejected.
await expect(notificationVisiblePromise).rejects.toThrow()


В данном случае мы через waitFor проверяем, что нотификашка хотя бы раз появилась. И затем ожидаем что промис от waitFor реджектнется, что позволяет быть увереным в том, что нотификашка не появилась.

https://www.epicweb.dev/inverse-assertions

#development #javascript #testingLibrary #testing #assertions
ECMAScript proposal updates 2024-10

Пришел октябрьский апдейт по пропозалам в EcmaScript.

В 4 стейдж перешли Promise.try, Import Attributes, RegExp Modifiers, Sync Iterator helpers, JSON Modules

Promise.try
Позволяет завернуть колбек в промис
До Promise.try
await new Promise((resolve) => resolve(fn()))


С Promise.try
await Promise.try(fn)


Import Attributes
Позволяет указать мета-информацию для импортов
import json from "./foo.json" with { type: "json" };
import("foo.json", { with: { type: "json" } });


RegExp Modifiers
Модификаторы RegExp (например i, m и другие) теперь можно использовать и в под-выражениях
Пример из доки (внимание на группы, внутри которых используется i)
const re1 = /^[a-z](?-i:[a-z])$/i;
re1.test("ab"); // true
re1.test("Ab"); // true
re1.test("aB"); // false

const re2 = /^(?i:[a-z])[a-z]$/;
re2.test("ab"); // true
re2.test("Ab"); // true
re2.test("aB"); // false


Sync Iterator helper
Добавляет удобные методы (map, filter, take, flatMap, reduce, toArray, forEach , some , every, find, from) для работы с итераторами
Пример
function* naturals() {
let i = 0;
while (true) {
yield i;
i += 1;
}
}

const result = naturals()
.take(5)
.reduce((sum, value) => {
return sum + value;
}, 3);

result // 13


В stage-3 перешел Atomics.pause. Этот метод позволяет указать, что треду следует встать на короткую паузу. Это позволяет более оптимально использовать CPU

В stage-2.7 перешли: Error.isError и Iterator Sequencing

Error.isError решает ту же проблему что и Array.isArray, а именно создание инстансов Ошибки в разных контекстах (например, iframe имеет полностью свой контекст и там свой класс Error, поэтому проверка ошибки на instanceof Error в родительском контексте выведет false т.к. в родительском контексте есть свой класс Error)

Iterator Sequencing добавляет API для объединения итераторов.
Например, у вас есть 2 итератора и вы между ними еще хотите добавить значений. Сейчас самый удобный способ сделать это

let lows = Iterator.from([0, 1, 2, 3]);
let highs = Iterator.from([6, 7, 8, 9]);
let digits = function* () {
yield* lows;
yield 4;
yield 5;
yield* highs;
}();

Array.from(digits); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


А будет
let lows = Iterator.from([0, 1, 2, 3]);
let highs = Iterator.from([6, 7, 8, 9]);
let digits = Iterator.concat(lows, [4, 5], highs);



В stage-2 пришли Extractors, structs, iterator chunking

Extractors - это расширение деструктуризации, которое позволяет сразу обработать деструктурированное значение.
Проще всего показать на примере
Сейчас приходится делать так:
const { field: rawField } = data 
const field = process(rawField)


Пропозал позволяет сделать так
const processData({ field }) = data


Ну и пример того как сделать простую деструктуризацию в этом пропозале
class C {
#data;
constructor(data) {
this.#data = data;
}
[Symbol.customMatcher](subject) {
return #data in subject && [this.#data];
}
}

const subject = new C({ x: 1, y: 2 });

const C({ x, y }) = subject;
x; // 1
y; // 2


structs добавляет структуры в язык. Это более строгая версия классов. Эта штука нужна для повышения производительности (в том числе для кейсов с воркерами)

struct Box {
constructor(x) { this.x = x; }
x;
}

let box = new Box(0);
box.x = 42; // x is declared
assertThrows(() => { box.y = 8.8; }); // structs are sealed
assertThrows(() => { box.__proto__ = {}; }); // structs are sealed


iterator chunking - мега простой пропозал, позволяет нарезать итератор на куски
const digits = () => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].values();
let chunksOf2 = Array.from(digits().chunks(2));
// [ [0, 1], [2, 3], [4, 5], [6, 7], [8, 9] ]



https://ecmascript-daily.github.io/ecmascript/2024/10/12/ecmascript-proposal-update

#development #javascript #ecmascript #proposal
Announcing Deno 2

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

Что нового в Deno 2 (согласно статье):
- Обратная совместимость с nodejs и npm (можно запустить свое node.js приложение в deno без дополнительных усилий)
- Поддержка package.json и node_modules
- Свой менеджер пакетов - deno install, deno add, deno remove
- Стандартная библиотека (вместо десятка пакетов из npm)
- Поддержка приватных реджистри
- Поддержка воркспейсов и монорепо
- LTS-релизы
- JSR - свой модный реджистри пакетов

Также улучшили много существующих фичей:
- deno fmt теперь умеет в HTML, CSS, YAML
- deno lint теперь умеет в специфику Node
- deno test теперь поддерживает тесты, написанные с помощью node:test
- deno task запускает скрипты из scripts
- deno doc - улучшили вывод
- deno compile - поддерживает подпись и иконки для Windows
- deno serve теперь умеет запускать сервер на нескольких ядрах
- deno init позволяет инициализировать библиотеки и сервера
- deno jupyter теперь поддерживает изображения, графы и HTML
- deno bench теперь более точно замеряет
- deno coverage теперь умеет отдавать вывод в HTML

https://deno.com/blog/v2.0

#development #javascript #deno #release
Дайджест за 2024-10-28 - 2024-10-31

pretty-print
pretty-print - библиотека для удобного вывода в консоль любых JS-значений. Когда делаешь обычный console.log по большим объектам, то там легко наступить на кейс, когда в каком-нибудь поле выведется Object object. Эта "проблема" решается с помощью JSON.stringify, но либа предлагает еще кучу всякого и удобного

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

Inverse Assertions
Небольшая статья, которая рассказывает как правильно проверять в тестах, что сайд-эффекта не случилось. Например, вам нужно проверить, что после клика на кнопку уведомление не появилось.

Логично сделать что-то типа expect(notification).not.toBeInTheDocument(). Но что, если нотификашка появляется не сразу?

ECMAScript proposal updates 2024-10
Пришел октябрьский апдейт по пропозалам в EcmaScript.

В 4 стейдж перешли Promise.try, Import Attributes, RegExp Modifiers, Sync Iterator helpers, JSON Modules

Announcing Deno 2
Вышел Deno 2.0. Сделали аж целое часовое видео про то, какой Deno крутой. Сам видос начинается с немного кринжовой рекламы про то, как тяжело разработчикам без Deno и как хорошо с Deno.


——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂
Максим Соснов. Двое за ноутом, не считая copilot’а, или Как внедрить парное программирование

Мое выступление на codefest про парное программирование и его применение в нашей команде.

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

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

https://www.youtube.com/watch?v=T14D2GVHGgw&list=PL8761XQAJnrb2Z-Q50OocgfyAyAMlDDEs&index=14
https://vk.com/video/@codefest/playlists?z=video-65336816_456239569%2Fclub65336816%2Fpl_-65336816_29

#development #pairProgramming #extremeProgramming #codefest #speech
Давно не делился папками с телеграм каналами 🙃

Тут завели новую тг-папку, называется "Архитектура", но это обманчивое название - там много каналов от фронтенд-разработчиков (в том числе этот канал) 😁

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

https://www.tg-me.com/addlist/Pk3F9xr4il5lZTc6
Please Stop Using Barrel Files

Статья про вред от использования barrel-файлов

Немного контекста, что такое barrel file. Это когда у нас есть папка dir с файлами someFile1.ts и someFile2.ts.
Мы могли бы импортировать их так

import { someFunction } from 'dir/someFile'
import { someFunction2 } from 'dir/someFile2'


Но есть паттерн barrel (в переводе бочка) файлов, когда мы в папке dir создаем index.ts, который ре-экспортит все внутренние сущности

dir/index.ts
export { someFunction } from './someFile'
export { someFunction2 } from './someFile2'


Использование
import { someFunction, someFunction2 } from 'dir'


Какие минусы выделяет автор у таких файлов:

Первый минус - циклические импорты. Тут автор дает какой-то странный юзкейс, когда мы в файлах внутри папки dir также делаем все импорты через index. В этом случае index импортирует модули, а модули импортируют другие модули через index. Это максимально странное использование паттерна

Второй минус уже более близок к реальности - barrel-file ведут к замедлению перформанса инструментов сборки. Когда в тулинге сборки появилась оптимизация по выбросу неиспользуемых экспортов, в сознании разработчиков это отпечаталось как "если я не использую экспорт, его стоимость для сборки - нулевая". Однако, это не так. Если вы используете jest для юнит-тестов, то вы напрямую можете столкнуться с этой проблемой, т.к. jest не занимается три-шейкингов и если вы импортируете 1 маленькую функцию из barrel-файла - вы, на самом деле, импортируете весь модуль.

Автор приводит в пример свой проект, где замена импортов на прямые ускорила сборку на 70% (также могу подтвердить такое по своему опыту борьбы с jest).

Также автор приводит в пример опыт Next.js, которые для борьбы с этой проблемой сделали фичу optimizePackageImports, которая заменяет импорты из barrel-файлов на прямые импорты во время сборки

Не смотря на минусы, такие файлы могут быть полезны, если используются по назначению: для организации публичного API библиотеки

https://tkdodo.eu/blog/please-stop-using-barrel-files

#development #javascript #barrelFile
Optimizing SPA load times with async chunks preloading

Небольшая статья про оптимизацию загрузки асинхронных чанков в SPA-приложении.

В чем вообще проблема: как правило, если у вас SPA, у вас есть роутинг, в который асинхронными чанками подключены страницы.

Если сильно утрировать, то в коде проекта есть что-то типа:
const routes = {
'/': import('pages/main'),
'/search': import('pages/search')
}


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

Примерно та же проблема есть и при навигации. Пользователь делает действие, которое должно перекинуть его на страницу search и снова ждет загрузки скрипта.

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

5 простых шагов для реализации идеи:
- Добавляем имена чанкам import(/* webpackChunkName: "main" */ "./pages/main")
- Пишем плагин (в случае автора - плагин для RSPack)
- Плагин получает стату сборки и из нее достает ссылку до именованного чанка
- В проекте заводится способ нахождения имени чанка по текущему урл
- Плагин инжектит скрипт в head, который на основе window.loocation.href находит нужное имя чанка и инжектит ссылку до чанка в link rel=preload.

Таким образом достигается ускорение загрузки страниц.

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

https://mmazzarolo.com/blog/2024-08-13-async-chunk-preloading-on-load/

#development #javascript #performance
React Switchboard

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

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

https://github.com/coryhouse/react-switchboard

#development #javascript #react #library
Дайджест за 2024-11-05 - 2024-11-08

Максим Соснов. Двое за ноутом, не считая copilot’а, или Как внедрить парное программирование
Мое выступление на codefest про парное программирование и его применение в нашей команде.

Please Stop Using Barrel Files
Статья про вред от использования barrel-файлов.

Optimizing SPA load times with async chunks preloading
Небольшая статья про оптимизацию загрузки асинхронных чанков в SPA-приложении.

React Switchboard
React-switchboard - библиотека для создания своих дев-тулов в приложении. Под дев-тулами тут имеются в виду быстрый способ управлять поведением приложения. Например, залогиниться под определенным юзером, получить какое-то специфичное состояние или настройка мокирования определенных сетевых запросов.

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

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂
Crafting a 13KB Game: The Story of Space Huggers

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

Данная статья - как раз одна из таких. Автор одной из игр делится тем, как создать такую игру. Здесь не так много технических деталей, связанных с JS, но зато очень много про сам гейм-дизайн и про принятие решений.

Хорошее чтиво на вечер

https://frankforce.com/space-huggers-how-i-made-a-game-in-13-kilobytes/

#development #javascript #game
Announcing Official Puppeteer Support for Firefox

Наконец-то появилась официальная поддержка firefox в puppeteer. Теперь можно использовать puppeteer для работы с firefox.

Из интересных технических деталей в статье: было два основных варианта для реализации интеграции с puppeteer:
- Использовать WebDriver BiDi протокол. Это штука, которая была стандартизирована еще w3c и поверх нее, как я помню, работает selenium
- Использовать CDP (chrome dev-tools protocol), по которому puppeteer работает с хромом, т.е. по сути надо имплементировать CDP в firefox; Или сделать интеграцию puppeteer с RDP - это аналог CDP но для firefox

Сначала попробовали сделать экспериментальную и ограниченную поддержку CDP в firefox. Но решили что лучше идти в сторону Webdriver BiDi, как более стандартизированная и кросс-браузерная штука.

https://hacks.mozilla.org/2024/08/puppeteer-support-for-firefox/

#development #javascript #puppeteer #firefox
Common Causes of Memory Leaks in JavaScript

Хорошая статья про утечки памяти.

Статья начинается с разбора типов памяти в V8.

Есть:
- RSS (Resident Set Size) - все используемая память
- Heap Total - Память выделенная под JS-объекты
- Heap Used - Память, используемая JS-объектами
- External - Память под С++ объекты, прилинкованные к JS объектам
- Array Buffers - Память выделенная под ArrayBuffer. Используется для хранения бинарных данных

Получить текущее использования можно так

console.log('Initial Memory Usage:', process.memoryUsage());


Initial Memory Usage: {
rss: 38502400,
heapTotal: 4702208,
heapUsed: 2559000,
external: 1089863,
arrayBuffers: 10515
}



Основные причины утечки памяти:
- Плохая работа с данными. Например, когда данные уже не нужны, а мы все еще их храним (в глобальной переменной или в замыкании)
- Плохая работа с event listeners. Если их не удалять, после того как они стали не нужны, они будут также держать объекты и защищать их от сборки
- Замыкания
- Некорректной использование bind. Например, мы забиндили метод к this, но в методе this не используется. В этом случае из-за bind GC не сможет собрать то, на что забинжена функция (this).
- Циклические зависимости (пример в статье интересный - this.reference = this;

Третья часть статьи описывает, как же профилировать использование памяти в ноде.

Сначала надо запустить процесс с записью лога node --prof server.js
Затем необходимо прочитать лог node --prof-process isolate-0x140008000-42065-v8.log > processed-profile.txt

Что выдаст в файл человеко-читаемый профайлинг, где описано, какие функции запускались, сколько времени заняли, какие объекты аллоцированы

https://www.trevorlasn.com/blog/common-causes-of-memory-leaks-in-javascript

#development #javascript #performance #memoryLeak
How we shrunk our Javascript monorepo git size by 94%

У статьи очень кликбейтное название. Я сначала подумал, что чуваки комитили node_modules и теперь решили его удалить или что-то в этом роде. Но все оказалось куда интереснее.

Есть команда в Microsoft, которая разрабатываем в большом монорепо на JS. Называется это 1JS, в нем около 20 миллионов строк кода, 2500 пакетов, а клонирование требует 178 гигабайт дискового пространства и некоторые коллеги из Европы (странное уточнение от автора, ну да ладно) не могли его склонировать.

История про клонирование 178 гигабайт звучит очень странно т.к. я точно помню, что microsoft делала свою файловую систему для работы с огромными гит-репозиториями, которая решает проблему клонирования "лишних" файлов. Ну, видимо в репозитории 1JS это не так.

В репозитории есть 2 основных ветки - mainи versioned. В первой ведется разработка, во второй ведутся релизы. По сути ветка versioned хранит в себе изменения CHANGELOG.md и CHANGELOG.json. На удивление, обнаружилось, что именно эти файлы приводят к тому, что в дереве гита приходится хранить дополнительные 125 гигабайт данных.

Почему так? По умолчанию, алгоритм запаковки изменений и снапшотов в git для идентификации файла использует только последние 16 символов названия файла. Поэтому, если изменить repo/packages/foo/CHANGELOG.json, то git будет собирать diff и к repo/packages/bar/CHANGELOG.json (пересчитал символы, у меня получилось что 15 совпадают, а 16 отличается. Либо я не так считаю, либо что-то не так понял). Т.к. это монорепо с 2500 пакетов, то ченджлогов много и git считает дифф каждый к каждому (опять же, если я правильно понял).

Это можно поправить, увеличив окно для сравнения. Для этого ребята добавили возможность регулировать это окно в git for windows. После перепаковки репозитория, размер уменьшился с 178ГБ до 5ГБ.

Очень интересная история с неожиданной развязкой. Никогда бы не подумал что ведение ченджлога может привести к 94% затрат на размер репозитория.

https://www.jonathancreamer.com/how-we-shrunk-our-git-repo-size-by-94-percent/

#development #javascript #performance #monorepo #git #microsoft
Самые тяжелые NPM пакеты

Одновременно интересная и практически бесполезная таблица с самыми тяжелыми npm пакетами и тем, сколько мирового интернет траффика они потребляют.

Рассчет трафика достаточно простой: берем вес tar.gz пакета, берем количество загрузок в неделю, перемножаем, получаем трафик в неделю

Самый большой трафик создают swc, typescript, next, esbuild, aws-sdk, pnpm, prettier, date-fns

Jquery на 178 месте по трафика. React-dom - 28, сам React - 275.

В целом можно посмотреть за популярностью инструментов для сборки и самыми популярными либами.



https://docs.google.com/spreadsheets/d/1oYJxQgMA7lQ6-wNaBKNNDz6vr3Yaa1EDsI_Hakr4ROg/edit?gid=1891857584#gid=1891857584

#development #javascript #npm
Дайджест за 2024-11-11 - 2024-11-15

Crafting a 13KB Game: The Story of Space Huggers
Периодически проходит интересный челлендж - необходимо создать игру на JS, которая поместится в 13кб. Всегда интересно почитать, как люди делают полноценные игры и умещают их в такой крохотный размер.

Данная статья - как раз одна из таких. Автор одной из игр делится тем, как создать такую игру. Здесь не так много технических деталей, связанных с JS, но зато очень много про сам гейм-дизайн и про принятие решений.

Announcing Official Puppeteer Support for Firefox
Наконец-то появилась официальная поддержка firefox в puppeteer. Теперь можно использовать puppeteer для работы с firefox.

Из интересных технических деталей в статье: было два основных варианта для реализации интеграции с puppeteer:

Common Causes of Memory Leaks in JavaScript
Хорошая статья про утечки памяти.

How we shrunk our Javascript monorepo git size by 94%
У статьи очень кликбейтное название. Я сначала подумал, что чуваки комитили node_modules и теперь решили его удалить или что-то в этом роде. Но все оказалось куда интереснее.

Есть команда в Microsoft, которая разрабатываем в большом монорепо на JS. Называется это 1JS, в нем около 20 миллионов строк кода, 2500 пакетов, а клонирование требует 178 гигабайт дискового пространства и некоторые коллеги из Европы (странное уточнение от автора, ну да ладно) не могли его склонировать.

Самые тяжелые NPM пакеты
Одновременно интересная и практически бесполезная таблица с самыми тяжелыми npm пакетами и тем, сколько мирового интернет траффика они потребляют.

Рассчет трафика достаточно простой: берем вес tar.gz пакета, берем количество загрузок в неделю, перемножаем, получаем трафик в неделю

——————————————

Спасибо что читаете, ставите реакции и отмечаетесь в комментариях. Если вы хотите помочь каналу - расскажите о нем своим коллегам или друзьям. Также оставляйте фидбек по формату, материалу и чему-угодно еще 🙂
2025/07/06 17:02:44
Back to Top
HTML Embed Code: