Популярные расширения для VS Code 2022 / Хабр | Веб-студия Nat.od.ua
Популярные расширения для VS Code 2022 / Хабр
В виду того, что мне срезали подписку на Medium решил поддерживать отечественные IT ресурсы. Попробую кидать интересные статьи с переводом на русском, а правообладатели пусть сами разбираются, я честно платил за подписку.
На текущий момент VS Code остается средой разработки, которая доступна в период санкций, когда JetBrains отказался продавать лицензии, про Visual Studio даже не узнавал. Сам использую VS Code много лет в разных стеках. VS Code предоставляет возможности разработки практически во всех направлениях: веб-разработка, мобильные приложения, часто встречаются приложения для встраиваемых систем. Ниже перечислены наиболее популярные расширения, которые облегчают разработку приложений.
Atom One Dark Theme
При всем изобилии тем в VS Code тема Atome One Dark наиболее популярная, потому-что имеет наиболее удачный контраст и прекрасно выглядит.
Тама в магазине VS CodeПример React приложения
Установка ext install akamud.vscode-theme-onedark
VSCode Great Icons
Популярное расширение для иконок. Кому как красивее и удобнее решайте сами.
Установка ext install emmanuelbeziat.vscode-great-icons
Hungry Delete
Очень простое, но очень полезное расширение. Помогает при удалении нескольких пустых строк. Позволяет удалить все пустые строки клавишами Ctrl-Backspace для Windows, Linux и Alt+Backspace для Mac. Чтобы удалить строки снизу служит комбинация клавиш Ctrl+]. Поддерживает удаление в режиме мультикурсор.
Удаление нескольких строк комбинацией клавиш Ctrl-Backspase
Функция Smart Backspace позволяет выравнивать код при нажатии клавиши Backspace.
Функция Smart Backspace
ext install jasonlhy.hungry-delete
Live Server
Простое и удобное расширение для веб-разработки. Позволяет запускать статические веб-страницы в режиме локального сервера. Поддерживается перезагрузка страниц при изменении исходных файлов.
Перезагрузка страницы при изменении исходных файловКнопка быстрого доступа в строке состояния
Поддерживает команды контекстного меню в Проводнике и в редакторе кода.
ext install ritwickdey.LiveServer
TabOut
Расширение, похожее на Hungry Delete, но в отличии от него запускается через меню команд.
ext install albert.TabOut
Сниппеты
Если вы никогда не использовали сниппеты, стоит о них подумать, они делают нашу жизнь легче и упрощают работу с часто используемыми блоками.
Сниппеты — небольшие преднастроенные строки, которые позволяют заполнять большие куски кода. Удобно использовать в React компонентах, где большое количество повторяемого шаблонного кода.
Сниппеты для React
Установка React сниппетов ext install runningcoder.react-snippets
Список расширений, который может заинтересовать
Vim — эмулятор Vim редактора в VS Code.
Auto Close Tag — автоматически добавляет закрывающие теги для HTML/XML.
Git Graph — визуальное представление для веток Git репозитория. Проще один раз увидеть.
Таблица горячих клавиш для VS Code
Кидайте в комментарии расширения, которые используете вы…
Фронтенд-новости №1 | Веб-студия Nat.od.ua
Фронтенд-новости №1
Дайджест новостей из мира фронтенд-разработки за последнюю неделю 5—11 апреля.
Спецификации
Опубликован первый рабочий черновик (First Public Working Draft) Region capture.
Последний призыв к рассмотрению предлагаемых изменений в Media Queries Level 3.
W3C приглашает к реализации WebXR Device API.
Спецификации preload становится отключенным черновиком (Discontinued Draft), чтобы продолжить развитие в HTML living standard.
Письмо генерального директора W3С к 33-й годовщине интернета.
Больше новостей о HTML, CSS, JavaScript и инструментах разработчика — под катом.
Больше новостей
Legal design и договор о сайте / Хабр | Веб-студия Nat.od.ua
Legal design и договор о сайте / Хабр
Дизайн-мышление — модный тренд, который за время пандемии добрался и до юристов. Если законы все еще пишут крючковатым языком, то юристы, занятые в частном секторе (B2B, судебные юристы и т.д.), стремятся сделать документы не только выигрышными, но и понятными.
Margaret Hagan полагает, что с помощью Legal design многообещающие и полезные юридические идеи и концепции могут быть разработаны быстро и эффективно.
Я с ней соглашусь и, имея 8+ летний опыт работы юристом, добавлю, что «задизайненный» договор гораздо быстрее заключить. Однако нельзя попадаться в ловушку «хороший дизайн = простота» и удалять элементы, кажущиеся избыточными, ведь они могут иметь важное правовое значение.
Алгоритм составления договора о сайте через призму Legal design
-
Определиться с содержанием услуг, их объемом, сроками оказания и ценой
-
Предоставить гарантии заказчику по работоспособности сайта
-
Договориться о порядке взаимодействия с заказчиком
-
Ввести ответственность сторон
-
Сформировать разделы договора
-
Подготовить пояснения условий договора
-
Предложить альтернативы некоторым условиям
Как результат, такая рыба договора ускорит процесс заключения договора, а способность ясно описать услугу и предложить альтернативы по ее цене и объему привлечет нового клиента.
По комментариям постов на Хабре составлен шаблон Договора о сайте. Данный шаблон учел потребности разработчиков и минимизировал риски заказчика.
Буду признательна комментариям и вопросам по шаблону договора, если есть возможность лучше учесть технические моменты, пожалуйста, пишите — обязательно сделаю апдейт шаблона.
Некоторые мифы заключения и исполнения договора
Необходима физическая передача всех материалов, исходников и графики (пишет Stan_1 )
Это утверждение не универсально и не применимо к каждому виду договора на разработку. Если говорить о сайте — это составное произведение, которое не используется иначе, чем в электронном виде. Поэтому для юриста/ бухгалтера (для учета расходов организации на покупку сайта) достаточно акта об оказанных услугах и электронного письма, которым передан сайт, ссылки на скачивание, ключи доступа и т.п..
Данная практика основана на широком распространении электронного взаимодействия, разъяснениях судебных инстанций к статьям 160 и 165.1 ГК РФ.
Если же заказчик просит больше актов и исходников, а обязанность их предоставить не прописана в договоре, задумайтесь, возможно заказчик тянет с оплатой. Тогда можно напомнить ему про начисление процентов за просрочку оплаты по ст. 395 ГК РФ или договорную неустойку.
Заключить договор в электронном виде сложно, не надежно и не подходит для крупных заказов
2020-2021 годы в корне развеяли это предубеждение юристов и бухгалтеров. Ранее упомянутая статья 160 ГК РФ позволяет заключать договоры даже путем обмена подписанными сканами документа по e-mail. Кроме того, в ГК РФ есть концепция договора-оферты: направляете Договор-оферту и счет на его оплату (или оплату одного из этапов работ) и договор считается заключенным с момента оплаты счета. А в рамках B2B распространяется заключение договора через системы электронного обмена документами (Контур.Диадок и т.д.)
Заказчик противится указанию авторства на сайте (по мотивам комментария)
Право заказчика запретить указание имени автора сайта (т.е. разработчика) зависит от того, какие права он получает по договору. Если права на сайт отчуждаются — то заказчик вправе препятствовать указанию имени автора разработчика сайта. Если элементы сайта передаются по лицензии, то разработчик вправе настаивать на указании своего имени на сайте. В любом случае этот вопрос рекомендуется обговорить до заключения договора, а также следует добавить на макет указание разработчика сайта.
Право на изменение произведения должно быть получено явно
По аналогии с комментарием к выше. Отчуждение предполагает, что новый собственник может и изменять сайт (модифицировать). А вот лицензия — ограничивает эти полномочия, если иное явно не прописано в договоре.
Необходимо отдельно прописать вознаграждение разработчика
По моему опыту проще и яснее указать цену. А вот в части вознаграждения прописать, что оно включено в цену. Если же это не договор авторского заказа, а договор услуг/ работ или купли-продажи, то выделять вознаграждение не обязательно.
Заказчик всегда может отказаться платить и ничего с этим не поделаешь
К сожалению так случается, и именно для защиты в суде ваших прав составляется письменный договор, актируется (фиксируется) передача результата работ, сохраняется переписка с заказчиком.
Legal design в договоре о сайте
Legal design структурирует не только форму, но и мысли, концепции, взаимодействие людей. Дизайн-мышление упрощает переговоры, облегчает работу над проектом, делая юридические моменты понятными, легко объяснимыми и правильно применимыми.
Остаюсь на связи и жду ваших вопросов и комментариев.
Теги: Разработка сайтов Договор Управление проектами Маркетинг
Хабы: Разработка веб-сайтов
Разница между python и php / Хабр | Веб-студия Nat.od.ua
Разница между python и php / Хабр
Год назад я полностью перешел в разработку на Python. До этого около 4-х лет писал в основном на PHP. В процессе работы я постоянно сравнивал эти 2 языка и сейчас решил уложить это все в одной статье, чтобы структурировать плюсы и минусы. Для вас эта статья может быть полезна, чтобы разобраться, какой выбрать для ваших задач.
Качество документации кода
Первое, что бросилось мне в глаза, когда я с php перешел на python — это качество документации кода и тайпхинты в популярных библиотеках.
Возьмем для примера самые популярные либы http клиентов: guzzle — для php и requests — для python.
Откройте любой класс в requests и вы увидите, что почти каждый публичный метод имеет параметр **kwarg, что означает — какой-то набор именованных аргументов. Не для всех аргументов есть описание типа. И так почти во всех либах. Даже в нативных библиотеках не используется типизация (обсуждение на stackoverflow).
В guzzle все методы имеют понятный интерфейс с описанием и указанными типами. В php в целом культура описания кода выше. Часто вы сможете использовать либы даже не открывая документацию, а посмотрев исходный код. На python вам почти всегда придется посмотреть примеры использования в документации и только потом понять, как сделать то, что вы хотели сделать.
Синтаксис языка
Python явно проще для чтения. Хорошо написанный код будет выглядеть почти как обычный текст написанный на английском языке.
Когда переходишь с php на python, первое время непривычно учитывать наличие декораторов и контекстных менеджеров в коде. Я считал это лишним синтаксическим сахаром. Но это оказалось делом привычки. Если использовать их правильно, то код становится проще.
Например, так будет выглядеть кэширование результатов метода на 2 минуты через декоратор:
@cache(ttl=120)
def foo(x) -> str:
…
Php же наоборот, содержит меньше синтаксического сахара и неявных конструкций. Это позволяет легче анализировать код линтерами и для автоподсказок в IDE (я пользуюсь phpStorm и pyCharm от Jetbrains).
Использование в веб приложениях
В php один запрос всегда обрабатывает один процесс, для этих целей часто используют nginx в связке с fpm сервером.
Рассмотрим самую распространенную схему работы веб сервера на php:
Веб сервер на PHP
Она хороша тем, что процесс, в котором обрабатывается запрос, полностью изолирован. Вы не имеете доступа к объектам из другого запроса. Всю ответственность за управление числом одновременно обрабатываемых запросов и числа создаваемых для этого процессов берет на себя php-fpm.
В php гораздо больше веб фреймворков, позволяющих быстро создавать сайты, как простые, так и высоконагруженные. На момент написания статьи, наиболее популярные и известные мне это: yii, symphony, slim, laravel. У каждой из них есть либо свои ORM менеджеры, либо сторонние, с очень большой поддержкой. На python список фреймворков, сопоставимых по уровню поддержи, гораздо меньше, это: tornado, django, flask.
Для Python используются очень разные схемы. Часто это схема nginx -> WSGI -> python app. При использовании фреймворка tornado, прослойки для управления процессами вообще нет, все управление берет на себя сам фреймворк. Поэтому я делаю вывод, что python дает больше возможности в управлении сервером.
Варианты вебсервера на Python
На python гораздо проще написать, например, веб-сокет сервер, или разрабатывать в микросервисной архитектуре.
Использование для разработки утилит и моделей машинного обучения
Python абсолютный лидер в этих сферах. Почти все самописные инструменты для devops или парсинга гораздо удобнее и быстрее делать на python. Я думаю, дело в том, что python позволяет очень быстро погрузиться в язык, не изучая глубоко синтаксис и позволяет понимать интуитивно, как использовать простые инструменты. Поэтому непрофессиональным разработчикам легче использовать python.
Для парсинга на python есть библиотека scrapy, аналогичной которой нет в php. Благодаря этому можно гораздо быстрее писать сложные парсеры.
Разработка моделей машинного обучения на php — это извращение, по моему мнению. Python с библиотеками sklearn, xgboost, pytorch, tensorflow, keras ушёл далеко вперед от остальных языков в плане разработки ML. Даже более низкоуровневые библиотеки, такие как numpy, scipy позволяют ученым делать сложные вычисления не вникая в особенность языка.
Выводы
Для веб разработки, в большинстве случаев, лучше подойдет php потому что:
-
на нем более удобные фреймворки, позволяющие быстрее решать типовые задачи
-
лучше уровень документации библиотек
-
Проще схема управления сервером
Но если у вас сложная микросервисная архитектура или вы делаете не типовой сервис, в котором требуется асинхронный веб сервер, то лучше использовать python.
Для других задач, таких как: парсинг, разработка ML моделей, простые утилиты — больше подходит python.
Если вы не согласны со мной, либо у вас есть свои наблюдения, пишите об этом в комментариях.
Ресурсы:
http://xandeadx.ru/blog/php/866
https://scrapy.org
https://ru.wikipedia.org/wiki/Список_ORM-библиотек
https://habr.com/ru/company/ruvds/blog/539098/
https://www.tornadoweb.org/en/stable/guide/running.html
https://www.php.net/manual/ru/install.fpm.php
PHP Дайджест № 222/2 (22 февраля – 25 марта 2022) / Хабр | Веб-студия Nat.od.ua
PHP Дайджест № 222/2 (22 февраля – 25 марта 2022) / Хабр
Дисклеймер: Нет, это не дайджест авторства Романа Пронского. К сожалению, у меня нет достоверной информации — будет ли выходить его дайджест далее.
Однако я взял на себя смелость временно продолжить дело Романа и написать новый дайджест за тот месяц, что прошел с выхода последнего.
Если Роман сможет и захочет далее продолжать свой дайджест — он сам решит, как использовать мой текст: взять в свой проект, как его часть или нет. На всякий случай я ставлю нумерацию дайджеста через дробь. Однако не претендуя при этом на продолжение оригинального проекта.
PHP
Вышли версии PHP 8.1.4, 8.0.17. Обновления в основном посвящены исправлению найденных багов.
RFC (Requests for Comments )
За прошедшее время было не так много событий вокруг RFC.
Allow null and false as stand-alone types
https://wiki.php.net/rfc/null-false-standalone-types
В этом RFC предлагается добавить в систему тайп-хинтинга PHP еще два типа: null и false. Данная возможность позволит писать примерно такой код:
class Foo {
public null $nil = null;
public function foo(null $v): null
{ /* … */ *}
}
// В стандартной библиотеке достаточно много функций, возвращающих int|false или string|false
// Например таких:
function strpos(string $haystack, string $needle, int $offset = 0): int|false
{ /* … */ *}
На всякий случай предлагается запретить декларацию типа ?null — видимо, от греха подальше 🙂
В момент, когда писалась статья, RFC находился на голосовании. Однако его принятие не вызывает никаких вопросов — результат голосования составляет 38 голосов «за» и 0 (ноль, а не null!) «против».
Undefined Variable Error Promotion
https://wiki.php.net/rfc/undefined_variable_error_promotion
Очень интересное предложение, которое фактически сводится к запрету на использование не объявленных явно переменных в PHP.
Сейчас обращение к необъявленной ранее (например через операцию присваивания) переменной производит ошибку уровня E_WARNING, после чего значением переменной становится null, а код продолжает выполняться далее, со следующей строки.
В обсуждении будущего PHP 9 Никита Попов отмечал, что такое поведение — это существенная проблема: дело в том, что ошибки могут обрабатывать хэндлеры, неявно меняющие состояние виртуальной машины PHP совершенно непредсказуемым образом, в отличие от явного выброса и явной же обработки исключения.
В данном RFC предлагается заменить ошибку уровня E_WARNING на исключение класса Error. Голосование закончено, результат весьма предсказуем: 33 «за» и 8 «против», предложение будет реализовано в PHP 9.
Sealed Classes
https://wiki.php.net/rfc/sealed_classes
Новая возможность языка, появление которой, если предложение будет принято, возможно уже в PHP 8.2
Вкратце: возможность для классов (и интерфейсов) ограничивать список своих наследников (и реализаторов). Проще, наверное, показать на примерах:
sealed class Foo permits Bar
{
/* … */
}
class Bar extends Foo
{
/* обычное наследование, без особенностей */
}
class Baz extends Foo
{
/* фатальная ошибка этапа компиляции, наследование не разрешено */
}sealed interface HasPrice permits Product, Service
{
/* … */
}
class Product implements HasPrice
{
/* реализация интерфейса разрешена */
}
class Service implements HasPrice
{
/* реализация интерфейса разрешена */
}
class User implements HasPrice
{
/* ошибка, реализация интерфейса не разрешена! */
}
Наряду с классами и интерфейсами возможностью разрешать своё использование предлагается наделить и трейты. Можно будет указать список классов, которым будет позволено включать в себя данный трейт.
Предложение находится в стадии голосования и, в целом, за его принятие уже подано голосов больше, чем за отказ.
Новости фреймворковSymfonyLaravel
-
Представлен инструмент Translation Checker, позволяющий находить в вашем коде фразы, не покрытые переводами
-
Представлен пакет Telegraph, упрощающий работу с Telegram: создание ботов, работа с чатами, сообщениями и API Telegram
-
Вышел релиз инструмента Visit — клиент для просмотра HTTP-запросов и ответов в человеко-читаемом виде
-
Вышли версии Laravel 9.4, 9.5
Yii
Ввиду того, что сервис OpenCollective более недоступен в России, сообщество фреймворка открывает дополнительный сбор пожертвований в сервисе Boosty: https://boosty.to/yiisoft
Отмечается, что разработка фреймворка замедлится из-за резкого (примерно в 5 раз) сокращения сумм пожертвований.
Дополнительная информация может быть найдена здесь.
Инструменты и библиотеки
-
php-dry: библиотека для поиска дубликатов в вашем коде
-
sebastian/type: коллекция ValueObject-обёрток над нативными типами PHP
-
Laravel Optikey: пакет, позволяющий использовать первичные ключи типа UUID в Laravel
-
Image with text: библиотека, включающая в себя продвинутые возможности создания текста на изображениях.
Интересные статьиХабрДругие источники
Подготовлено при активном участии сообщества телеграм-чата «PHP Russian Talks».
Замечания по текущему выпуску и предложения для следующего можете отправлять автору в личку или в указанный выше чат.
3 совета по удобным интерфейсам за март / Хабр | Веб-студия Nat.od.ua
3 совета по удобным интерфейсам за март / Хабр
Хабр, все мы испытываем негативные эмоции, когда встречаемся с неудобными интерфейсами. Чтобы эти события происходили как можно реже, я пытаюсь доносить лучшие практики. В марте я провел исследования и написал 3 совета, которые, надеюсь, помогут вам делать более удобно для пользователей.
Заставлять пользователя заново вводить email это плохой UX
Ребят, сейчас я хочу поделиться своей болью. У меня дофига паролей, и когда я пытаюсь авторизоваться в каком-то приложении, то часто не могу вспомнить, какой пароль мне нужно ввести. Поэтому я пытаюсь сбросить его, если первая попытка авторизации была провалена.
Ох… И тут я довольно частенько обламываюсь. Все из-за того, что введенный ранее email сбрасывается, и мне приходится заново вводить его! Например, так сделано на сайте Preply.
Чтобы продемонстрировать, что я имею ввиду, попытаемся авторизоваться, введя email и неправильный пароль. После того, как мы не пройдем валидацию нажмем на ссылку «Forgot password» и перейдем на страницу, где введенный ранее email уже сброшен! И нам придется заново вводить его…
У меня 0 идей, почему нельзя сделать так, чтобы email добавлялся автоматически. Например, так реализовано на Booking.
Если мы попытаемся авторизоваться с неправильным паролем, а после ошибочной валидации нажмем на ссылку «Forgot your password?», то приложение перейдет на новую страницу, где ранее введенный email автоматически добавлен. Бинго!
Цифровая клавиатура упрощает ввод чисел
Долгое время мы были вынуждены использовать `type=»tel»` везде, где пользователям нужно было ввести числа. Например, на сайте Телеграмм при вводе кода авторизации вы увидите именно такую клавиатуру.
В этом случае при вводе кода пользователи могут быть сбиты столку символами # и *, а это может привести к ошибкам при вводе. Соответственно, если ошибка случится, то люди будут вынуждены сделать дополнительные действия для ее исправления.
Я предлагаю использовать `inputmode=numeric`. Значение `numeric` позволяет показать клавиатуру только с числами. Поэтому пользователи гарантированно не ошибутся и будут быстрее вводить данные, делая это машинально и не концентрируясь на символах.
Глаголы более понятны, чем существительные
Существует подход использования существительных там, где пользователю нужно выполнить какое-то действие. Например, я нашел такой пример на сайте Etsy. Когда наводишь на иконку колокольчика, появляется подсказка «Updates» (Обновления).
Существительные в этом случае воспринимаются сложнее, потому что когда мы с вами изучали язык, мы узнали, что они представляют объект. Поэтому, когда мы видим существительное, мы подсознательно думаем «Какой это объект?» или «Что это означает?» или любой другой вопрос, который помогает нам получить информацию об объекте.
А вот если мы используем глаголы, то здесь наш мозг работает по другому. Мы знаем, что они представляют «действие». Поэтому, когда встречаем глагол мы думаем о действии. Для примера я покажу такую же ссылку на страницу уведомлений на Booking.
При наведении на иконку колокольчика появляется подсказка «View your notifications» (Посмотрите свои уведомления). Глагол «View» (Посмотрите) призывает к просмотру. Он буквально говорит «Посмотри». Поэтому пользователь, не задумываясь, нажмет на иконку, и получит более привычный опыт взаимодействия.
P.S. Помогаю делать интерфейсы более удобными и доступными. Если вам нужна помощь, то смело пишите [email protected].
Чек-лист по SEO оптимизации для фронтенд разработчика / Хабр | Веб-студия Nat.od.ua
Чек-лист по SEO оптимизации для фронтенд разработчика / Хабр
Привет всем!
Сегодня хотелось бы затронуть тему SEO оптимизации, как ее проводить, для чего и что для этого надо. Как ни как, сейчас это один из мощных инструментов для жизни веб-сайта или приложения.
Что такое SEO
SEO — Search Engine Optimization, то есть, это оптимизация сайта под поисковые движки, и это надо для того, чтоб при поиске какой либо информации, которую наш сайт может предоставить, в поисковиках наш сайт оказался на первых рядах списка выдачи резултата.
Как это работает
Если утрировать и упрощать, поисковые движки имеют роботов/пауков (crawlers), которые считывают данные находящиеся на странице нашего сайта, и делают это они для того, чтоб понимать, какую информацию предоставляет сайт и при каких запросах поиска наш сайт выводить, и на сколько информация, которую наш сайт предоставляет актуальна.
Как нам оптимизировать сайт для SEO
Оптимизация сайта для SEO по большой части подразумевает то, что мы должны разработать сайт таким образом, чтоб роботы/пауки поискового движка могли легко понимать наш сайт.
Нам как фронтенд разработчикам для этого надо позаботиться о следующих вещах:
-
Семантичная и структурированная верстка. На данный момент поисковики обращают внимание на семантику HTML, и если все на div-ах или таблицах, то сайт навряд ли попадет на первые строчки поискового запроса. Семантичная верстка наполняет смыслом теги, и структуры, которые мы создаем в HTML, и это облегчает роботам понимать где и что находится на странице нашего сайта.
-
Правильно использовать и структурировать заголовки на страницах. У каждой страницы должен быть один и единственный тег
, который считается основным заголовком и говорит о чем страница, далее должна соблюдаться вложенность заголовков, то есть h2, у вложенного в него элемента заголовок h3 и т.д.
-
Никогда не забывать alt атрибут у тега
, таким образом мы объясняем роботам, что это за картинка.
-
Указать язык страницы, используя атрибут lang на теге .
-
Правильно указывать название страницы, то есть тег
, он должен быть уникален для каждой страницы и быть длиною до 55 символов, помимо этого значение тега должно отличаться от значения от тега .
-
Использовать мета-тег description: тут пишется описание страницы, на каждую страницу оно должно быть уникальным и длиною до 150 символов.
-
Подключить favicon и иконки для Apple Web Meta, Windows Tiles и прочие иконки
-
Настроить и добавить OG-теги, то есть Open Graph теги: og:type, og:title, og:site_name, og:description, og:image, og:url, og:error для социальных сетей.
-
Удалить комментарии в HTML, это в целом считается хорошей практикой, заливать сайт на продакшн без комментариев в коде/разметке.
-
Подключать стили и скрипты и сторонние библиотеки и прочие не блокируя отрисовку сайта, можно использовать асинхронную загрузку сайта .
-
Обязательно иметь страницу ошибки 404.
-
Оптимизировать производительность сайта, производительность и доступность сайта очень важна для поисковых движков, для этого надо:
-
Использовать как можно меньше узлов HTML, т.е. отказаться от лишних оберток в врестке.
-
Оптимизировать картинки, кропать их до нужных размеров отображения и сжимать, лучше всего использовать формат webp, и fallback на jpg картники в браузерах, где не поддерживается формат webp. Помимо этого, если на странице много картинок, то лучше использовать ленивую загрузку картинок (lazy loading).
-
Оптимизировать JS, удалить мертвый код, не использовать большие библиотеки, если из всей библиотеки вам нужен всего один или несколько методов. Писать код так, чтоб не было утечек памяти.
-
Сжимать все файлы HTML, CSS, JS.
-
-
Если вы работаете над SSR(Server Side Rendered) приложениями, то не забыть про такие вещи как:
-
robots.txt - это конфиг файл, при помощи которого мы можем указать, какие директории, страницы могут индексировать роботы/пауки.
-
sitemap.xml - это файл, который хранит в себе все пути к страницам, он нужен для того, чтоб роботам/паукам было проще найти те или иные страницы у вас на сайте.
-
-
Также, если вы пишите SSR или SPA приложение, то лучше хорошо подумать о том, как вы формируете навигацию(роутинг) в приложений. Навигация должна быть лаконичной, все вложенности должны быть сохранены, и соответствовать семантическим URL . К примеру, если у вас есть пользователь, и в личном кабинете пользователя есть страница "Мои оплаты", то стоит формировать навигацию, к примеру: https://example.com/profile/courses Где, https://example.com/ - хост, profile/ - роут до личного кабинета, courses/ - вложенная страница "Мои курсы"
Лучше с самого начала разработки думать о SEO оптимизации, как ни как, оно очень зависит от качества разработки, верстки и соблюдением мелочей, о которых легко забыть при разработке.
Как работать с i18n в Nuxt.js / Хабр | Веб-студия Nat.od.ua
Как работать с i18n в Nuxt.js / Хабр
Всем привет!
Сегодня хотел поделиться несколькими фишками в работе с i18n.
i18n – это фреймворк для интернализации веб-приложении. То есть, при помощи данного фреймворка мы легко можем реализовать мультиязычность в веб-приложениях.
Nuxt.js мощный инструмент для разработки веб-приложений. Помимо того, что он из коробки предоставляет много полезных утилит и инструментов, также, есть много дополнительных модулей из community, которые позволяют легко интегрировать разные инструменты в Nuxt.js. Посмотреть на сторонние модули для Nuxt.js можно здесь.
Nuxt i18n
Среди сторонних модулей, также есть модуль nuxt/i18n, который под капотом работает на vue-i18n. Данный модуль легко настраивается в Nuxt.js приложениях, достаточно просто в nuxt.config.js добавить модуль и настроить опции наиболее подходяще под проект:
{
…
modules: ,
i18n: {
/* module options */
},
…
}
Работа с переводами
После настройки модуля, можно уже работать непосредственно с переводами. Есть несколько способов работы с переводами. Вынести переводы в отдельные файлы, и хранить их там, хранить переводы непосредственно в nuxt.config.js (не рекомендуется), и хранить переводы в самих компонентах.
Как лучше хранить переводы
Если речь идет о переводах в виде названий кнопок, разных плашек и других переводов, которые используются в абстрактных компонентах, в атомах или молекулах при атомарном дизайне, то можно хранить подобные переводы в самих компонентах, так как они обычны лишены контекста:
{
«ru»: {
«viewers»: «зрителей»
},
«kk»: {
«viewers»: «көрермендер»
}
}
{{ count }}
{{ $t(‘viewers’) }}
Подробнее о подобном подходе хранения переводов можно ознакомиться тут.
А вот если речь идет уже о словах или фразах, которые имеют какой-то контекст к проекту, которые часто встречаются в компонентах, то их желательно хранить как TypeScript или JSON файл в директорий src/i18n
export const ru = {
common: {
all: ‘все’,
},
partners: ‘Организаторы | Партнеры | Организаторы и партнеры’,
page_names: {
home: ‘Главная | На главную’,
contests: ‘Конкурсы | Конкурс’,
events: ‘Мероприятия | Мероприятие’,
faq: ‘Вопросы и ответы’,
live_tournaments: ‘Live турниры’,
rating: ‘Рейтинг’,
shop: ‘Магазин’,
streams: ‘Стримы | Стрим’,
tournaments: ‘Турниры | Турнир’,
},
…
}
Множественность в переводах
i18n позволяет хранить в одном ключе несколько вариации перевода, в том числе и множественности. К примеру, у нас есть слово “Конкурсы”, однако в некоторых местах у нас это же слово в единственном числе “Конкурс”. Хранить это в двух разных ключах неудобно и не эффективно. Поэтому для этого надо хранить данный ключ можно следующем образом:
export const ru = {
contests: ‘Конкурсы | Конкурс’,
}
А уже в компонентах, чтоб использовать данный перевод надо обращаться к методу $tc вместо $t:
{{ $tc(‘contests’) }} // на выходе будет ‘Конкурсы’
{{ $tc(‘contests’, 2) }} // на выходе будет ‘Конкурс’
Данный функционал также можно использовать для слов синонимов, которые встречаются в проекте:
export const ru = {
partners: ‘Организаторы | Партнеры | Организаторы и партнеры’,
}
Переиспользование ключей переводов
i18n также позволяет переиспользовать существующие ключи переводов и объединять их вместе:
export const ru = {
day: ‘день’,
is_weekend: ‘выходной’,
weekend: ‘@:day @:is_weekend’, // ‘выходной день’
}
Интерполяция переводов
Бывают ситуации, когда надо интерполировать переводы. К примеру, мне надо выводить подобные текста:
-
с 24.02.2022 до 25.02.2022
-
24.02.2022 бастап 25.02.2022 дейін
-
from 24.02.2022 to 25.02.22
Дату я получаю с сервера, и дата должна быть обернута в HTML тег . А на разных языках я имею разный шаблон перевода. Для этого можно использовать интерполяцию в i18n:
export const ru = {
date_range: ‘с {from} до {to}’
}
export const kk = {
date_range: ‘{from} бастап {to} дейін’
}
export const en = {
date_range: ‘from {from} to {to}’
}
В данном случае получается, что наши данные, которые мы хотим интерполировать мы прописываем в метках, как {from} / {to}.
В итоге, в нашем компоненте, в шаблоне мы это прописываем следующим образом:
Подробнее об интерполяции можно почитать в документации здесь.
Очень сильно рекомендую вам ознакомиться и изучить документации модуля под Nuxt.js и самого Vue-i18n. Так как там описано много, и о многих утилитах в работе с этим инструментом:
JavaScript редактор диаграмм, который открывает диаграммы из PNG картинок (open source) / Хабр | Веб-студия Nat.od.ua
JavaScript редактор диаграмм, который открывает диаграммы из PNG картинок (open source) / Хабр
dgrm.net | GitHub
<< предыдущая статья
dgrm.net — это редактор диаграмм, с прицелом на трансформацию в карту знаний.
Отличительные особенности:
-
аскетичность,
-
работает на телефонах (одно из немногих web-решений),
-
открытый исходный код.
В процессе разработки появляются интересные моменты. Статья про один из таких моментов: чтение данных из PNG. Исходный код для использования в своих проектах прилагается.
Зачем открывать диаграммы из PNG изображений
Пользовательские интерфейсы сделанные разработчиками славятся своей самобытностью. Возможно, идея использовать изображения в качестве файлов проекта как раз этот случай. Как минимум подход оригинальный.
Все редакторы используют свои файлы проекта. Но это же неудобно:
-
нет превьюшек,
-
при пересылке изображения, надо еще и исходник пересылать.
Удобнее иметь картинку диаграммы, которую при необходимости можно отредактировать.
Глядя на рисунок 1 можно предположить что используется стеганография, или распознавание изображений. На самом деле гораздо проще, и без хаков — формат PNG поддерживает хранение дополнительной информации, например метки времени, имени автора, или любой другой.
dgrm.net записывает в png-файлы JSON с данными диаграммы.
PNG Chunks
Формат PNG хорошо описан на Хабре в статье “PNG — not GIF!”.
Основной момент:
-
png-файлы состоят из блоков, которые называются chunk-и,
-
в файл можно добавлять свои chunk-и.
Рис 2. Структура одного chunk-a PNG (источник “PNG — not GIF!”)
Для своих данных имя chunk-a (например “dgRm”):
-
Можно придумать любое, лишь бы оно не было зарезервировано;
-
Длина имени строго 4 латинских буквы;
-
Регистр букв имеет значение. Для самодельных chunk-ов ставьте все буквы в нижнем регистре, а 3-ю в верхнем.
Таким образом, для хранения строки JSON внутри файла PNG нужно добавить в файл свой chunk.
Чтение/запись PNG chunk-ов на JavaScript в браузереЧтение chunk-а
Chunk-и следуют друг за другом, нужный chunk находится перебором.
Алгоритм поиска chunk-а (листинг 1):
-
берем название первого chunk;
-
если название не совпадает с искомым:
a. берем длину chunk (первые 4 байта см. рис 2);
b. зная длину chunk смещаем курсор на начало следующего chunk. -
повторяем 1 и 2 пока не найдем нужный chunk или ‘IEND’ (конец файла).
/**
* @param {ArrayBuffer} pngData
* @param {number} chunkNameUint32 chunk name as Uint32
* @returns {DataView | null} chunk data
*/
function chunkGet(pngData, chunkNameUint32) {
const dataView = new DataView(pngData, 8); // 8 byte — png signature
let chunkPosition = 0;
let chunkUint = dataView.getUint32(4);
let chunkLenght;
while (chunkUint !== 1229278788) { // last chunk ‘IEND’
chunkLenght = dataView.getUint32(chunkPosition);
if (chunkUint === chunkNameUint32) {
return new DataView(pngData, chunkPosition + 16, chunkLenght);
}
chunkPosition = chunkPosition + 12 + chunkLenght;
chunkUint = dataView.getUint32(chunkPosition + 4);
}
return null;
}
Листинг 1. Функция поиска chunk-а
Краткая справка:
В JavaScript интересный способ работы с бинарными данными.
Цитата:
Объект ArrayBuffer используется для работы с бинарными данными. Он представляет собой ссылку на поток «сырых» двоичных данных, однако работать с ними напрямую возможности не даёт.
developer.mozilla.org
Для чтения данных можно обернуть их в DataView. DataView позволяет прочитать данные в любой позиции в виде числа (с помощью методов getInt8(), getUint32() и др.).
Запись chunk-а
Для записи chunk-а, нужно вставить новый chunk в цепочку. Если chunk с данным именем уже есть — его нужно заменить.
Реализацию можно посмотреть на GitHub — функция chunkSet.
Исходный код
Функции работы с PNG chunk-ами вынесены в один файл. У файла нет зависимостей, поэтому его можно просто скопировать в свой проект.
png-chunk-utils.js
Пример использования:
// Запись chunk-а, на выходе новый blob
const newPngBlob = await pngChunkSet(
// png-изображение
pngBlob,
// имя chunk-а
‘dgRm’,
// значение chunk-а: строка в виде массива byte
new TextEncoder().encode(‘…’));
// чтение chuk-а
const dgrmChunkVal = await pngChunkGet(newPngBlob, ‘dgRm’);
const str = new TextDecoder().decode(dgrmChunkVal);
Листинг 2. Вызов функций записи и чтения PNG chunk-ов
Как поддержать проект
-
Начните использовать, расскажите что думаете.
Любым способом: комментарии, личные сообщения, на GitHub.
Все читаю, веду список предложений. -
Расскажите знакомым.
-
Ставьте звездочки на GitHub.
Telegram-бот на страже порядка в Redmine / Хабр | Веб-студия Nat.od.ua
Telegram-бот на страже порядка в Redmine / Хабр
Невыдуманная история с хеппи-эндом, про то, как бот для Telegram увеличил выручку и упорядочил работу команды разработчиков.
Предыстория
Все началось с того, что в рабочем чате Telegram, где мы обмениваемся рабочими, не совсем рабочими и откровенно не рабочими сообщениями, решили делиться оценками качества булочек и пирожков из соседней пекарни. Булки там представлены в большом ассортименте и глаза около прилавка разбегаются.
Договорились, что каждый, кто отведает пирожок, будет отписываться в чат и ставить оценку от 1 до 5. Со временем должна скопиться история дегустаций и мы сможем высчитать среднюю оценку каждой булочки.
Пирожки кушаем, оценки ставим, время идет. Но кроме рейтинга хлебобулочных изделий, в рабочем чате и работа проскакивает, которая засоряет ленту. В итоге оценки булок смешались с обсуждениями задач. Миссия провалена, статистики нет. Но программисты же всегда могут найти решение. Тут мы вспомнили про Telegram-ботов. Можно и себе помощника электронного организовать. Сказано – сделано. Пару часов и готова первая версия бота, который принимает оценки в общем чате и делится драгоценной статистикой по запросу.
Скриншот общения с ботом:
А что бот может ещё?
После запуска бота начали накидывать идеи, чему бы еще научить нашего электронного помощника. И понеслось. За рабочий день, в коротких перерывах между задачами, добавили несколько мелочей:
-
уведомление, что пора сходить на перекур;
-
уведомление, что пора на обед;
-
уведомление, что пора выпить кофе(с утра) или чаю(файв-о-клок).
Когда наигрались с ботом, задумались о действительно полезных функциях, которые могут упростить рабочий процесс. Вспомнили, что бывают проблемы с продлением SSL-сертификатов и доменов для клиентских сайтов. Не каждый хостинг поддерживает cron или автопродление, приходится регулярно заниматься этим в «ручном режиме». Продлить домен или сертификат не сложно, главное об этом вовремя вспомнить.
Для бота эта задачка оказалась простая:
-
стащить заголовки сайта и определить срок годности SSL-сертификата. Если до часа икс осталось меньше 7 дней, отправить уведомление;
-
сделать запрос в сервис whois, вытащить срок оплаты домена и также сверить с текущей датой. Если домен умрет через неделю, то пора слать уведомление.
Реализация заняла ещё пару часов, но польза от такой фичи уже ощутима. На душе стало спокойнее.
А ещё?
Очевидно, потенциал бота огромный, осталось придумать, какую функцию прикрутить следующей. Покумекали и пришли к выводу, что у нас есть проблема с отчетами и выгрузками таск-менеджера/трекера рабочего времени. Мы используем доработанный напильником Redmine. За последние 3 года дважды пробовали реализовать надстройку для формирования отчётов по задачам, но каждый раз забрасывали, закапывались слишком глубоко, да и пользоваться выгрузками было неудобно. Вдобавок, не все разработчики следят за своими активными таймерами в задачах. За рабочий месяц у нас терялось до 15-20% часов, которые по разным причинам не были отмечены. Бывает, прилетает срочная задача и сразу погружаешься в нее, забыв включить таймер. А случается и простая невнимательность, вспоминаешь про таймер не сразу. Из-за этого собирать ежемесячные отчеты приходилось в полуручном режиме, вспоминая, не потеряли ли часы в задаче. Но восстановить хронологию удаётся не всегда, и месяц закрывается с потерями. При этом все сотрудники загружены на 100%, всегда есть активные задачи на несколько недель вперёд, однако достоверно закрыть все 160 часов не получается.
Постоянно контролировать таймеры тоже не получится, это отдельный «надзиратель» нужен, который только и будет, что приглядывать за трудозатратами.
Постойте-ка… Но у нас же есть бот, который может за этим следить и сообщать о нарушении. А раз уж запустили его в таск-менеджер, пусть ещё и за выполнением регламентов присмотрит: какие статусы меняются у задач, какие дедлайны приближаются, как изменились приоритеты задач и т.д.
Быстренько собираем список проблемных мест, объясняем боту и вот у нас уже новая версия помощника. Пора бы и имя ему придумать. Окрестили бота «Железный Феликс», в честь одного знаменитого дядьки, который хорошо умел присмотреть за выполнением регламентов.
Затратив всего 23 рабочих часа, мы научили Железного Феликса:
-
Проверять активность таймеров программистов. Если таймер не включен, то уведомлять об этом ответственного менеджера и программиста;
-
Проверять задачи и уведомлять сотрудников, если произошли изменения в приоритетах задач;
-
Проверять задачи и уведомлять программистов, если вдруг появилась вторая задача со статусом «В работе». Этот статус означает, что задача именно сейчас в работе, две активных одновременно быть не должно;
-
Напоминать программистам и менеджерам о необходимости добавления комментария к задаче, если в ней фиксировалась активность в течении дня (отмечены трудозатраты) и не поступало текстовых комментариев. Уведомление отправляется в конце рабочего дня и дублируется утром на следующий день, если комментарий все еще не был добавлен;
-
В конце рабочего дня для каждого программиста проверяется количество отмеченных трудозатрат и уведомляет менеджера, если было отмечено меньше 7 часов;
-
Через пол часа после завершения рабочего дня проверять активные таймеры. Если такие есть, отправлять уведомление с напоминанием остановить таймер и скорректировать фактическое время. Бонусом приходят соболезнования, если вдруг сотрудник еще работает;
-
Отправлять уведомление о необходимости начать выполнять задачу, если для неё было заранее установлено напоминание;
-
Уведомлять ответственного о смене статуса в задачи;
-
Уведомлять ответственного, если он передал задачу с неправильным статусом или не передал её дальше;
-
Утром напоминать менеджеру об открытых задачах, в которых давно не было активности;
-
В конце рабочего дня отправлять отчет менеджеру о трудозатратах всех программистов за день с разбивкой по задачам;
-
В конце рабочего дня по пятницам отправлять отчет трудозатрат программистов за неделю с разбивкой по проектам;
-
Уведомлять менеджера, если фактические трудозатраты приближаются к плановым или подходит дедлайн;
-
За час до конца рабочего дня напоминать всем, что есть «База знаний» и туда нужно что-то добавить, если были интересные/нестандартные ситуации в течении дня;
-
По запросу бот создает поддомены и разворачивает тестовые сайты. Удобно для верстальщиков – не нужно просить разработчика или сисадмина.
-
По запросу бот может найти информацию в базе знаний (блог на WordPress с рабочими заметками и регламентами) и отдать ссылку на полное описание
Чтобы считать активность таймеров, пришлось залезть напрямую в базу данных Redmine, поскольку таймтрекер у нас нестандартный, а настроен через плагин. Также пришлось импровизировать, чтобы быстро реагировать на смену статусов задач и перестановку их на scrum-доске. Api Redmine не даёт таких колбеков, а для скрама у нас вообще отдельный модуль. Поэтому колбеки мы добавили сами, немного модернизировав код Redmine. Для всех остальных пунктов были использованы стандартные api таск-менеджера.
Звезды из GTA за проступки
Чтобы было проще выполнять отладку всех функций бота, стали собирать логи событий, которые обрабатывает Железный Феликс. Когда все заработало и все баги были исправлены, логирование решили оставить и даже пустили в дело. За каждую ошибку стали начислять звезды как в GTA. Больше проступков – больше звезд. Все «косяки» обнуляются в конце рабочего дня, но перед уходом домой, в общий чат приходит сообщение со статистикой.
Сперва это было ради шутки, но неожиданно появился азарт и количество ошибок стало уменьшаться. Никто не хотел схлопотать звезду. В первые пару дней работы бота мы собирали по 3-4 звезды каждый, а спустя неделю – 1-3 шт на тестовую группу.
Генерация отчетов
Бот быстро научил сотрудников пользоваться таск-менеджером по регламенту, уже через неделю до минимума сократилось неучтённое рабочее время. А имея корректные фактические часы, можно автоматизировать генерацию отчетов.
Мы не стали делать для этого отдельный интерфейс, реализовали запросы через бота – всё в одном месте. Это и удобнее в использовании, и быстрее в разработке, не нужен фронтенд. За один рабочий день обучили Железного Феликса формировать отчетность в Excel: выгрузка за любой период времени по любым проектам. В отчет попадает полный список задач и трудозатрат, с учетом всех параметров, которые мы используем при формировании сметы.
Хэппи-энд
В первый же месяц, в тестовой группе под присмотром бота, общее количество отмеченных часов в задачах, увеличилось и потери сократились на 12,5%. Это как раз те часы, которые мы всегда теряли. Плюс ко всему, теперь экономится менеджерское время, которое уходило на составление отчетов. В итоге мы не только покрыли трудозатраты на разработку бота, но и увеличили выручку, поскольку с большей частью заказчиков мы работаем с оплатой по факту трудозатрат и каждый час = деньги.
Ну и самое главное, команда научилась работать по регламенту, теперь не путаются статусы задач, приоритеты всегда понятны, а программистам не приходится держать в голове все итерации, которые должны быть у задачи. Если что-то идет не по плану, то бот всегда подскажет и напомнит.
Послесловие
В статье нет технических моментов, старался рассказать только про логику работу бота и поделиться радостью, что иногда простые решения приводят к ощутимому профиту. А интересные идеи могут появиться из совсем дурных и не связанных с работой затей.
Если кому-то интересны технические нюансы, то спрашивайте в комментариях, постараюсь ответить всем. Каких-то инноваций в реализации бота не было, все уже рассказано и ни один раз, но если запросов будет много, то подготовлю статью с описанием для технарей.
С наилучшими пожеланиями Ипатов Евгений, руководитель отдела разработки в OWL agency.












