Наткнулся на шикарную штуку для визуализации регэкспов - Regexper https://regexper.com/#%5E%28%5C%2F.*%29%3F%5C%2F.*
Строит действительно понятную диаграмму того, что будет происходить в вашем регэкспе.
Для тестирования регэкспов всегда пользовался https://regex101.com/ - но там хоть и есть описание поведения каждого токена, такой диаграммы не хватает.
Вот бы их еще и совместить - проблема регэкспов была бы навсегда решена.
Строит действительно понятную диаграмму того, что будет происходить в вашем регэкспе.
Для тестирования регэкспов всегда пользовался https://regex101.com/ - но там хоть и есть описание поведения каждого токена, такой диаграммы не хватает.
Вот бы их еще и совместить - проблема регэкспов была бы навсегда решена.
Разработка трекера привычек идёт.
Я взял небольшую паузу и не делился ходом разработки, чтобы разобраться насколько удобно работать с Expo SQLite и что лучше использовать - чистые SQL запросы или все же какой-то ORM.
Я однажды пробовал подключить TypeORM на Expo и это была мука - нужно было включать какие-то экспериментальные флаги, накатывать патчи - в общем работало тогда это очень плохо. Да и приложение довольно простое - в ORM смысла особенно нет.
И тут я решил попробовать Drizzle https://orm.drizzle.team/ и остался в полном восторге.
Drizzle - это так называемый SQL builder - он даёт очень лёгкие абстракции поверх SQL - т.е. вместо того чтобы написать:
ты пишешь:
тоже самое будет и с джоинами:
вместо:
пишешь:
По сути ты пишешь SQL и этот SQL выполняется как есть без лишней магии и дополнительных вычислений. Ну и соответственно производительность запроса через Drizzle такая же как наивный запрос с помощью чистого SQL.
Почему бы тогда не остаться на чистом SQL?
Вот тут самая главная прелесть Drizzle - до того, как начать работать с базой и делать запросы ты описываешь ее схему. И все полученные данные приходят тебе уже с типами.
Плюс удобный инструмент для миграции - если схема поменялась, Drizzle сам мигрирует существующую базу, плюс админка для работы с базой на Expo - если например к сторонней базе ты можешь подключится любым SQL клиентом, то Expo SQLite не поддерживает сторонние подключения, а тут данные можно редактировать в UI - очень удобно.
Я взял небольшую паузу и не делился ходом разработки, чтобы разобраться насколько удобно работать с Expo SQLite и что лучше использовать - чистые SQL запросы или все же какой-то ORM.
Я однажды пробовал подключить TypeORM на Expo и это была мука - нужно было включать какие-то экспериментальные флаги, накатывать патчи - в общем работало тогда это очень плохо. Да и приложение довольно простое - в ORM смысла особенно нет.
И тут я решил попробовать Drizzle https://orm.drizzle.team/ и остался в полном восторге.
Drizzle - это так называемый SQL builder - он даёт очень лёгкие абстракции поверх SQL - т.е. вместо того чтобы написать:
SELECT * FROM test
ты пишешь:
db.select().from(test);
тоже самое будет и с джоинами:
вместо:
SELECT * FROM users LEFT JOIN pets ON users.user_id = pets.owner_id
пишешь:
db.select().from(users).leftJoin(pets, eq(users.id, pets.ownerId));
По сути ты пишешь SQL и этот SQL выполняется как есть без лишней магии и дополнительных вычислений. Ну и соответственно производительность запроса через Drizzle такая же как наивный запрос с помощью чистого SQL.
Почему бы тогда не остаться на чистом SQL?
Вот тут самая главная прелесть Drizzle - до того, как начать работать с базой и делать запросы ты описываешь ее схему. И все полученные данные приходят тебе уже с типами.
Плюс удобный инструмент для миграции - если схема поменялась, Drizzle сам мигрирует существующую базу, плюс админка для работы с базой на Expo - если например к сторонней базе ты можешь подключится любым SQL клиентом, то Expo SQLite не поддерживает сторонние подключения, а тут данные можно редактировать в UI - очень удобно.
orm.drizzle.team
Drizzle ORM - next gen TypeScript ORM.
Drizzle ORM is a lightweight and performant TypeScript ORM with developer experience in mind.
This media is not supported in your browser
VIEW IN TELEGRAM
В субботу установил превью версию трекера на свой телефон и нужно сказать, что один довольный юзер у этого приложения уже есть 😂
Осталось привести в порядок внешний вид и можно будет выкладывать в Google Play (дедлайн у меня 16 число).
Т.к. всю бизнес логику и работу с хранилищем я провел оффлайн, хочу в субботу записать на стриме видос о том, как работать с Expo SQLite с помощью Drizzle - в этот раз долгих размышлений не будет, весь код уже готов - буду просто показывать, что сделано.
Так, что если будет минутка - забегайте:
https://youtube.com/@featinitialcommit
https://www.twitch.tv/feat_initial_commit
https://live.vkvideo.ru/initial_commit
Стрим начнётся в 10:00 GMT+2
Осталось привести в порядок внешний вид и можно будет выкладывать в Google Play (дедлайн у меня 16 число).
Т.к. всю бизнес логику и работу с хранилищем я провел оффлайн, хочу в субботу записать на стриме видос о том, как работать с Expo SQLite с помощью Drizzle - в этот раз долгих размышлений не будет, весь код уже готов - буду просто показывать, что сделано.
Так, что если будет минутка - забегайте:
https://youtube.com/@featinitialcommit
https://www.twitch.tv/feat_initial_commit
https://live.vkvideo.ru/initial_commit
Стрим начнётся в 10:00 GMT+2
Ура, друзья!
Мой аккаунт не будет удалён.
Я поправил верстку, и опубликовал приложение в закрытый тест. Кстати, чтобы выполнить требование по активности аккаунта, достаточно было просто публикации для внутреннего теста.
Вообще Гугл имеет три уровня публикации:
1. Внутренний тест (internal testing) - для первоначального тестирования того как будет выглядеть приложение на реальных устройствах - не нужно настраивать вид странички приложения в сторе, тестеры скачивают его просто по ссылке.
2. Закрытый тест (closed testing) - нужно тестировать приложение на реальных устройствах в течении двух недель, тестеров должно быть не менее 12 человек. Нужно оформить страничку приложения, согласиться с политиками и офертами, указать какие данные пользователя используются и как.
3. Продакшн - приложение публично доступно в Google Play Store.
И теперь, когда приложение в закрытом тесте, мне нужны 12 добровольцев, которые поставят его себе на устройство и будут пользоваться 2 недели 😅
В общем, ребята, если есть желание помочь пожалуйста пошэрьте свои адреса Гугл аккаунтов и попользуйтесь две недельки (нужны адреса к которым привязан Google Store, иначе установить не удастся).
Я сделал форму, чтобы можно было пошэрить адреса только со мной https://docs.google.com/forms/d/e/1FAIpQLSekYYQBfxdAJNB-r8cxeKQXRptsPRtY_iuk9o6TjmSG7F4gMA/viewform?usp=header
Там можно анонимно пошэрить только адрес - я добавлю вас в список и приложение можно будет скачать по этой ссылке в Google Store - https://play.google.com/store/apps/details?id=com.artabr.streakTracker
Мой аккаунт не будет удалён.
Я поправил верстку, и опубликовал приложение в закрытый тест. Кстати, чтобы выполнить требование по активности аккаунта, достаточно было просто публикации для внутреннего теста.
Вообще Гугл имеет три уровня публикации:
1. Внутренний тест (internal testing) - для первоначального тестирования того как будет выглядеть приложение на реальных устройствах - не нужно настраивать вид странички приложения в сторе, тестеры скачивают его просто по ссылке.
2. Закрытый тест (closed testing) - нужно тестировать приложение на реальных устройствах в течении двух недель, тестеров должно быть не менее 12 человек. Нужно оформить страничку приложения, согласиться с политиками и офертами, указать какие данные пользователя используются и как.
3. Продакшн - приложение публично доступно в Google Play Store.
И теперь, когда приложение в закрытом тесте, мне нужны 12 добровольцев, которые поставят его себе на устройство и будут пользоваться 2 недели 😅
В общем, ребята, если есть желание помочь пожалуйста пошэрьте свои адреса Гугл аккаунтов и попользуйтесь две недельки (нужны адреса к которым привязан Google Store, иначе установить не удастся).
Я сделал форму, чтобы можно было пошэрить адреса только со мной https://docs.google.com/forms/d/e/1FAIpQLSekYYQBfxdAJNB-r8cxeKQXRptsPRtY_iuk9o6TjmSG7F4gMA/viewform?usp=header
Там можно анонимно пошэрить только адрес - я добавлю вас в список и приложение можно будет скачать по этой ссылке в Google Store - https://play.google.com/store/apps/details?id=com.artabr.streakTracker
Решил попробовать Vitest.
А подтолкнуло меня к этому вот это видео с Артемом Захарченко про Mock Service Worker - https://youtu.be/-g_jGlIbJys?t=2973&si=42y5PRXrxt8iKRCU
Ссылку вставил на конкретный момент про Vitest, но советую посмотреть все видео - там Артем очень подробно рассказывает про архитектуру MSW, его преимущества и вообще про юнит тестирование в целом.
MSW кстати потрясающая библиотека, и по сути должна являться стандартом для мокирования запросов. Первый фронтенд фреймворк, который приходит на ум - это Next, а вот первая библиотека для моков API - должен быть MSW, только так.
Но возвращаясь к Vitest, я очень долго откладывал знакомство с ним, т.к. чтобы попробовать его в рабочем проекте нужно переписать несколько тысяч тестов с Jest (это был бы шикарный опыт, может быть однажды 😁), а просто документация и простые примеры не дадут понять тонкости.
Поэтому буду писать тесты для трекера на Vitest.
А подтолкнуло меня к этому вот это видео с Артемом Захарченко про Mock Service Worker - https://youtu.be/-g_jGlIbJys?t=2973&si=42y5PRXrxt8iKRCU
Ссылку вставил на конкретный момент про Vitest, но советую посмотреть все видео - там Артем очень подробно рассказывает про архитектуру MSW, его преимущества и вообще про юнит тестирование в целом.
MSW кстати потрясающая библиотека, и по сути должна являться стандартом для мокирования запросов. Первый фронтенд фреймворк, который приходит на ум - это Next, а вот первая библиотека для моков API - должен быть MSW, только так.
Но возвращаясь к Vitest, я очень долго откладывал знакомство с ним, т.к. чтобы попробовать его в рабочем проекте нужно переписать несколько тысяч тестов с Jest (это был бы шикарный опыт, может быть однажды 😁), а просто документация и простые примеры не дадут понять тонкости.
Поэтому буду писать тесты для трекера на Vitest.
YouTube
Mastering Mocking in Automated Tests with Artem Zakharchenko
Artem on X: https://x.com/kettanaito
Artem's course: https://www.epicweb.dev/workshops/testing-fundamentals
Cory on X: https://x.com/housecor
Cory's courses: http://pluralsight.com/authors/cory-house
Cory's consultancy: http://reactjsconsulting.com
Cory…
Artem's course: https://www.epicweb.dev/workshops/testing-fundamentals
Cory on X: https://x.com/housecor
Cory's courses: http://pluralsight.com/authors/cory-house
Cory's consultancy: http://reactjsconsulting.com
Cory…
Закрытие окна загрузки файлов закрывает родительскую модалку с ролью "dialog"
Представьте вы открыли модальное окно с формой, заполнили кучу данных, и внизу видите поле для загрузки файла (например, опционально, вашего аватара), вы открыли окно загрузки файлов, а потом передумали и нажали Отмена, предполагая, что закроется только окно загрузки файлов.
Вместо этого закрывается и модалка вместе с формой. И вашими данными.
Так вот, оказывается cancel ивент из нативного окна выбора файлов, которое открывается при клике на
И если вы поставили обработчик onCancel на этот элемент - то он будет выполнен.
Судя по всему, изначально, когда этот баг только появился, событие cancel не просто триггерило обработчик, но и натурально закрывало диалог - https://stackoverflow.com/questions/76372090/cancel-input-file-close-dialog-element. Сейчас же это поведение пофиксили, но обработчик все равно вызывается - https://jsfiddle.net/artabr/b6k4r19o/.
Зачем так сделано - до конца непонятно, ведь отменяется вложенный диалог, который мы по сути даже не рендерим и никак на него не влияем. А событие триггерится в родительском, в том же месте, где и его собственное событие отмены. Единственный положительный момент, что target в событии все равно указывает на наш input и хотя-бы позволяет отфильтровать это событие и не выполнять те действия, которые мы выполняем при закрытие основного диалога.
Поведение на мой взгляд очень сильно похоже на баг, по крайней мере крайне неочевидно.
А началось все с безобидного добавления
Представьте вы открыли модальное окно с формой, заполнили кучу данных, и внизу видите поле для загрузки файла (например, опционально, вашего аватара), вы открыли окно загрузки файлов, а потом передумали и нажали Отмена, предполагая, что закроется только окно загрузки файлов.
Вместо этого закрывается и модалка вместе с формой. И вашими данными.
Так вот, оказывается cancel ивент из нативного окна выбора файлов, которое открывается при клике на
<input type="file" />
, всплывает в родительский <dialog />
или элемент с этой ролью (role="dialog"
).И если вы поставили обработчик onCancel на этот элемент - то он будет выполнен.
Судя по всему, изначально, когда этот баг только появился, событие cancel не просто триггерило обработчик, но и натурально закрывало диалог - https://stackoverflow.com/questions/76372090/cancel-input-file-close-dialog-element. Сейчас же это поведение пофиксили, но обработчик все равно вызывается - https://jsfiddle.net/artabr/b6k4r19o/.
Зачем так сделано - до конца непонятно, ведь отменяется вложенный диалог, который мы по сути даже не рендерим и никак на него не влияем. А событие триггерится в родительском, в том же месте, где и его собственное событие отмены. Единственный положительный момент, что target в событии все равно указывает на наш input и хотя-бы позволяет отфильтровать это событие и не выполнять те действия, которые мы выполняем при закрытие основного диалога.
Поведение на мой взгляд очень сильно похоже на баг, по крайней мере крайне неочевидно.
А началось все с безобидного добавления
role="dialog"
- спасибо WCAG 😁Stack Overflow
Cancel input file close dialog element
I have a dialog to show to user an input type file. I have an issue when the user canceled the input file or when he chooses the same file, that closes my dialog. I don't want that, so I added event
Выложил на Гитхаб свой сервис, который делает RSS ленту из постов в Telegram канале - https://github.com/artabr/tg-rss-feed
RSS ленту потом можно транслировать на другие платформы. Например, разместить у себя на сайте или делать репосты.
Не нашёл похожего функционала в бесплатном варианте (на rss.app есть что-то подобное, но за $10 в месяц) - пришлось сделать самому.
Проверить можно тут: https://tg-rss-feed.vercel.app/feed/feat_initial_commit (вместо feat_initial_commit поставьте свой канал).
К сожалению, из-за того, что список всех сообщений недоступен в API для ботов, приходится забирать сообщения последовательным перебором, и на канале с большой историей наверняка будут ошибки по таймауту, но я кэширую полученные сообщения (пока жива serverless функция) и после нескольких вызовов, вы все равно должны получить свою ленту.
Если кому-то ещё пригодится, буду благодарен, если поставите звезду в4️⃣ GitHub
RSS ленту потом можно транслировать на другие платформы. Например, разместить у себя на сайте или делать репосты.
Не нашёл похожего функционала в бесплатном варианте (на rss.app есть что-то подобное, но за $10 в месяц) - пришлось сделать самому.
Проверить можно тут: https://tg-rss-feed.vercel.app/feed/feat_initial_commit (вместо feat_initial_commit поставьте свой канал).
К сожалению, из-за того, что список всех сообщений недоступен в API для ботов, приходится забирать сообщения последовательным перебором, и на канале с большой историей наверняка будут ошибки по таймауту, но я кэширую полученные сообщения (пока жива serverless функция) и после нескольких вызовов, вы все равно должны получить свою ленту.
Если кому-то ещё пригодится, буду благодарен, если поставите звезду в
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - artabr/tg-rss-feed
Contribute to artabr/tg-rss-feed development by creating an account on GitHub.
Вот это действительно стоит посмотреть.
Ни кто иной как Matt Pocock сделал курс по MCP.
Его вклад в JS экосистему сложно переоценить - XState, Total TypeScript и всегда очень качественные обучающие видео.
Для меня это значит две вещи: MCP - это действительно штука, которую стоит изучить подробнее. И то, что теперь можно сделать это без лишней шелухи, с грамотным объяснением от Мэтта.
https://www.aihero.dev/model-context-protocol-tutorial
Ни кто иной как Matt Pocock сделал курс по MCP.
Его вклад в JS экосистему сложно переоценить - XState, Total TypeScript и всегда очень качественные обучающие видео.
Для меня это значит две вещи: MCP - это действительно штука, которую стоит изучить подробнее. И то, что теперь можно сделать это без лишней шелухи, с грамотным объяснением от Мэтта.
https://www.aihero.dev/model-context-protocol-tutorial
www.aihero.dev
Model Context Protocol Tutorial
The Model Context Protocol is driving a new wave of innovation in the world of AI. In this tutorial, I'll break down everything you need to know to get started.
Что по трекеру?
Изначально идея была лишь в том, чтобы выложить в Google Play хоть какое-то приложение.
После того как выяснилось, что публиковать в общий доступ чтобы сохранить аккаунт не обязательно, планы слегка изменились.
Я решил делать полноценное приложение. Хотелось бы иметь личный кабинет, синхронизацию между устройствами, чтобы была возможность добавлять разные привычки, с разным графиком исполнения и нотификаций.
В общем планов много, да и как-то прикипел я к этому проекту. Прикольно наблюдать как он из простейшей поделки на Expo Go становится взрослым приложением, у которого есть своя страничка на Google Play. А дальше ведь еще больше всего.
А еще проект решил поддержать мой товарищ - UI/UX дизайнер. И теперь приложение будет еще и приятным на вид и удобным в использовании.
Понятное дело фронт работы значительно увеличился, поэтому переносим сроки релиза - предварительно на конец июня.
Кстати, если вы знаете кого-то, или возможно сами захотите присоединиться к проекту - напишите мне в личку.
Вся разработка в опен сорсе. Кроме приложения ещё есть классические фронт задачи. Из приоритетного уже понятно, что нужно делать мультиязычный лэндинг и блог на Next.js.
Изначально идея была лишь в том, чтобы выложить в Google Play хоть какое-то приложение.
После того как выяснилось, что публиковать в общий доступ чтобы сохранить аккаунт не обязательно, планы слегка изменились.
Я решил делать полноценное приложение. Хотелось бы иметь личный кабинет, синхронизацию между устройствами, чтобы была возможность добавлять разные привычки, с разным графиком исполнения и нотификаций.
В общем планов много, да и как-то прикипел я к этому проекту. Прикольно наблюдать как он из простейшей поделки на Expo Go становится взрослым приложением, у которого есть своя страничка на Google Play. А дальше ведь еще больше всего.
А еще проект решил поддержать мой товарищ - UI/UX дизайнер. И теперь приложение будет еще и приятным на вид и удобным в использовании.
Понятное дело фронт работы значительно увеличился, поэтому переносим сроки релиза - предварительно на конец июня.
Кстати, если вы знаете кого-то, или возможно сами захотите присоединиться к проекту - напишите мне в личку.
Вся разработка в опен сорсе. Кроме приложения ещё есть классические фронт задачи. Из приоритетного уже понятно, что нужно делать мультиязычный лэндинг и блог на Next.js.
Только NX нормально работает с Expo
Выбирал тулинг для монорепо - появляются кастомные компоненты, которые хотелось бы релизить отдельно от основного приложения, да и веб версия когда нибудь появится.
Сейчас существует несколько вариантов для организации монорепо - нативный функционал бандлеров (NPM/Yarn/PNPM Workspaces), NX и хайповый Turborepo.
Мой стандартный выбор - это NX. Обожаю NX.
Но тут решил посмотреть, что же предлагает Turborepo. Turbo используют популярные темплейты типа t3-stack, вообщем-то все темплейты, которые я нашёл, использовали Turbo - думаю, наверное, должно работать хорошо.
И оно работает. До тех пор пока не делаешь собственный дев билд с помощью prebuild. С Expo Go работает прекрасно, как только делаешь пребилд - все разваливается. А без пребилда по сути нельзя делать нормальные приложения.
В моем случае билд не собирается, потому что при сборке в Turbo откуда-то появляется старая версия Котлина. Есть ещё и другие приколы - типа в Турбо нужно прямо указывать в конфиге какие энв переменные нужно передавать в билд (например ANDROID_HOME) - зачем, я так и не понял - но это не баг конечно, скорее скилл ишью с моей стороны, они решили сделать именно так, и в доке это прописано. Просто странно.
В NX в случае с Expo не работает терминал Expo CLI - не работают шорткаты a, r, shift+m и т.д. Но если запускать напрямую, не через NX CLI - то все прекрасно работает.
И вот тут основная прелесть NX. По сути если упростить, то NX сейчас - это утилита, которая раскидывает твои проекты по папкам, и корректно настраивает пути в tsconfig. Все, после этого ты можешь пользоваться своими проектами как обычно. И только если это требуется, сверху уже можно добавлять кэшинг, общий конфиг линтеров, зависимости между задачами и т.д. У NX есть куча аддонов, как от самой команды NX, так и от коммьюнити, которые позволяют расширять функционал.
В моем случае проект также работает на Bun, с Biome в качестве линтера, и забирает компонент с библиотеки, которая будет отдельным пайплайном публиковаться в NPM. Просто теперь этим стало чуть удобнее управлять.
Выбирал тулинг для монорепо - появляются кастомные компоненты, которые хотелось бы релизить отдельно от основного приложения, да и веб версия когда нибудь появится.
Сейчас существует несколько вариантов для организации монорепо - нативный функционал бандлеров (NPM/Yarn/PNPM Workspaces), NX и хайповый Turborepo.
Мой стандартный выбор - это NX. Обожаю NX.
Но тут решил посмотреть, что же предлагает Turborepo. Turbo используют популярные темплейты типа t3-stack, вообщем-то все темплейты, которые я нашёл, использовали Turbo - думаю, наверное, должно работать хорошо.
И оно работает. До тех пор пока не делаешь собственный дев билд с помощью prebuild. С Expo Go работает прекрасно, как только делаешь пребилд - все разваливается. А без пребилда по сути нельзя делать нормальные приложения.
В моем случае билд не собирается, потому что при сборке в Turbo откуда-то появляется старая версия Котлина. Есть ещё и другие приколы - типа в Турбо нужно прямо указывать в конфиге какие энв переменные нужно передавать в билд (например ANDROID_HOME) - зачем, я так и не понял - но это не баг конечно, скорее скилл ишью с моей стороны, они решили сделать именно так, и в доке это прописано. Просто странно.
В NX в случае с Expo не работает терминал Expo CLI - не работают шорткаты a, r, shift+m и т.д. Но если запускать напрямую, не через NX CLI - то все прекрасно работает.
И вот тут основная прелесть NX. По сути если упростить, то NX сейчас - это утилита, которая раскидывает твои проекты по папкам, и корректно настраивает пути в tsconfig. Все, после этого ты можешь пользоваться своими проектами как обычно. И только если это требуется, сверху уже можно добавлять кэшинг, общий конфиг линтеров, зависимости между задачами и т.д. У NX есть куча аддонов, как от самой команды NX, так и от коммьюнити, которые позволяют расширять функционал.
В моем случае проект также работает на Bun, с Biome в качестве линтера, и забирает компонент с библиотеки, которая будет отдельным пайплайном публиковаться в NPM. Просто теперь этим стало чуть удобнее управлять.
Одно из главных преимуществ Expo всегда было удобство разработки.
Ты делаешь изменения в коде, они сразу появляются в Expo Go, Expo Go может скачать любой человек, ввести ссылку на дев сервер и увидеть текущие изменения.
В Expo Go не работают нативные функции, но теперь для этого появилась возможность создать кастомный клиент на подобие Expo Go, но конкретно под ваше приложение с помощью команды prebuild.
Этот клиент тоже будет просить ссылку на дев сервер и сперва я думал, что придется крутить собственный сервер, к которому будут подключаться заинтересованные лица (в моем случае дизайнер). Сделал даже пайплайн в GitHub Actions, который собирает текущий коммит в докер образ, и деплоит это все на сервер.
И оно даже работает, правда медленно - каждый раз дев сервер пересобирает бандл, что даёт задержку при первой загрузки дев версии приложения.
А оказывается все было проще. В Expo есть сервис EAS Update, который позволяет упаковать текущее состояние приложения, и открыть его из дев клиента. И никакого сервера не нужно. Достаточно ссылку дизайнеру ссылку на apk дев клиента и QR апдейта.
А вот уже сами апдейты можно собирать в GH Actions по коммиту.
Ты делаешь изменения в коде, они сразу появляются в Expo Go, Expo Go может скачать любой человек, ввести ссылку на дев сервер и увидеть текущие изменения.
В Expo Go не работают нативные функции, но теперь для этого появилась возможность создать кастомный клиент на подобие Expo Go, но конкретно под ваше приложение с помощью команды prebuild.
Этот клиент тоже будет просить ссылку на дев сервер и сперва я думал, что придется крутить собственный сервер, к которому будут подключаться заинтересованные лица (в моем случае дизайнер). Сделал даже пайплайн в GitHub Actions, который собирает текущий коммит в докер образ, и деплоит это все на сервер.
И оно даже работает, правда медленно - каждый раз дев сервер пересобирает бандл, что даёт задержку при первой загрузки дев версии приложения.
А оказывается все было проще. В Expo есть сервис EAS Update, который позволяет упаковать текущее состояние приложения, и открыть его из дев клиента. И никакого сервера не нужно. Достаточно ссылку дизайнеру ссылку на apk дев клиента и QR апдейта.
А вот уже сами апдейты можно собирать в GH Actions по коммиту.
Все больше крупных компаний вводят владение AI инструментами как базовый навык для своих сотрудников.
На это раз Spotify https://x.com/tobi/status/1909251946235437514
Всё, теперь это база. Потому что работает.
На это раз Spotify https://x.com/tobi/status/1909251946235437514
Всё, теперь это база. Потому что работает.
Эксперимент с NativeWind закончился неудачно.
Проблема не с синтаксисом TW (работать с ним как раз очень удобно, и если нет специфичных требований в виде расширенной темизации, и тем более если делаешь прототип - очень приятно).
Проблема в том, как NativeWind сейчас работает - под капотом NativeWind преобразует ваши TW классы в React Native StyleSheet - и этот дополнительный шаг вызывает дополнительные проблемы. Во первых, это заметно во время разработки - ты добавляешь класс, и долю секунды бандлер думает, просчитывает, и добавляет нужный StyleSheet.
Во вторых, иногда он просто их не добавляет. Реально. Есть куча ишью на ГХ, где люди описывают свои пропавшие стили. В основном, такие ишью закрыты как stale, и складывается что люди просто не получают решения и уходят от NativeWind (как и я).
В вебе это в целом так же работает, но видимо из-за того, что в вебе тулинг для TW более взрослый и оптимизированный, задержек и тем более потерей стилей нет.
Выходит, что NativeWind добавляет ещё один слой в систему, в которой и так уже слишком много слоев.
Складывается впечатление, что если core команда React Native не добавит нативную стилизацию с помощью TW, комфортно работать с ним в React Native так и не получится.
В итоге, пока переехал на Tamagui - про него кстати тоже много плохого пишут, но пока он выглядит как вариант, который предоставляет достойный набор дефолтных компонентов и кастомизацию как через собственные токены, так и через нативный StyleSheet.
Проблема не с синтаксисом TW (работать с ним как раз очень удобно, и если нет специфичных требований в виде расширенной темизации, и тем более если делаешь прототип - очень приятно).
Проблема в том, как NativeWind сейчас работает - под капотом NativeWind преобразует ваши TW классы в React Native StyleSheet - и этот дополнительный шаг вызывает дополнительные проблемы. Во первых, это заметно во время разработки - ты добавляешь класс, и долю секунды бандлер думает, просчитывает, и добавляет нужный StyleSheet.
Во вторых, иногда он просто их не добавляет. Реально. Есть куча ишью на ГХ, где люди описывают свои пропавшие стили. В основном, такие ишью закрыты как stale, и складывается что люди просто не получают решения и уходят от NativeWind (как и я).
В вебе это в целом так же работает, но видимо из-за того, что в вебе тулинг для TW более взрослый и оптимизированный, задержек и тем более потерей стилей нет.
Выходит, что NativeWind добавляет ещё один слой в систему, в которой и так уже слишком много слоев.
Складывается впечатление, что если core команда React Native не добавит нативную стилизацию с помощью TW, комфортно работать с ним в React Native так и не получится.
В итоге, пока переехал на Tamagui - про него кстати тоже много плохого пишут, но пока он выглядит как вариант, который предоставляет достойный набор дефолтных компонентов и кастомизацию как через собственные токены, так и через нативный StyleSheet.
Последнее время не слежу за новостной повесткой и кажется упустил действительно важную новость.
Next добавляет поддержку Rspack.
А это действительно может означать увеличение скорости без сломанного проекта (в отличие от злополучного Turbopack, с котором они так носятся - ну или делают вид, потому что прогресса там никакого).
Вчера полез в исходники их вебпаковских конфигов и там действительно появились коммиты про Rspack. Пока пишут про экспериментальную поддержку, но это уже огромный прогресс. Экспериментальная поддержка стартует с последней минорной версии 15.3
Как появится свободное время поэксперементирую с рабочим проектом, чтобы "в полях" посмотреть, что работает, что нет.
https://rspack.dev/blog/rspack-next-partner
Next добавляет поддержку Rspack.
А это действительно может означать увеличение скорости без сломанного проекта (в отличие от злополучного Turbopack, с котором они так носятся - ну или делают вид, потому что прогресса там никакого).
Вчера полез в исходники их вебпаковских конфигов и там действительно появились коммиты про Rspack. Пока пишут про экспериментальную поддержку, но это уже огромный прогресс. Экспериментальная поддержка стартует с последней минорной версии 15.3
Как появится свободное время поэксперементирую с рабочим проектом, чтобы "в полях" посмотреть, что работает, что нет.
https://rspack.dev/blog/rspack-next-partner
rspack.dev
Fast Rust-based web bundler
Сегодня вышел релиз OpenNext 3.6.6 с моими изменениями и я стал полноценным контрибьютором в open source.
OpenNext - это проект, который позволяет деплоить Next.js в инфраструктуру других провайдеров помимо Vercel, причем делать это похожим на Vercel способом - а именно, исполняя код необходимый для ревалидации страниц не в Node сервере, а в серверной функции облачного провайдера.
В результате отпадает необходимость держать Node сервер, а SSR и ISR остаются. Ну и кроме этого появляются другие плюшки, вплоть до того, что можно деплоить разные пути своего приложения в разные регионы - например локаль /de/ - приземлить во Франкфурт, а /en/ в Лондон. Ну и в целом OpenNext дает возможность более широкого контроля над ресурсами, которые составляют приложение.
Проблемы, которые потребовали изменений возникли при апгрейде на Next 15 - мы делали апгрейд сразу с 13 на 15 версию, и это потребовало апгрейда со 2 на 3 версию OpenNext.
А в 3 версии OpenNext перестал складывать CSS файлы в серверный бандл, и как бы они там вообще-то и не нужны, за одним исключением - если они не будут использоваться во время ревалидации.
А вот мы как раз используем - для того, чтобы собрать Critical CSS и положить его прямо в генерируемый HTML.
В итоге пришлось возвращать CSS в бандл.
Кстати нужно сказать большое спасибо команде OpenNext за быстрое ревью и комменты. Ребята открыты для общения в Discord и максимально быстро отвечают на PR.
https://github.com/opennextjs/opennextjs-aws/releases/tag/v3.6.6
OpenNext - это проект, который позволяет деплоить Next.js в инфраструктуру других провайдеров помимо Vercel, причем делать это похожим на Vercel способом - а именно, исполняя код необходимый для ревалидации страниц не в Node сервере, а в серверной функции облачного провайдера.
В результате отпадает необходимость держать Node сервер, а SSR и ISR остаются. Ну и кроме этого появляются другие плюшки, вплоть до того, что можно деплоить разные пути своего приложения в разные регионы - например локаль /de/ - приземлить во Франкфурт, а /en/ в Лондон. Ну и в целом OpenNext дает возможность более широкого контроля над ресурсами, которые составляют приложение.
Проблемы, которые потребовали изменений возникли при апгрейде на Next 15 - мы делали апгрейд сразу с 13 на 15 версию, и это потребовало апгрейда со 2 на 3 версию OpenNext.
А в 3 версии OpenNext перестал складывать CSS файлы в серверный бандл, и как бы они там вообще-то и не нужны, за одним исключением - если они не будут использоваться во время ревалидации.
А вот мы как раз используем - для того, чтобы собрать Critical CSS и положить его прямо в генерируемый HTML.
В итоге пришлось возвращать CSS в бандл.
Кстати нужно сказать большое спасибо команде OpenNext за быстрое ревью и комменты. Ребята открыты для общения в Discord и максимально быстро отвечают на PR.
https://github.com/opennextjs/opennextjs-aws/releases/tag/v3.6.6