TGViewer
Channel Public Channel
Жабаскрипт (веде Віктор Турський)

Жабаскрипт (веде Віктор Турський)

@jabascript

Авторський контент для JavaScript розробників, але не завжди про JS:). Пишу про архітектуру, best practices, продуктивність, безпеку, інструментарій.

Viktor Turskyi (@koorchik), Cofounder at Webbylab, SWE at Google

Рекламу не розміщую!
Subscribers
4.72K
Photos
25
Videos
3
Links
309

Showing posts older than #62 · Back to latest

Older Posts 20 shown
Post #61 3.7K
Я всегда топлю в разработке за здравый смысл и всегда против догматичности.

1. Мое видение Шаблонов проектирования: это не некое сакральное знание, а набор подходов, которые работает а конкретных ситуациях и ребята типа Фаулера не придумали что-то уникальное, а просто классифицировали то, что отлично работает в проектах. Это дало нам общую терминологию и описание стандартных подходов. Нужно ли знать паттерны? Да, нужно. Нужно ли им следовать? Следовать нужно здравому смыслу, а паттерны могут подходит, а могу не подходить.

2. Мое видение Best Practices. Лучшие практики - это не то, что лучшее в 100% случаев. Best practices - это обычно не возможность сделать лучшим образом, а скорее не сделать хреново. Если вы не просто знаете конкретные Best Practices, а понимаете причины их появления, то в некоторых проектах вы можете сознательно их нарушать, поскольку у вас может быть более оптимальное решение для вашей конкретной ситуации.

К чему я это все? К тому, что нужно понимать программирование, а не "верить" в него. Вместо догматичного следования каким-то идеям - прислушивайтесь к здравому смыслу.
Например, многие говорят, что TDD это только для полностью изолированных юнит-тестов, иначе это не TDD, но TDD не про изоляцию, а про red green loop.
Аналогично CQRS и Event Sourcing. Народ увидел пример, который показал Greg Young и считают, что Event Sourcing может быть только таким, но все не так на самом деле.

Я недавно посмотрел интересный доклад Грега "Greg Young — A Decade of DDD, CQRS, Event Sourcing" https://www.youtube.com/watch?v=LDW0QWie21s И он как раз рассказывает про проблемы этой догматичности (вторая половина доклада) и что иногда фразы сказаны для примера, а народ потом верит в это и следует как догме, что не есть правильно.

Я очень часто замечаю эту проблему в нашем комьюнити. Банальный пример из жизни. В документации по React, когда-то была фраза, что есть антипаттерн использования this.props в getInitialState (в старом API) для определенных случаев. Потом на одной из конференций я показываю кусочек кода и мне говорит разработчик, что использование this.props в getInitialState это антипаттерн. Я спрашиваю почему - ответ “так написано в документации”. Но если внимательно читать документацию, то там хорошо описано, когда это является антипаттерном, а когда нет. И даже, если не описано, задумайся о причинах. И таких случаев у меня было множество, когда вместо “понимания” - ”вера” :)

