Пишу про разработку вообще и в частности про: JavaScript, HTML5, CSS3, AngularJS, ReactJS, Agile.

Таблица умножения в функциональном стиле

Итак, задача простая – вывести таблицу умножения. Поскольку ничего такого в этом нет, то немного усложним – нужно сделать максимально функционально, то есть вообще не использовать циклы. На выходе должно получиться вот так:

multiplication-table

Самое смешное, что в JS нет явного функцонального способа создать цикл. Если речь заходить о циклах, то перед глазами сразу встает for или while, но они же ни разу не фенкциональные =)

На языке Scala можно решить это достаточно просто:

А все потому, что циклы тут умеют сами возвращать значение. Но это в скале, а вот в JS все иначе.

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

Кстати, я об этом уже писал – Создаем массивы в JS

Это, кстати, и будет самым “сложным” этапом, после этого весь остальной код достаточно тривиален:

Поделиться:

Консоль хрома теперь не интерпретирует код сразу как нажали на enter

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

console-brackets-boundaries

Да, скорее всего это обновление еще с прошлой версии. Каюсь ребята, забыл протестировать, а ждал уже давно 🙂

Поделиться:

Подключение стилей через webpack

Подключать стили через webpack не очень сложно, есть два основных варианта:

  • Собирать все стили в один внешний файл css
  • Хранить стили в файлах js и встраивать их уже во время парсинга

Преимущество хранения в одном файле в том, что все стили подгружаются отдельно и отсутствует этап манипуляции DOM’ом. Это, хорошо, потому что сокращается время парсинга. Это, кстати, самый емкий по настройкам способ. Нам потребуется использовать плагин ExtractTextplugin, для экспорта стилей. Я обычно использую less, для работы со стилями, но сути дела от это не меняет.

webpack.config.js

Встраивать стили в js файлы проще. Для этого дополнительный плагинов не требуется, достаточно только указать каким “лоадером” парсить стили:

webpack.config.js

Я предпочитаю использовать второй способ – встраивать стили в js файлы. Тому есть несколько причин:

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

Как не надо расходовать пространство на мобильном сайте

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

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

crunchbase-ios-chrome

Это еще в хроме так, у которого нет встроенной нижней панельки. В сафари полезного места еще меньше, тут все гораздо мрачнее:

crunchbase-ios-safari

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

У меня все.

Поделиться:

Разрешение на показ сообщений сайта

Для меня загадка почему некоторые ресурсы запрашивают разрешение на показ “нотификаций” при первой загрузки сайта. Я же только что пришел! Дайте мне для начала осмотреться, проникнуться, понять что я без вас жить не могу. А то я ведь сейчас отменю, потому что все сайты подряд же спрашивают и я уже всем первым делом отказываю (синдром первой красавицы класса), а уже потом пойму, что мне без вас никак, а вот включать сам ручками уже ничего не буду. Хром же вам снова не даст показывать это сообщений. Хром на мой стороне, даже если я неразумен и просто котиков смотрю в интернете.

Господа маркетологи, вразумите владельцев сайтов или, увожаемые владельцы, вставьте пистон маркетологам, они впустую вашу деньги расходуют. К программистам претензий нет, они не ведают что творят.

notifications-onload

PS

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

Ссылки по теме:

Поделиться:

Frontend аудит сайта – adme.ru

Сегодня опять сайт широкой тематики – adme.ru. Основное направление сайта, как редакторы сами его определяют, это творчество и все, что с этим связано. Ходовой товар, правильно делают, давайте посмотрим, что творится у них “под копотом” 🙂

adme-ru

CSS

Сайт совершенно не адаптивный. То есть не то чтобы “не до конца, но рассчитан не некоторые размеры экрана”, нет, нет – в стилях вообще не прописан media-query. Это по-своему неожиданно, потому что верстка в принципе простая и на первый взгляд сделана как раз для адаптивности.

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

adme-ru-css-usage

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

И “important” в стилях тоже не стоит применять. Без него можно справится. Особенно странно “important” выглядет в сцепке с ховером. Это что же до него за каскад стоит, что без этого бронебоя не обойтись?

adme-ru-css-important

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

JS

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

Заглянем что там внутри. Тут два основных файла:

  • js-common
  • js-common-footer

Думаете потому что один сидит в хедере, а второй в футере? Нет, не угадали! Может раньше так и было, но теперь оба сидят в футере, собственно туда им и дорога конечно.

Основной код находится в файле “js-common”, файл “js-common-footer” и меньше и в нем код больше напоминает настройки, обрывки данных для разных категорий, ничего особо интересного нет. Единственное чем этот файл примечателен это тем, что он в глобальном скопе объявляет "use strict"; на 403 строке.

Ба-бах! Разработчики, как будто говорят – мы уверены в своем коде и в библиотеках, которые подключаем, у нас не могут внезапно всплыть несостыковки из-за глобальной директивы. Ну, может у них и правда все так круто, я не знаю 🙂

Весь функционал js на фронте построен вокруг jQuery, который использует кастомные плагины. Это хорошо видно из файла “js-common”.

Сайт достаточно насыщен интерактивом, поэтому очевидно, что нужно применять некий паттерн для управления кодом. Команда adme.ru используют объектно ориентированный подход. Разумеется в случае с js этого описания не достаточно и нужно уточнить, потому что вариантов исполнения этого подхода несколько.

Для начала посмотрим на основной объект, который обеспечивает ООП:

adme-ru-lixil

Я не знаю с чем связанно название “Lixil”, вполне возможно сокращение от чего-то, кстати, если есть догадки, то пишите в комментариях. Итак, у объекта есть три метода: “extend”, “mixin”, “export”:

  • extend – принимает два объекта и выстраивает цепочку наследование между ними, через прототипы.
  • mixin – копирует методы объектов. Принимает два или более объектов. Первый объект – это тут, в который свойство последующих будут скопированы.
  • export – “экспортирует” объект в указанное пространство имен (namespace).

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

Создаем новое пространство имен и добавляем ему свойства:

Создаем базовую функуию, от которой будем наследовать все остальные:

Добавляем методы, которые должны быть доступны дочерним объектам:

Теперь мы можем применить наследование:

Вот так и продолжаем подключать модули и развивать приложение. Такой подход достаточно надежен и позволяет расти приложение и развивать кодовую базу. Однако, по-прежнему нет решения для модели данных и все хранится в DOM’е.

Вполне возможно, что имело бы смысл добавить хотя бы Backbone, для более слаженной работы с данными.

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

adme-ru-imperative-approch

В декларативном же подходе вы определяете модель данных и относительно ее изменений, происходит изменение в приложении. Яркий пример такого подхода – это React вместе с Redux (или любой другой вариант декларативной модели).

Разумеется каждая команда выбирает свой путь, по которому будет идти в разработке, что не мешает нам высказать свое оценочное суждение 😉

Ссылки по теме:
Essential JavaScript Namespacing Patterns
Declarative programming

Поделиться:

И снова обновляю версии в проекте на реакте

Стандартная ситуация – обновляем версии в достаточно большом проекте и начинаем тихо материться. Сколько же успевают обновить и сколько переписать. Фронтенд он такой фронтенд. Обычно я начинаю с самых простых пакетов и не спеша поднимаюсь к основным библиотекам.

babel

babel-preset-latest (или babel-preset-es2015, babel-preset-es2016, и babel-preset-es2017 вместе) – все это теперь деприкейтед. Вместо них просто используем babel-preset-env. Что в принципе не так уж и плохо. Тем более что, теперь просто в настройках указываем какие версии браузеров поддерживаем.

Например, последние две версии всех браезеров, кроме сафари, там начиная с седьмой:

storybook

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

Ну и дополнительная сложность в настройке препроцессора. Я пользуюсь less-ом и для этого нужно подправить файл конфигурации webpack для storybook:

Плюс к тому перетасовали плагины (addons) и нужно иметь это ввиду. В частности аддон для дополнительной информации @storybook/addon-notes

enzyme

Enzyme переписал подход к конфигурации. Теперь для каждой мажорной версии реакта нужно использовать свою библиотеку адаптера и для тестов нужна конфигурация этого адаптера:

И тут возникает вопрос куда же эту настройку совать, если у меня все тесты бегут на jest’е. В каждый файл что ли импортировать? Конечно нет, этот вариант так себе. Лучше всего импортировать автоматически через настройки фреймворка ваших тестов. В случае с jest’ом делаем вот так:

Да, вам так же понадобиться “raf/polyfill”, для всех полифилов. Подробнее про это можно посмотреть вот тут React 16 JavaScript Environment.md

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

Поделиться:

Решение проблемы с анимацией preact, react

В продолжение предыдущего поста “Баг с анимацией в списке“. Проблема была с тем, что не были указаны ключи для элементов в списке. Preact на это не ругается, а просто перестает работать адекватно, react же начинает писать предупреждения в консоли и всячески привлекать внимание. Тут однозначно 1:0 в пользу старшего брата.

Однако, только добавив ключи проблема не исчезла. Она только приобрела другой оттенок. Сейчас покажу нагляднее. Обратите внимание на анимацию ниже. Заметьте, что как только я нажимаю в первый раз на элемент, то зачеркивание появляется мгновенно, и только потом начинает появляться с анимацией. Очень неприятная особенность. Уточню, что первый пример написан на preact’е.

preact-key-bug

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

Поэтому я просто заменил фреймворк на react и все сразу начало работать. Обратите внимание, что анимация работает всегда:

react-key

Собственно именно этого мне и хотелось добиться. Так что я preact’ом я пока закончил эксперименты, будем продолжать работать со старшим братом 🙂

Кстати, если кому интересно, то код этого проекта есть у меня в гитхабе: https://github.com/artemdemo/todo-smooth. Если кому интересно, то велкам.

Поделиться:

Вышел новый React 16 – что нового

Итак, наконец-то вышла 16-я версия библиотеки и хочется поговорить о некоторых обновленных и добавленных фичах. Пишу, конечно же о том, что мне в первую очередь бросилось в глаза, если хотите что добавить – велком в комментарии 🙂

react-16-fiber

Во-первых, ребята подошли массированно к улучшению библиотеки и полностью ее переписали. Вместе с тем API не поменялся, за что отдельное спасибо. Файлы библиотеки стали на 30% легче без потери качества:

  • react теперь весит 5.3 kb (2.2 kb gzipped), раньше был 20.7 kb (6.9 kb gzipped).
  • react-dom теперь 103.7 kb (32.6 kb gzipped), раньше был 141 kb (42.9 kb gzipped).
  • react + react-dom вместе весят 109 kb (34.8 kb gzipped), раньше были 161.7 kb (49.8 kb gzipped).

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

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

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

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

Новая возможность – теперь в реакте есть порталы. Порталы это возможность рендерить часть компонента в другом элементе дома, а не в родителе данного компонента.

Это может быть полезно в тех случаях когда нужно показать контент в компоненте, который “не вмещается” в компонент. Например, всплывающую подсказку. С ними обычно проблема в том, что если они будут вложены в тег со стилем “overflow: hidden”, то часть подсказки будет отрезана. Разумеется это проблема и приходится вкладывать ноду подсказки в другую часть DOM’а и стилями выставлять ее положение. Теперь в реакте можно будет с этим работать удобнее работать (ну по идее).

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

Среди таких возможностей – асинхронный рендеринг. Я думаю, что ни для кого не секрет, что браузер не умеет делать сразу много дел одновременно, особенно это касается рендеринга. Самое лучшее, когда все разбито на части и рендерится постепенно. Тогда контент появляется плавно и не “замораживает” работу уже появившихся на экране элементов. Однако, это только анонсированно, появится в будущих релизах.

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

А пока, хороших выходных, парни 😉

Поделиться:

Баг с анимацией в списке – preact

Обнаружилась достаточно интересная сложность в работе с анимацией в preact (вполне возможно, что она относится и к реакту, я пока не тестировал). Все связанно с тем, что фреймворк хочет по-максимому реиспользовать элементы DOM’а и старается где можно (с его точки зрения) просто менять текст, а не удалять ноды.

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

preact-animation-bug

  • Пометили первый элемент списка.
  • После этого нажали на удаление этого элемента.
  • После удаления вдруг начинает работать анимация на двух других элементах.
  • WTF,… Carl?

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

Продолжение следует.

Поделиться: