npm и интерфейс

или достоинства метафор завтрака

Работа с npm в интерфейсе сопряжена с множеством проблем. Краткое изложение этого можно найти в этом сообщении в блоге npm. В следующей статье я исследую способ беспрепятственного использования и повторного использования интерфейсных компонентов (таких как партиалы Sass) через реестр npm.

Эта проблема

Для целей этой статьи давайте рассмотрим самую фундаментальную проблему для внешнего интерфейса: ад зависимостей.

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

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

Однако в действительности все иначе.

Пакеты будут иметь зависимости, которые конфликтуют с зависимостями других пакетов. В этом, все еще очень упрощенном примере, мы получаем 5 зависимостей для нашего проекта. Это потому, что, хотя для каждого пакета по-прежнему требуются одни и те же зависимости, они зависят от разных версий. Npm следит за тем, чтобы все по-прежнему работало, дважды устанавливая пакеты A и B под те пакеты, которые они требовали.

Теперь представьте, что каждая зависимость имеет свои собственные зависимости, и большинство из них также конфликтуют. В экосистеме npm нередко бывает 30 000 или более зависимостей.

Это не проблема, если вы используете npm для серверной части. Здесь нам не нужно заботиться о размере нашего проекта. Однако во внешнем интерфейсе, где учитывается каждый килобайт и оптимизируется каждая миллисекунда, у нас нет возможности. Теперь подумайте о CSS-стране, где каждая переменная или объявление являются глобальными. Даже с действительно умными обходными путями JavaScript мы все равно удваиваем количество вещей, которые должны естественным образом каскадироваться.

По этой теме написано много вещей, и большинство из них связано с добавлением CSS в Javascript. Я думаю, что это очень хорошее решение для проектов, которые полностью полагаются на Javascript. В других случаях, когда мы не хотим вводить большой фреймворк Javascript для управления и масштабирования нашего CSS, это может быть неправильным путем. Я думаю, что совместное использование CSS, Sass, postCSS и т. Д. Не должно зависеть от вашего вкуса Javascript, поскольку CSS - это один из трех основных языков, которые веб понимает изначально.

Куда мы должны пойти

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

В идеале у вас должна быть возможность создавать небольшие компоненты внешнего интерфейса и делиться ими в реестре. Не нужно изобретать кнопки каждый раз, когда вы начинаете новый проект. Настроить их в соответствии с вашими потребностями легко с помощью переменных CSS / Sass. Частичные Sass - это распространенный способ модульного построения вашего сайта. Мы просто пока не используем их повторно и не распространяем. Мы также не проверяем каждую из них. Это сделало бы вещи более сложными и потребовало бы бесконечного набора инструментов, верно? Но почему мы не можем использовать то, что уже разработала npm? Огромный реестр многоразовых битов с версией, которые можно легко установить и использовать повторно.

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

Решение

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

  1. Держите зависимости плоскими и избегайте конфликтов
  2. Используйте существующие технологии, которые достаточно хорошо известны
  3. Не навязывайте инструменты, среду или предпочтения

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

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

Введите Блин,

инструмент, который я создал для обработки сообщений об ошибках, связанных с зависимостями между сверстниками, а затем и с некоторыми другими. Мы назвали его «Блинчик», потому что он делает вещи плоскими. Собственно, на этом метафора заканчивается. Pancake проверит все ваши зависимости на предмет конфликтов зависимостей и ошибок с помощью полезного сообщения об ошибке.

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

Я выбрал тихий подход: добавив pancake в качестве зависимости к каждому плоскому пакету и запустив его из обработчика post install этих пакетов. Это означает, что вам не нужно устанавливать его или даже запускать вручную. Он будет запускаться каждый раз, когда вы устанавливаете пакет, подготовленный для Pancake.

Теперь мы уверены, что устанавливаемые вами пакеты плоские. Больше никакого ада зависимости. Это начало, но нам придется вручную импортировать каждый пакет в ваши файлы sass.

@import ‘../../node_modules/your-packageA/dist/_index.scss’;
@import ‘../../node_modules/your-packageB/path/to/_index.scss’;
@import ‘../../node_modules/your-packageC/_packageC.scss’;

Это большая работа, если вы действительно хотите быстро повторно использовать небольшие компоненты. Поскольку Pancake уже запущен, я добавил к нему систему плагинов. Pancake устанавливается, загружается и запускается после установки каждого пакета, поэтому я подумал, что важно сделать его как можно более легким. Я перенес все дополнительные функции в плагины. Основное приложение имеет только одну зависимость, которая необходима для его запуска на узле 5 и выше. После проверки зависимостей ваших пиров на конфликты, Pancake проверит конфигурацию вашего package.json файла. Если вы не отказались от плагинов, Pancake установит и запустит для вас плагины, которые обрабатывают Sass, postCSS или что-то еще, что вы можете поставить в своих плоских пакетах. Эти плагины могут компилировать и сохранять файлы для вас каждый раз, когда вы устанавливаете новый пакет и помещаете его в любое место по вашему выбору. Плагин, например может скомпилировать ваш Sass, чтобы вам не приходилось фиксировать код CSS. У нас есть базовый пакет с множеством переменных. В зависимости от того, какую версию ядра вы используете, CSS вашего пакета может отличаться, что делает невозможным его предварительную компиляцию. Вам также может понадобиться плагин SVG. Он генерирует резервные изображения PNGS из ваших SVG и создает таблицу спрайтов SVG.

Как это отразится в вашем рабочем процессе?

Плагин pancake-sass сгенерирует и сохранит файл со всеми уже включенными текущими пакетами Pancake. Все, что вам нужно сделать, это включить этот файл в свой проект Sass, и каждый раз, когда вы устанавливаете новый пакет, ваш проект будет автоматически обновляться. Это означает, что вы сразу получите новый код Sass. Нет необходимости искать новый путь в папке node_modules и импортировать его вручную.

Файлы, сгенерированные Pancake, являются артефактами вашего package.json файла и могут легко игнорироваться системами контроля версий, такими как git. Что бы вы ни делали, один и тот же package.json файл всегда будет генерировать одни и те же файлы в одних и тех же папках. (Это отличается от подхода беседки, когда конфликты дают вам выбор, поэтому один package.json файл может привести к совершенно разным результатам)

Эй

Pancake может сделать для вас еще много всего. Он представляет собой набор инструментов, который вы можете расширить для всех плоских пакетов. Они не обязательно должны быть только на CSS. Блин следит за тем, чтобы все настройки были сохранены в вашем package.json файле. Таким образом, все будут на одной странице. Конечно, вы можете отключить и это. Перейдите в GitHub Readme, чтобы узнать больше.

Но как насчет моих сборок ci?

Мы сами работаем с непрерывной интеграцией и знаем, как важны быстрые ci-сборки. Вот почему поведение Pancake можно настраивать. Вы можете изменить папку, в которой хотите сохранить файлы импорта, игнорировать определенные плагины или полностью отключить их. Однако будьте осторожны: некоторые службы CI во многом полагаются на кеширование и не запускают фактическую команду npm install. В этом случае вам нужно будет указать в сборке запускать pancake вручную после npm install.

Как я могу это попробовать?

Зайдите в Австралийский GOV.AU UI-Kit, чтобы попробовать. Каждый модуль Design System поставляется с Pancake, и каждый модуль очень быстро использовать и повторно использовать.

Просто создайте новую папку с package.json файлом (Pancake нужен package.json файл, иначе он выйдет из строя, как грязная авария на кухне с брызгами масла) и начинайте установку пакетов:

npm install @gov.au/header @gov.au/body @gov.au/footer

Теперь включите сгенерированный файл pancake.sass в ваш основной файл Sass. Если вы чувствуете, что вам не хватает пакета, просто установите его, и ваши файлы Sass обновятся автоматически.

npm install @gov.au/buttons

Это не помешало моему рабочему процессу. Он работает очень быстро, и мне не нужно снова думать о Sass partials. Я могу делиться ими гораздо быстрее и быстрее добираться до самых сложных моментов.

Больше не нужно изобретать велосипед.