Chulakov Dev – Telegram
Chulakov Dev
1.15K subscribers
140 photos
5 videos
205 links
Канал команды разработки Студии Олега Чулакова.

Советы по Frontend- и Backend-разработке web-сервисов, мобильных приложений, статьи и презентации от наших разработчиков, анонсы проектов и многое другое.

Обсудить проект @YuraAndreev
Download Telegram
Порталы в React

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

Ранее подобную проблему решали с помощью компонента-обертки, где сам рендер необходимого компонента осуществлялся не в методе render, а в componentDidUpdate с помощью функции ReactDOM.unstable_renderComponentIntoSubtree().

В новой версии появился метод createPortal объекта ReactDOM, который позволяет отрендерить React-компонент в DOM-дереве, о котором React ничего не знает. Для этого ему надо передать первым аргументом сам компонент, а вторым — ссылку на нужный DOM-узел.

Мы подготовили интерактивный пример использования этого метода. В примере рассматривается случай с интерфейсом плеера Video.js, в панель которого мы добавили компонент Likes.
Полезные команды Git. Удаление из индекса

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

Чтобы убрать файл из индекса, не удаляя его из директории, можно использовать следующую команду:
git rm --cached path-to/file.txt
Полезные команды Git. Перенос коммита

Если вы сделали коммит не в той ветке, вы можете легко скопировать его в нужную, используя команду:
git cherry-pick <хэш коммита>

Эта команда создаст в ветке новый коммит, который будет содержать все изменения из указанного.
Полезные команды Git. Откат незакоммиченных изменений

Если вы внесли изменения в файлы, а теперь хотите вернуть их в изначальное состояние, можно воспользоваться командой:
git reset --hard HEAD
Полезные команды Git. Откат коммита

Если вы сделали коммит, но забыли внести в него некоторые файлы, вы можете отменить коммит, сохранив все ваши изменения на диске:
git reset --soft HEAD~1

Чтобы удалить последний коммит вместе с изменениями в файлах, вы можете воспользоваться командой:
git reset --hard HEAD~1

Вы также можете откатить несколько последних коммитов. К примеру:
git reset --hard HEAD~3
Полезные команды Git. Revert

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

Если команда разработчиков большая, можно воспользоваться командой git revert. Это команда делает новый коммит, в котором отменяет все изменения из указанного:
git revert <хэш коммита>
Плотность пикселей в JavaScript

При разработке веб-приложения или сайта может быть необходимо учесть плотность пикселей на экране устройства пользователя. Например, для четкого отображения контента в теге canvas необходимо создавать холст, содержащий большее число точек, а затем с помощью CSS уменьшать визуальный размер этого холста обратно:
https://codepen.io/OlegChulakovStudio/pen/BrKWYE?editors=0110

Самый простой способ узнать плотность пикселей в современных браузерах — обратиться к свойству devicePixelRatio объекта window.
Retina + CSS

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

Для этого можно использовать следующий медиа-запрос:
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)

Пример использования:
https://bitbucket.org/snippets/OlegChulakovStudio/7egg9R

Если в рамках проекта требуется максимально высокая кроссбраузерность, можно воспользоваться расширенной версией медиа-запроса:
https://bitbucket.org/snippets/OlegChulakovStudio/zeaaBK
Retina + CSS-препроцессоры

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

Эти проблемы легко решить, используя возможности любого из современных CSS-препроцессоров:
https://bitbucket.org/snippets/OlegChulakovStudio/yeGxpp

Аналогично можно поступить и с любым другим более распространенным медиа-запросом, вроде (max-width: 1024px).
​​Кубическая кривая Безье и CSS

Специалисты, которые работают с анимацией, знают про easeOutCubic, easeInOutExpo, easeOutBack и другие основные функции плавности.

Те, кто копнул в принципы работы этих функцией знают, что они реализуют поведение, соответствующее различным кубическим кривым Безье.

Эта кривая строится на основе четырех точек:
P0 и P3 — начало и конец кривой;
P1 и P2 — указывают ее направление.

В CSS-реализации можно изменять только точки P1 и P2. Координаты P0 здесь всегда равны «0, 0», а P3 — «1, 1».

Кубические кривые Безье можно использовать в свойствах transition-timing-function и animation-timing-function, чтобы настроить зависимость между временем и прогрессом выполнения анимации:
transition-timing-function: cubic-bezier(x1, y1, x2, y2)
​​Кубическая кривая Безье и SVG

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

Создать такую линию можно с помощью команды C, в которую нужно передать координаты точек P1, P2 и P3:
<path d="M x0, y0 C x1, y1, x2, y2, x3, y3" />

Пример использования:
codepen.io/OlegChulakovStudio/pen/zWLQYL
Кубическая кривая Безье и canvas

Аналогично можно нарисовать такую линию и в canvas. Для этого нужно воспользоваться функцией bezierCurveTo, которая доступна в рамках 2D-контекста:
context.bezierCurveTo(x1, y1, x2, y2, x3, y3)

Пример использования:
codepen.io/OlegChulakovStudio/pen/pLqOXz

О других возможностях 2D-контекста canvas можно узнать из нашей интерактивной презентации.
Базовые принципы защиты

В этой заметке мы рассмотрим базовые принципы защиты, которые помогут избежать серьезных проблем с безопасностью на вашем сайте. К потенциальным уязвимостям относятся SQL-инъекции и XSS-атаки.

Принцип №1: проверка корректности ввода обязательно должна осуществляться и в backend-части web-приложения. Часто разработчик допускает очевидную ошибку, оставляя валидацию вводимых данных только на стороне браузера. В современных фреймворках такого рода проверка и фильтрация обеспечиваются на уровне модели данных или на уровне middleware-сервисов. Так, например, Yii2 Framework поддерживает множество стандартных валидаторов, а также позволяет реализовывать кастомные механизмы проверки данных.

Принцип №2: работа с SQL-запросами в БД должна производиться с подготовленными на предыдущем этапе данными. Любые входные данные для любого SQL-предложения должны быть типизированы на уровне PDO-типов, а их вставка в SQL должна производиться с помощью переменных привязки.

Принцип №3: препроцессинг вывода. При выводе данных в HTML необходимо также обрабатывать данные. Если вы выводите plain-текст, то необходимо использовать функцию языка htmlspecialchars, а если вы выводите html, например, введенный пользователем через визуальный редактор, то необходимо использовть более сложный механизм обработки выходных данных. Например, HTML Purifier. К счастью, современные фреймворки также включают в себя хелперы и компоненты для этого. Например, Yii2 содержит метод encode в хелпере Html-detail) для вывода plain-text. Для вывода html в Yii2 реализован хелпер yii\helpers\HtmlPurifier, который достаточно легко настраивается под нужды разработчика.
Yii2 FileStorage

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

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

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

Для фреймворка Yii2 мы разработали компонент FileStorage, который реализует большинство необходимых задач:
1) загрузку файлов из различных источников (например, из POST-запроса или по URL-адресу);
2) централизованное хранение оригинальных и измененных файлов с привязкой к объектам моделей данных;
3) получение расширенной информации о загружаемом или загруженном ранее файле;
4) API для добавления, получения и удаления файлов с автоматизацией очистки кэша модификаций;
5) разграничение доступа к загруженным файлам на основе взаимодействия с системой аутентификации Yii2;
6) основные операции над изображениями: различные методы ресайза, наложение водяных знаков, генерация thumbnail-изображений и т.д.

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

В прошлой заметке мы рассказали о нашем компоненте Yii2 FileStorage.

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

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

Для файлов изображений доступны два базовых слушателя:
1) ImageManager — производит изменение оригинального файла изображения, при этом оригинал изображения не сохраняется. Действует как фильтр: какое бы изображение ни загрузил пользователь, оно будет приведено к нужному формату;
2) ThumbsManager — генератор превью для загружаемого изображения с удобными конфигурационными настройками.

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

Мы реализовали три базовых источника:
1) UploadedFile — реализует получение файла при загрузке формы методом POST;
2) RemoteUplodedFile — получение файла по прямой ссылке;
3) LocalUploadedFile — получение файла из локальных ресурсов сервера.
Вращение в canvas

В 2D-контексте canvas есть функция rotate, работа которой ставит в тупик многих, кто пытается ей воспользоваться. Объекты, отрисованные после вызова этой функции, поворачиваются на указанный в ней угол. Однако есть одна сложность: вращение выполняется не относительно центра объекта, как в CSS, а относительно начала координат всего холста.

То есть, если отрисовать прямоугольник в центре холста, то опорной точкой вращения будет верхний левый угол всего canvas-а.

Чтобы выполнить вращение вокруг нужной точки, нужно сместить к ней начало координат с помощью функции translate и разместить новый объект с соответствующим сдвигом:
context.translate(originX, originY);
context.rotate(angle);
context.fillRect(x - originX, y - originY, width, height);


Пример с вращением прямоугольника относительно его центра:
codepen.io/OlegChulakovStudio/pen/NMxMzv
Channel name was changed to «Chulakov Dev»
Silence is gold, but not for us

После затяжного перерыва мы решили вернуться в эфир.

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

Стартуем в первой половине сентября.
Я тебя по IP вычислю

Современое веб-приложение с геотаргетированным контентом стремится автоматически определить ваш регион или город.

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

Точность бесплатных сервисов с открытым API может отличаться. Каждый из них агрегирует информацию региональных банков геоданных из различных источников и с разной периодичностью. Со временем пулы IP-адресов могут смещаться и переходить из одного региона в другой.

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

На базе сервиса SypexGeo мы разработали компонент для Yii Framework, упрощающий работу с геоданными посетителей сайтов в backend-окружении.
Mobile интересует?

Наряду со сложными интеграциями и разработкой веб-сервисов Студия активно развивает направление нативной мобильной разработки для ОС iOS и Android.

Мы привыкли делиться опытом, и нам важно ваше мнение.

Стоит ли публиковать заметки по Mobile Dev в этом канале или завести отдельный? 🤔
Разреши узнать, где ты

В предыдущей заметке мы рассмотрели возможность получения геоданных пользователя по IP-адресу на стороне сервера.

С помощью нативных средств HTML5 на стороне клиентского приложения тоже можно работать с геолокацией пользователя.

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

Если такое поведение приемлемо, то работать с геоданными в JavaScript можно через метод getCurrentPosition() свойства geolocation объекта navigator.

API предусматривает тонкую конфигурацию запроса с целью повлиять на его производительность. Управлять можно приоритетом точности options.enableHighAccuracy, кешированием определенных ранее геоданных options.maximumAge и максимальным временем выполнения запроса options.timeout.

Пример работы с API можно посмотреть в сниппете.