Это моя ода здравому смыслу!
YouTube Greg Young — A Decade of DDD, CQRS, Event Sourcing Domain-Driven Design Europe 2016 - Brussels, January 26-29, 2016 - Organised by Aardling (https://aardling.eu/) https://dddeurope.com https://newsletter.dddeurope.com/ https://be.linkedin.com/company/domain-driven-design-europe https://bsky.app/profile…
Post #60 3.95K
Мы создаем еще одну IoT платформу для управления умным домом. Это еще один проект по автоматизации, который мы стартовали буквально пару месяцев назад.
В проекте: Docker, событийная модель работы, WebSockets, NodeJS, MQTT, много всяких интересных железяк, крутая команда.

➜ Я лично в нем тоже активно участвую, помогаю команде в решении архитектурных задач.

➜ Сейчас расширяю команду в Киеве и есть возможность взять 2х людей (фултайм в офис). Нужны NodeJS разработчики уровня Junior+/Middle. Если у кого есть желание, то приходите к нам, всему научим, но думать и работать придется 🙂

Детальное описание вакансии тут - http://bit.ly/2muaYCW
Также мы регулярно обновляем список вакансий в канале @webbylab, подписывайтесь.

Если есть любые вопросы относительно вакансии, то пишите мне лично или в чат, или нашим рекрутерам на почту, или в @webbylab_recruiter.

ХАК: пишите, что узнали про вакансию на канале "Жабаскрипт", тогда на вас обратят внимание в первую очередь 🙂
DOU Middle Node.js Developer Мы ищем профессионального, увлеченного, ориентированного на результат бэкенд разработчика в нашу очень дружную команду.
Post #59 4.06K
"NodeJS и OpenCV... однажды в Голливуде" - еще один интересный пост в блоге WebbyLab.
В одном из наших проектов возникла задача находить лицо человека на видео и замыливать его. Сегодня вся эта магия уже сугубо инженерная задача, просто нужно знать какие инструменты скомбинировать (OpenCV, ImageMagick, NodeJS, прямые руки). В продакшене это уже почти год и мы решили поделиться этим контентом с комьюнити. Возможно задача немного нестандартная для JS, но не только же CRUD клепать 🙂

ССЫЛКА НА ПОСТ: - https://medium.com/@WebbyLab/face-blurring-with-nodejs-and-opencv-once-upon-a-time-in-hollywood-f3b8e09669e8

Ну, и подписывайся на наш блог на Medium 🙂
Medium Face blurring with NodeJS and OpenCV once upon a time in… Hollywood Author: Yurii Vlasiuk (Developer)
Post #58 3.81K
Как я переезжал с Webpack на Parcel - часть 3

✳️Часть 1
✳️Часть 2

Я обычно не пакую файл конфигурации в билд. Конфиг я загружаю таким образом:

<script type='text/javascript' src="/config.js"></script>

сам "/config.js" выглядит так:

window.APP_CONFIG = {
// my configuration here
};


и прячу его за модулем "src/config.js", чтобы код не ходил в глобальную переменную.

// src/config.js
export default window.APP_CONFIG;

такой подход позволяет использовать один и тот же билд в разных окружениях. Билд один, но для каждого окружения свой конфиг (по модели 12 factor app). Идея - выкатывать в прод только те билды, которые были протестированы.

И вот такое практически невозможно заставить работать в Parcel. Это оказался целый квест :)

То есть, если вы напишите:

<script type='text/javascript' src="/config.js"></script>
И вас нет файла config.js, то Parcel ругнется ошикой, а если config.js есть, то он попадет в бандл, что нас тоже не устраивает.

Я начал искать решение и оказалось, что на эту тему много issues (например, https://github.com/parcel-bundler/parcel/issues/144), но разработчики не добавляют такую фичу. Кто-то пытается писать дополнительные плагины для решения проблемы, но плагины оказались не сильно высокого качества.

Затем я попробовал posthtml с плагином "include", но в итоге все, что мы инклудим точно также процессится Parcel-ом.

Потом я подумал, почему не грузить динамически конфиг и написал такой код:

const script = document.createElement("script");
script.async = false;
script.type = "text/javascript";
script.src = "/config.js";
document.head.appendChild(script);

Но этот код не заработал, поскольку файл с конфигом выполнялся после main.js даже с опцией async=false.

В итоге, вот такое решение заработало:

<script type='text/javascript'>
document.write(`<${"script"} src="/config.js"> </${"script"}>`);
</script>


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

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

Надеюсь, что этот опыт будет полезен читателям канала 🙂
Post #57 3.57K
Как я переезжал с Webpack на Parcel - часть 2

Лето оказалось перегружено поездками и конференциями. Наконец-то добрался до канала и решил опубликовать вторую часть про переезд на Parcel.

Первым этапом было перевести все на Parcel, но оставить точкой входа main.js.

Этап 2️⃣: Поменять точку входа на index.html и отказаться от лишних аргументов командной строки. Сборка должна выглядеть вот так
parcel index.html
и никаких конфигов.

Проблема №1: Перестали работать локальная статика типа jquery.js и пара других библиотек.

Parcel находит все теги script и собирает файлы в бандл(кроме файлов с внешних серверов). JQuery плагины перестали находить JQuery. Похоже, что проблема с тем, что модули уже объявляются не в корневом скоупе. Я долго не заморачивался, просто подключил все с CDN.

Проблема №2: перестали загружаться файлы локализации.
Для каждого языка в директории public/static/lang есть свой json файл. И был код, который загружал нужный файл локализации:

function loadLocaleData(locale) {
const url = `/static/lang/${locale}.json`;
return fetch(url);
}


В итоге, когда поменяли entry point на index.html, Parcel начал результат сборки помещать в dist. Естественно, он ничего не знает про статические файлы, которые не участвовали в сборке и loadLocaleData не может загрузить файлы локализации.

Тут есть несколько вариантов:
✳️ Использовать плагин parcel-plugin-static-files-copy (я решил не подключать лишний плагин).
✳️ Использовать динамический импорт (я пошел по этому пути).

По сути, я переписал код на такой:

const localeImports = {
ru: import(`../static/lang/ru.json`),
uk: import(`../static/lang/uk.json`)
};

export function loadLocaleData(locale) {
return localeImports[locale];
}


Может показаться, что я загружаю все файлы локализации сразу, но это не так. Import возвращает Promise, но загрузка файла начнется только, если вы запросите результат с промиса и загрузится только нужный файл. Подход с динамическим импортом лучше, чем c plugin-static-files-copy еще по нескольким причинам:
✅Файл будут минифицирован.
✅Имя файла будет содержать хеш сумму и я могу кешировать файл навечно (без проверки etag или last modified), что особенно актуально в данной ситуации (браузер не может показать интерфейс пользователю, пока не загружен файл локализации).

Отлично! Теперь у меня нет никаких конфигов для сборки и проект запускается одной простой командой
parcel index.html


Но нет 😬, осталась еще одна проблема - я не хочу, чтобы Parcel упаковывал конфиг приложения в билд. И на эту проблему я потратил больше всего времени.
Продолжение следует...
Post #56 3.51K
Долго думал нужен ли чатик для обсуждения постов. Я долго сомневался, но все таки пришел к выводу, что имеет смысл его сделать по нескольким причинам:
1️⃣ Возможность ответить на вопросы подписчиков или получить какие-то комментарии.
2️⃣ Определиться с темами, которые интересны подписчикам.
3️⃣ Иногда есть вещи, которые не сильно подходят для канала. Например, я часто выступаю на конференциях и постоянно кидать в канал, что на следующей неделе буду с таким-то докладом там-то вне сильно хочется. В канал планирую уже скидывать видеозаписи самых интересных докладов с какиме-то комментариями, но не анонс. А вот чатик для этого подходит 🙂.

Ссылка на чат - https://t.me/jabascript_chat
Post #55 6.48K

Forwarded from Viktor Turskyi

Небольшая заруба для всех участников конференции OdessaJS и подписчиков @jabascript, да и просто желающих. Играем в JavaScript Golf. Есть простая задача, нужно написать решение и чье решение будет содержать меньше всего символов, тот и победил.

Описание задачи - https://gist.github.com/koorchik/867460697526af0d84940960ee82652b
Правила тут (подключайтесь в чат) - @jsgolf

Как сабмитить результаты еще думаю 🙂
Post #53 6.34K
Как я переезжал с Webpack на Parcel.

Для различных небольших демо я постоянно использую Parcel. Parcel - "zero configuration bundler" и это правда. Никаких конфигов, все работает из коробки и очень быстро. Если ты не пробовал Parcel, то обязательно попробуй.

Можно ли использовать Parcel в крупном проекте? Сложно ли переехать с Webpack на Parcel?
У меня выпала возможность это проверить.

Был у меня один проект для сборки которого использовался еще Webpack первой версии. И когда я начал обновлять Webpack и лоадеры, я понял, что проще написать все с нуля, чем исправлять существующую конфигурацию и зависимости. Если уже все равно все делать с нуля, то почему бы не подключить Parcel? 🙂

Что у меня было: Babel, JSX, ES6 modules, Less. Точкой входа был файл main.js.
Задача перевести все на Parcel с минимальным количеством плагинов и конфигурацией по умолчанию, с точкой входа index.html.

Делал я это в 2 этапа:
Этап 1: Перевести все на Parcel, но оставить точкой входа main.js
Этап 2: Поменять точку входа на index.html

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

Первый этап оказался сильно проще, чем второй и возникло всего 2 проблемы 🙂.
1️⃣ Перевести все на Parcel, но оставить точкой входа main.js

Проблема №1: В некоторых случаях перестал работать импорт функций (локализации и других утилит).

Этот код перестал работать, хотя до этого работал:

import { l } from '../i18n';


Проблема оказалась в том, что в модуле i18n экспорт выглядел вот так:

export default {
l(text) {
return jed.gettext(text);
}
};


Соответственно нужно было бы переписать на:

export function l(text) {
return jed.gettext(text);
};


но после этого перестал работать код вида:

import i18n from '../i18n';


Чтобы это завелось, пришлось привести модуль i18n к такому виду:

export function l(text) {
return jed.gettext(text);
};

export default {
l
};


По сути нужно было привести модули ES6 к корректному виду (их было 2-3 таких).

Проблема №2: Загрузка статики с неправильных путей.

В проекте была такая структура директорий для статики:
public/
index.html
static/
3d-party/
lang/
en.json
ru.json
uk.json
favicon.ico
build/
main.js
main.css
...


и соответственно пути в index.html выглядели так /static/build/main.js .
Все, что нужно было - это указать нужные аргументы командной строки для Parcel.

Финальная команда выглядела так:

parcel watch \
--out-dir publiс/static/build \
--public-url /static/build \
src/main.js


и после этого с точкой входа через main.js все заработало.

Осталось запустить http сервер для раздачи статики из папки public. Я использую для этого node-static (всегда установлен у меня глобально в систему).

cd public
// запустить в режиме SPA
// если запрашиваемого файла нет,
// то всегда возвращает index.html
static --spa -p 8090


Со вторым этапом все сложнее оказалось, опишу завтра 🙂
Post #51 5.17K
И еще немного про монолиты и микросервисы в продолжение https://t.me/jabascript/50.

Фейсбук это огромный монолит на PHP, раньше просто собирался 1.5 ГБ бинарь, которые просто деплоился на все сервера. Почему так? Неужели они не знают про микросервисы?

Я уже цитировал Роберта Мартина, что лучшее архитектурное решение - это то, которое не было принято. Основная идея в том, что наша архитектура зависит от знаний предметной области, но на старте проекта мы знаем не слишком много и лучше строить так приложение, чтобы мы могли принять важное архитектурное позже, когда мы будем больше знать про предметную область. По мере изучения домена, мы проводим рефакторинг в коде, меняем абстракции, добавляем новые сущности, удаляем лишние и тд. И это одна из ключевых проблем микросервисов, мы думаем, что знаем, как нужно разрезать приложения на части с первого дня, но обычно это неправда и когда вы через 3 месяца начнете смотреть на код, вы поймете, что нужно было не так и коммуникация ваших микросервисов будет усложнена.

Но все это актуально не только для кода, но и для самой компании. Часто структура ваших микросервисов полностью соотносится со структурой команд в компании (вспомним тот же закон Конвея) . И это очень логично, когда каждая команда работает над своей частью (тут мы можем углубится в идеи code ownership, но не будем 🙂). Но по факту, по мере развития компании, в ней постоянно происходят изменения и мы заранее не знаем, какие они будут. Эти изменения ведут к реорганизации внутренней структуры компании и команд. В результате мы получаем, что в какой-то момент наша микросервисная структура не совпадает со структурой компании и это создает проблемы в поддержке.

Теперь вернемся к Facebook. Facebook пытается оптимизировать процесс под будущую неопределенность. Идея в том, чтобы можно было дешево и быстро реорганизовывать команды и сделать максимально дешевой их координацию за счет общего владения кодом и это у Facebook отлично работает. Микросервисы же - это когда вместо оптимизации координации, мы ее просто убираем и назначаем ответственную команду за каждый микросервис. Есть варианты, когда мы имеем одновременно микросервисы и монорепозитарий - это что-то посередине.

Про координацию отлично сказал Пит Хант (помните парня, который показал миру React):

It's all about Amdahl's Law: you're going to be limited by how much coordination you need, and how much it costs.
Mono: coordination is cheap/free👍 But might encourage more coordination 👎
Poly: less required coordination👍 But if you need to coordinate, it's very expensive 👎

Это касается не только работы с репозиториями, но и вопроса монолит/микросервисы.

Все эти различные подходы могут отлично работать. И если у вас что-то работает, не гонитесь за хайпом, здраво смотрите на задачу. Замена технологий, подходов, процессов - это всегда замена одних проблем на другие, всегда взвешивайте стоит ли оно того.

Ко всему этому могу порекомендовать послушать интервью с Питом Хантом - Facebook Engineering with Pete Hunt
Post #50 7.45K
Как работает Google со своим кодом или немного про монорепозитарии.

Google использует монорепозитарий. Это значит:
✅ Что весь код хранится в одном репозитории. Это несколько миллиардов строк кода. Размер репозитория 86 ТБ.
✅ Это значит, что каждый сотрудник имеет сразу доступ ко всем проектам Google.
✅ Все всегда вливается в HEAD (master/trunk).
✅ Все зависимости также находятся в репозитории.

Мы привыкли к совершенно другому подходу. Спрашивается зачем это? Мы теряем всю гибкость, как в случае с множественными репозиториями. Но это выбор между консистентностью всего кода и гибкостью. Google выбирает консистеность.

Теперь вопросы и ответы:

Вопрос: Как это влияет на деплоймент?
Ответ: Деплоймент это независимая процедура и деплоить они могу свои микросервисы раздельно.

Вопрос: Получается у Google нет ревью кода?
Ответ: Ревью кода и тесты есть, и это ключевая часть процесса разработки. Просто, для этого есть отдельный инструмент/инфраструктура.

Вопрос: Как такой репозитория клонировать на локальную машину?
Ответ: Репозиторий не клонируется, а используется виртуальная файловая система.

Вопрос: Как происходит работа над Chromium, если это open source проекты?
Ответ: Chromium и Android не находятся в этой монорепе.

Вопрос: Если нет версионности и я разработчик какой-то общей библиотеки и я решил поменять API, как не сломать чужой код?
Ответ: Ты должен будешь исправить код всех других проектов, которые зависят от твоей библиотеки. Также каждый разработчик должен помнить, что кто-то другой может обновить библиотеку и поэтому хорошая практика писать тесты для обнаружений проблем со сторонними библиотеками. Также в Google есть хорошие инструменты, которые позволяет быстро найти библиотеки зависимые от твоей и сделать быстро замены в коде.

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

Вопрос: Кто еще использует монорепозитарий?
Ответ: Из того, что я знаю - это Facebook и Twitter

Вопрос: Нравится ли сотрудникам такой подход?
Ответ: Да, большинство сотрудников Google поддерживают такой подход.

В целом, преимущества монорепозитарий сродни преимуществам монолита - это выше консистеность кода.
✅ Использование одного стиля (общий стайлгайд и правила статического анализа)
✅ Зависимость от одной версии рантайма/языка.
✅ Зависимости от одинаковых версий библиотек.

То есть даже, если вы пишите микросервисы, старайтесь по максимуму стандартизировать подходы к разработки.

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

Но консистеность кода для нас очень важна:
✅ Мы используем единый подход к архитектуре на большинстве проектов (описывал тут https://t.me/jabascript/36)
✅ Мы начинаем проекты с единого бойлерплейта.
✅ Мы активно используем инструменты для статического анализа кода. Мы не просто используем eslint и его плагины по максимуму, мы еще имеем конфиг eslint на всю компанию. И ко всему этому, мы пишем еще свои плагины для eslint
4. Мы используем общий набор библиотек. К примеру для валидации мы создали LIVR, который работает одинаково в JavaScript, PHP, Perl (и на многих других платформах).

Если хотите знать больше про монорепозитарии, вот ряд интересных ссылок:
1. Why Google Stores Billions of Lines of Code in a Single Repository
2. Monolithic Repositories with Ciera Jaspan
3. Monorepos in the Wild
4. Monorepos: Please don’t!
Post #48 6.15K
Сейчас мы делаем несколько проектов для автоматизации умного дома. Софт на NodeJs, запускается в докер-контейнерах на наших хабах. Хабы это железяки по типу raspberry/orange pi. Флеш память приходится сильно экономить и стал вопрос оптимизации размера докер образов.

Если взять стандартный образ node:10 и сделать все без оптимизаций, мы получим образ в 700МБ или больше. Базовый образ будет 600 МБ и 100 МБ слой с приложением.

Ребята из компании решили поделиться опытом и написали отличный пост про оптимизацию размера докер образов для NodeJS приложений.

Статья: Docker image size optimization for your Node.js app in 3 easy-to-use steps.

Результаты:
Размеры образов до оптимизации:
* 600 МБ базовый образ с NodeJS
* 100 МБ на каждый новый образ

Размеры образов после оптимизации:
* 100 МБ базовый образ с NodeJS
* 2.5 МБ на каждый новый образ
Post #47 4.51K
Сделал страницу на Github со списком моих докладов на предстоящих конференциях и с материалами по прошедшим (контент все еще добавляю). Если вдруг тоже окажетесь на какой-то из этих конференций, буду рад пообщаться 🙂

Обновляемый список моих докладов: https://github.com/koorchik/my-talks
GitHub GitHub - koorchik/my-talks: List of talks performed by me List of talks performed by me. Contribute to koorchik/my-talks development by creating an account on GitHub.
Post #46 5.99K
Много лет назад наткнулся на пост Бобука (Григорий Бакунов, был директором по разработке в Яндексе, сейчас директор по распространению технологий) о том, как развивается эмоциональное состояние человека по мере его профессионального роста. Я этот текст перечитавал уже много раз. Ни убавить, ни прибавить.

Это стоит прочитать - "Как закаляется сталь"
https://github.com/bobuk/addmeto.cc/blob/master/pages/2013-04-19.md
GitHub addmeto.cc/pages/2013-04-19.md at master · bobuk/addmeto.cc addmeto.cc. Contribute to bobuk/addmeto.cc development by creating an account on GitHub.
Post #45 4.95K
Меня сняли на скрытую камеру 😁

Позавчера был в Днепре и должен был выступать на RunIT. Во время завтрака в отеле неожиданно встретил Максима Безуглого (основателя "Internation Software Architect Club"), который также должен был выступать на той же конференции. С Максом и Мишей Корбаковым у нас завязалась небольшая дискуссия про архитектуру, graphql, REST. Получился спонтанный выпуск "Архитектура и Кофе" 🙂

ВИДЕО (20 минут): https://www.youtube.com/watch?v=DSwpL3s_eZA

Также рекомендую к просмотру весь цикл "Архитектура и Кофе" (неформальные обсуждения вопросов архитектуры с опытными разработчиками и архитекторами) - https://www.youtube.com/playlist?list=PL9lOYXXTeW0oE-H1fXrJ5tdLLUkMtWJtC
YouTube Архитектура и кофе "скрытая камера". Виктор Турский, Михаил Корбаков Application уровень архитектуры, код, снова GraphQL и REST
Post #44 4.4K
Еще один доклад с Google.io -
Beyond Mobile: Building Flutter Apps for iOS, Android, Chrome OS, and Web (Google I/O'19)

Flutter - это такой себе аналог React Native от Google, где вы пишите все на Dart. На самом деле, архитектура совершенно другая.
Flutter, в отличии React Native, реализует все с нуля. Все рендерится на канвасе через OpenGL и выглядит идентично на всех платформах.

Представьте себе, что вы пишете OpenGL игру, а потом запускаете ее на iOS и Android, она выглядит одинаково там и там, поскольку вы все нарисовали сами на канвасе. То есть, ваше Android приложение на iOS будет выглядеть точно также, как и на Android. Естественно, это не всегда хорошо и вы хотите нативное поведение для платформы. В связи с этим, Google реализовывает 2 набора компонентов, 2 набора механик/физики/анимаций под обе платформы и вы можете на Android увидеть как будет работать ваше iOS приложение и наоборот.

Flutter имеет отличную производительность (Google целится на 120fps, но пока это 60fps). На Android и iOS Dart код компилируется в ассемблерные инструкции для ARM архитектуры. У вас нет медленного JSCore, как в случае с React Native, и асинхронного "моста".

Сам же высокоуровневый API Flutter очень похож на то, что у нас есть в React, только батарейки в комплекте :).

В двух словах суть доклада в том, что Google запускает Flutter для десктопа и для веба:
✳️ https://flutter.dev/desktop
✳️ https://flutter.dev/web

Сейчас в WebbyLab мы смотрим на эту технологию, хотим сделать 1-2 небольших проекта. Один из проектов будет для комьюнити и уйдет в OpenSource. Я уже сам успел поиграться - Developer Experience отличный, рекомендую тоже посмотреть, если вам интересна мобильная разработка.

Начните с того, что установите себе Flutter Gallery и пощелкайте UI и различные опции.
YouTube Beyond Mobile: Building Flutter Apps for iOS, Android, Chrome OS, and Web (Google I/O'19) Flutter is a great way to build mobile apps for iOS and Android from a single codebase. But did you know that Flutter is expanding beyond mobile to run on desktop and the web, too? In this talk, you'll see two developers live code a real-world app that runs…
  • 👍 1
Post #43 4.51K
Вот прошел Google.io и я наткнулася на пару релевантных докладов. Один из них - What’s new in JavaScript (Google I/O ’19)

Я много лет в разработке, различные скрипты для управления сетевым оборудованием начал писать где-то в 2003. И практически с самого начала я писал на Perl и на JavaScript. Соответственно, я всегда сравниваю Perl и JavaScript. Я рад, что многие возможности, которые были в том же Perl много лет, появляются в JS.

Когда, я писал первый крупные SPA, то приходилось использовать ES3. С того момента JS кардинально поменялся:

✳️ В ES3 мне очень не хватало перловых "map" и "grep", пока не появились аналоги в JS - "map" и "filter".
✳️ Мне не хватало интерполяции переменных, как в Perl. В Perl каждая переменная начинается со знака $ и в двойных кавычках она интерполируется. То есть можно писать "Hello, ${name}!". Потом в JS появились Template Literals с аналогичным синтаксисом.
✳️ Переменные с лексической областью видимости - одна из фич, которые я прям ждал в JS. Даже до "let" и "const", я все равно объявлял все "var"-переменные , как если бы они имели локальную область видимости - максимально близко к месту их использования, такой код легче потом рефакторить.

JavaScript не варится сам в себе, а смотрит на соседние языки. Грамотно заимствует различные фичи, делая язык все более мощным.

Теперь по докладу:
1️⃣ Наконец-то в JS появился "string.matchAll". Кроме того, в stage 4 "RegExp Named Capture Groups" с синтаксисом как в Perl. Все это позволяет писать более понятный код. Вот пример регулярки на Perl. Еще немного и мы сможем писать так и в JS. Возможно даже грамматики подвезут :)
Главное не забывать слова Jamie Zawinski: "Некоторые люди, когда сталкиваются с проблемой, думают «Я знаю, я решу её с помощью регулярных выражений.» Теперь у них две проблемы"

2️⃣ Поддеркжа приватных свойств в классах. Похожая идея реализована в Perl6. Мне подход с # нравится значительно больше, чем через ключевое слово "private" (как в TypeScript и других языках), поскольку мы везде по коду можем видеть приватное или публичное свойство мы используем, да и объявление лаконичнее.

3️⃣ Разделители в числах. Можно писать 10_000_000, явно легче читается чем 10000000. Это есть во многих языках, включая Perl :)

4️⃣ array.flat и array.flatMap. В Perl я привык, что map может вернуть больше элементов, чем было в изначальном массиве, с flatMap наконец-то это тоже можно сделать и в JS :)

5️⃣ Object.fromEntries (противоположность Object.entries)

6️⃣ Поддержка BigInt из коробки.

7️⃣ Стабильная сортировка в стандарте. Кому-то это важно, я всегда писал код опираясь на идею, что сортировка нестабильная.

8️⃣ Promise.allSettled в дополнение к Promise.all и Promise.race.

9️⃣ Множество различных фич по i18n и l10n. Из наиболее полезных штук - Intl.RelativeTimeFormat.

Также в докладе показали улучшения производительности:
✳️ С node8 до node12 промисы стали в 11 раз быстрее. И что интересно, что нативный async/await в два раза быстрее чем нативные промисы.
✳️ С Chrome 61 до Chrome 65 на 40-100% ускорение скорости парсинга JS на реальных сайтах (типа FB).

На сегодняшний день, JavaScript имеет самый быстрый райнтайм среди динамических языков.
Post #42 4.76K
Мой коллега Рома Пухлий решил сделал полезное дело и написал статью про Linux утилиты, которые следует знать каждому разработчику - "Linux utilities that every developer should know"

Статья содержит примеры решения ежедневных задач при помощи командной стоки. Примеры поделены на разделы:

✳️ Работа с файлами
✳️ Работы с дисками
✳️ Чтение логов
✳️ Поиск по файловой системе
✳️ Работа с процессами
✳️ Запуск процессов в фоне
✳️ Использование системных ресурсов
✳️ Просмотр информации о системе
✳️ Сетевые утилиты
✳️ Другие утилиты

✅ К этому всему есть удобная шпаргалка в PDF https://blog.webbylab.com/images/linux-print.pdf
Большинство команд должно работать и на OSX.
Post #40 4.39K
Наткнулся на интересную статью на Хабре "Нужно ли чистить строки в JavaScript?"

В двух словах. Если у вас есть строка на 20мб, а вы вырезали из нее подстроку на 13 или больше символов, то v8 будет хранить ссылку на изначальну большую строку и не будет вычищать память.

Пример кода со статьи:

function MemoryLeak() {
// 15МБ строка
let huge = "x".repeat(15*1024*1024);

// Маленький кусочек
let small = huge.substr(0,25);
return small;
}

let arr = [];
setInterval(e=>{
let str = MemoryLeak();
arr.push(str);
console.log(JSON.stringify(arr).length, 'байт');
}, 500);

Я проверил на Node v12.2.0
Размер массива arr у меня был 3837 байт, а размер процесса дорос до 2ГБ и крашнулся с ошибкой
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

Такое поведение существует много лет, тикет был заведен еще в 2013 году.

Насколько это большая проблема? Если мы возьмем бэкенд, то он обычно не хранит состояние в памяти между запросами, и если пропадет ссылка на arr, то сборщик мусора все вычистит. Но вы можете столкнуться с данной проблемой, когда у вас есть кеши, которые живут между запросами, также на фронтенде, когда у вас есть долгоживущее состояние приложения (в SPA).
Post #37 5.8K
Мое утро началось с просмотра исключительно интересного доклада "Rich Harris - Rethinking reactivity"

Что будет, если фреймворк превратить в компилятор? Получится svelte.

Svelte - библиотека, которая очень похожа на React, но:
✅ Не имеет VirtualDOM, вся реактивность добавляется во время компиляции.
✅ Компоненты получаются компактнее чем в React (исходный текст компонентов).
✅ Svelte в 35 раз быстрее чем React и в 50 раз быстрее чем Vue.
✅ Имеет поддержку CSS изоляции, анимаций и много другого, но это не увеличивает размер вашего бандла, если вы не это не используете. Это работает, поскольку у библиотеки нет рантайма (или почти нет) - все проиходит на этапе компиляции.
✅ Имеется Sapper - аналог Next.js, но только для Svelte.

Не нужно сразу выбрасывать React/Vue/Angular/Ember и переходить на svelte, но точно стоит с этим поиграться, посмотреть на новые идеи.

ВИДЕО: https://www.youtube.com/watch?v=AdNJ3fydeao
YouTube Rich Harris - Rethinking reactivity Modern JavaScript frameworks are all about reactivity. Change your application's state, and the view updates automatically. But there's a catch — tracking state changes at runtime adds overhead that eats into your bundle size and performance budgets. In this…
Post #36 5.75K
Рабочая архитектура веб-приложений.

Не так давно прошла конференция для архитекторов devpoint.ua. Я делился тем, как мы строим архитектуру веб-приложений у нас в компании.

Архитектура очень схожа на "Clean Architecture" Роберта Мартина. Про "Clean Architecture" многие говорят, но это достаточно абстрактная концепция и от деталей зависит многое, я постарался рассказать, как мы на практике ее используем. Эта архитектура у нас работает на NodeJs, Perl, PHP проектах совершенно разных масштабов (более 60 проектов). Первый проект на этой архитектуре мы построили 7 лет назад, за это время архитектура эволюционировала, но ядро и концепции не поменялись за все годы.

Когда мы внедрили свою архитектуру, то понятия "Clean Architecture" еще не было, мы все строили опираясь на здравый смысл, а потом через какое-то время нашли этому всему правильные названия. На самом деле, вся история про различные шаблоны проектирования именно про названия. То есть это не сокральное знание, а что-то, что люди часто используют и дали ему имя. Зачастую шаблон проектирования это не определение "лучшего решение" (или даже не Best Practices), а просто решение, которое часто работает в определенной ситуации. Думаю, стоит написать отдельный философский пост посвященный моему видению различных архитектурных шаблонов 🙂

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

ВИДЕО ДОКЛАДА: https://www.youtube.com/watch?v=TjvIEgBCxZo

Обещаю ответить на все вопросы в комментариях под видео (если такие будут) 🙂

На самом деле, очень большая проблема найти адекватный бойлерплейт для проектов на NodeJs. Возьмите тот же NodeJs бойлерплейт от Microsoft. Несмотря на 4736 звезд, это не то, что я был взял себе в проект. Из очевидных моментов:
❌ Не хватает слоя сервисов (юз-кейсов) и в результате у нас нет нормальной изоляции от HTTP состовляющей и формата передачи данных.
❌ Не хватает надежного подхода к валидации. То есть, разработчик может смело пропустить валидацию и не ясно, что делать с иерархическими структурами.
❌ Бойлерплейт весь на колбеках (continuation passing style). У нас уже давно есть промисы, и даже более - async/await
И масса других вопросов остаются открытыми (локализация, конфигурации и тд).

В очередной раз думаю, что нужно заопенсорсить наш бойлерплейт, но основной момент - это подготовить документацию и описать идеи, которые стоят за ним. Видео доклада - первый шаг в эту сторону 🙂
YouTube DevPoint 2019. Рабочая архитектура веб-приложений - Виктор Турский. Презентация: https://www.slideshare.net/secret/1g38dVy5al76dX
  • 👍 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →