Делаем фильтрацию интерфейса более выразительной

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

В наши дни методы .map(), .filter() и .reduce() помогают сокращать или управлять большими наборами данных. Однако представьте, что вам нужны все имена пользователей из элементов, опубликованных за последнюю неделю, которые содержат более пяти комментариев, и отсортируйте их по имени. Вот тут-то и пригодится Needle! Итак, допустим, вы хотите получить все записи, которые содержат возраст старше 30 лет, не правда ли, было бы здорово просто написать .bigger('age', 30)? Что ж, теперь ты можешь. Если вам нужно получить фрагментированный результат парами по 5 из нового массива, подойдет .chunk(5).

По сути, Needle помогает найти вашу иголку в стоге сена данных, сжатых только ~5.2kb gzip. Фильтрация, как правило, в ближайшее время становится по-настоящему уродливой, к тому же глубокие вложенные слои объектов в объектах нелегко получить, и поэтому имело смысл опубликовать более интуитивно понятное, более простое и увлекательное решение. Создавая Needle, я имел в виду цель сделать фильтрацию через фронтенд блаженством, а не хлопотами.

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

  • ✍️ Максимально интуитивно понятные варианты макета: реализация синтаксиса, как если бы вы пишете предложение. Needle - это не новаторская концепция, но она позволяет сделать что-то повторяющееся простым, и это то, что в конечном итоге имеет значение!
  • 💡 Обеспечение читабельности и поддержки кода: обеспечение простоты за счет разделения ответственности и, следовательно, сохранения возможности повторного использования кодовой базы. С простой, но последовательной файловой структурой я заложил основу пакета.
  • 🏗 Написание тестируемой кодовой базы, которая может быть легко отделена: убедитесь, что каждый фрагмент кода обслуживается, и сохраняя разделение проблем. Использование как принципов функционального программирования, так и ООП, объединение лучшего из двух миров.
  • ✏️ Документирование всех ресурсов и опций: что касается самоочевидного кода, документация упрощает начало работы с неизвестным источником. Установив несколько примеров и создав обширный документ README, который будет сопровождать готовый продукт.

Простота по дизайну

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

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

Теперь, в этом случае, у нас есть набор данных, содержащий 3 объекта с некоторыми прямыми данными. Мы можем видеть запрос, используемый для выбора, где мы выбираем хобби «Фильмы» .where('hobbies', 'Movies'), что означает, что мы сначала извлекаем первые два элемента из массива данных. Хорошо, отлично, но теперь нам нужны только записи с именем «Сандер», поэтому мы используем метод .andWhere('name', 'Sander'), чтобы сузить выбор. «Николь» и «Джон» теперь исключены. Но тогда мы действительно хотим включить все элементы возрастом старше 40 лет, используя метод .orWhere('age', '>', 40), мы снова включаем «John» в микс. Теперь мы сортируем результаты, используя .sort('name') и .log() результат в консоли. Теперь мы объединили всеобъемлющий и эксклюзивный фильтр данных, а также некоторую сортировку с помощью всего 5 строк кода, простого, легкого и понятного.

Пройти лишнюю милю

Теперь все это кажется крутым, но что, если вам нужно сделать действительно обширную фильтрацию, будет ли Needle по-прежнему работать? С помощью методов .query(), .and() и .or() вы сможете сделать все возможное, если это необходимо. Либо с использованием методов, предоставляемых Needle, но с возможностью включения пользовательской логики в микс. В приведенном ниже примере мы видим, что запрос представит новый параметр как для набора данных, так и для экземпляра пакета, что означает, что каждый параметр может быть вложенным, комбинированным и настраиваемым, если вы возвращаете массив элементов.

Разделение закулисной логики

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

«Итак, допустим, вы хотите получить все записи, которые содержат возраст старше 30 лет, разве не здорово было бы просто написать .bigger('age', 30)? Что ж, теперь ты можешь! »

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

Затем ядро ​​расширяется до класса Needle, который содержит все методы. Используя магию this, я смог убедиться, что каждый метод имеет доступ к значениям, которые необходимо передать. Поскольку Javascript не поддерживает использование частных, защищенных или общедоступных методов, я обязательно поставил перед каждым методом префикс _. С помощью некоторой магии предварительной обработки я абстрагировал как помощники, так и переменные, чтобы ограничить размер файла и дополнительно абстрагировать (и предотвратить использование) эти частные функции.

За некоторыми исключениями мне удалось ограничить большинство функций небольшим количеством строк. Разделение логики на несколько папок гарантирует, что функции можно будет легко найти, а утилиты можно будет повторно использовать в кодовой базе. Это привело к уменьшению размера пакета. Я хотел иметь решение без зависимостей (за исключением некоторых devDependencies), окончательная сборка не зависит от каких-либо внешних решений.

С помощью нескольких дополнительных приемов пакет needle.pkg.js пакета был ограничен только ~5.2kb gzip и ~17.4kb размером файла, хотя он содержит более 60 методов, предназначенных для использования, эти методы отвечают либо за получение, сортировку, отладку, создание шаблонов, и за фильтрацию. , объединение, манипулирование и / или сохранение данных.

Тестирование кода

С небольшими фрагментами кода и четким разделением задач тестирование можно было легко реализовать. Для тестирования я предпочитаю использовать Jest, платформу тестирования, созданную Facebook. Поскольку у меня уже был некоторый опыт работы с Jest, было вполне разумно настроить автоматический тест, чтобы предотвратить ошибки при сборке пакета и объединить более 100 файлов в процессе сборки.

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

С помощью Jest я смог создать наборы тестов, которые содержат несколько вариантов использования одной и той же функции, убедившись, что каждый предполагаемый аргумент будет соответствовать окончательной сборке. Вместе с Github Actions я автоматизировал свое тестирование при каждом новом продвижении к основной ветке в рамках проекта. Простота использования Github Actions стала настоящим благословением для моих усилий по постоянному тестированию и предотвращению внесения критических изменений в рабочую среду.

Идя под капот

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

Использование простых коротких встроенных заметок в разметке JSDoc дает дополнительное представление о параметрах каждой функции в базе кода. О да, проверяя репозиторий, вы могли заметить, что я использовал Gitmoji, чтобы дать некоторый «крутой» контекст своим коммитам. Добро пожаловать в ненависть. Если вы не хотите углубляться в подробности, наверняка существует README.md документ, содержащий примеры использования различных методов на практике. Разделив документы на главы, мы убедились, что длина файла ограничена самым важным. Даже если вам не нравится читать (… вы все еще здесь?), Есть каталог, содержащий примеры в простом index.html файле, который визуализирует фактические результаты в таблицах, так что вы можете поиграть с использованием Needle и некоторых данных макетов.

Опыт

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

Поскольку я работал над пакетом в свободное время, у меня было дополнительное время, чтобы переосмыслить принятые решения. Это заставило меня узнать о рефакторах и использовании разных принципов, создавая что-то, чем я бы с удовольствием пользовался сам. Дополнительные сведения об управлении размером пакета, разделении, тестировании и действиях Github позволили мне получить новые полезные сведения для любых будущих проектов. Вы можете проверить проект в моей учетной записи Github (в процессе). Надеюсь, вам понравится! Быть в курсе.