0.20.6 • Published 2 years ago

@neoflex/fastdata-ui-kit v0.20.6

Weekly downloads
-
License
-
Repository
-
Last release
2 years ago

Библиотека компонентов DesignSystem UI

Проект совмещает библиотеку, сторибук, и CRA приложение consumer. В процессе разработки компонентов, даёт возможность напрямую отображать их в сторибуке или CRA, минуя бандлинг. Предполагается наличие yarn, или npm установленных глобально.

Общие сведения

Библиотека

Бандл библиотеки публикуется в git-репозиторий https://neogit.neoflex.ru/fastdata/fastdata-ui-kit. Каждая опубликованная версия представляет собой один коммит в ветке master. Номер версии бандла (такой, как 0.2.2) сохраняется в сообщение коммита, в файл package.json, и в легковесный тег, которым помечается коммит. Сохранение версии в теге позволяет consumer'ам использовать фиксированную версию бандла: npm i @neoflex/fastdata-ui-kit@latest --save. Если пакет добавляется без указания версии (#0.2.2), будет использоваться последняя опубликованная версия.

Точка входа бандлера - src/components/index.js. Всё что экспортируется в этом файле, попадает в бандл, и будет доступно consumer'ам через import { ... } from '@neoflex/fastdata-ui-kit'.

Репозиторий с бандлом хранится в каталоге lib-build (будет склонирован при первом билде бандла), и используется для публикации новых версий.

npm-скрипты билдинга/публикации:

  • yarn lib-build - собирает бандл из исходников. Сейчас это один файл - index.js. Предварительно клонирует (или обновляет, git pull) репозиторий в каталоге lib-build. В итоге получаем свежий репозиторий с перезаписанным файлом lib-build/index.js
  • yarn lib-publish - коммитит и пушит бандл (если в нём есть изменения). Принимает параметром номер публикуемой версии. Если параметр не указан, запросит номер версии в консоли, предлагая в качестве значения по-умолчанию, номер
    предыдущей версии увеличенный на 0.0.1
  • yarn lib-bp - последовательно выполнит скрипты lib-build и lib-publish. Как и lib-publish, может принимать параметром номер версии
  • yarn lib-rollup - только собирает бандл lib-build/index.js, без предварительной подготовки репозитория в каталоге lib-build. Удобно использовать при отладке бандлинга. Также используется командой lib-build

Сторибук

Сторибук визуализирует для каждого компонента JSX, возвращаемый одной или более story - функциями принимающими args от сторибука, и рендерящими некоторым образом компонент. Поиск stories производится в файлах src/**/*.stories.js. Каждый именованный экспорт в таком файле описывает одну story, а export default задаёт доп. параметры для stories в файле.

npm-скрипты:

  • yarn story - запускает dev режим сторибука
  • yarn build-storybook - собирает бандл сторибука в каталог storybook-static

CRA приложение consumer

Содержится в каталоге src/cra, точка входа - src/cra/index.js.

npm-скрипты:

  • yarn start - запускает dev режим приложения
  • yarn build - собирает бандл приложения в каталог build

Сторибук и CRA импортируют компоненты библиотеки через файл src/config/library_proxy.js, который используется для переключения между режимом использования исходников компонентов напрямую из src/components/index.js, и режимом использования бандла node_modules/@neoflex/fastdata-ui-kit. Переключение между этими режимами можно производить с помощью npm-скриптов yarn set-dev-conf и yarn set-build-conf.

На текущий момент, режим использования бандла работает только с CRA. Сторибук перестал работать в этом режиме после добавления одной оптимизации бандлинга, необходимой для работы tree shaking'a (см. ниже). Почти наверняка это можно починить.

Темизация

Библиотека поддерживает темизацию на основе SCSS переменных. Данные тем описываются файлами src/scss/themes/_*.scss. Эти файлы, помимо темизируемых значений CSS-свойств, могут содержать значения любых типов данных SCSS, используемые в SCSS-модулях компонентов. Всегда должен присутствовать файл дефолтной темы _default.scss. Остальные темы могут описывать только отличия от дефолтной (или любой другой) темы, ссылаясь на имя родительской темы в поле parent. В объектах (мапах) тем предусмотрен особый объект globals, предназначенный для описания глобальных переменных темы. На значения globals-переменных можно ссылаться из других переменных (определяемых в данной теме, или в её потомках):

$default: (
    globals: (
        color-text-primary: $gray-9,
        ...
    ),
    typography: (
        colors: (
            primary: _color-text-primary, // ссылка должна начинаться с символа _ 
            ...
        ),
        ...
    ),
    ...
);

\ Стили компонентов должны писаться так, как если бы описывали какую-то одну тему, например дефолтную. Для доступа к значениям, определяемым в файлах тем, SCSS-модули компонентов могут использовать функцию get определённую в файле src/scss/_themes_builder.scss (вручную импортировать этот файл не нужно). Для генерации стилей всех тем, SCSS-модули всех компонентов будут использоваться несколько раз подряд, столько, сколько генерируется тем, при этом функция get всякий раз будет возвращать значения текущей генерируемой темы. Все селекторы находящиеся на самом верхнем уровне SCSS-модуля (не вложенные в другие конструкции) будут автоматически конкатенироваться с классом текущей темы, вида .theme-magenta (не считая дефолтной темы; можно считать что доп. класс дефолтной темы является пустой строкой). Остальные селекторы (не находящиеся на самом верхнем уровне), останутся без изменений. При необходимости темизировать такие селекторы, можно воспользоваться переменной $curThemeClass из файла _themes_builder.scss, подобным образом:

@mixin icons($opacities) {
    @for $i from 1 through 3 {
        #{$curThemeClass}.icon#{nth($states, $i)} {
            opacity: nth(get(component opacities), $i);
        }
    }
}

\ Следует учитывать что значением $curThemeClass при генерации дефолтной темы, будет пустая строка. Т.е. код использующий данную переменную должен быть к этому готов. Автоматическую темизацию селекторов верхнего уровня можно отключать с помощью комментария // custom, размещённого внутри блока, следующего за селектором:

.selector { // custom
    ...
}

\ JavaScript компонента должен сам позаботиться о назначении класса темы DOM-элементам (название темы он может получить с помощью хука useTheme экспортируемого файлом src/components/Theme.js). В случае если вложенность селекторов в файле стилей повторяет вложенность DOM-элементов компонента, и используется автоматическая темизация селекторов, достаточно будет назначить класс темы только одному внешнему DOM-элементу, подобным образом (см. также компоненты Radio и Button):

const theme = useTheme();
return (
    <button 
        className={classNames(
            theme && css[`theme-${theme}`], 
            otherClass, 
            ...
        )}
    > 
        ... 
    </button>
);

\ Для задания темы компонентам, consumer'ам предлагается использовать компонент ThemeProvider из файла src/components/Theme.js, передающий вложенным в него компонентам библиотеки название темы через контекст:

<ThemeProvider theme="magenta">
    ...
    <div>
        ...
        <Button {...args} />
        ...
    </div>
    ...
</ThemeProvider>

\ Для использования одной лишь дефолтной темы, наличие выше по дереву компонента ThemeProvider необязательно.

Список включаемых в бандл тем задаётся массивом themes в корневом package.json.


Механизм темизации использует кастомный процессинг SCSS-файлов: генерируются темизированные версии SCSS для всех тем компонента как описано выше, далее они по отдельности рендерятся в CSS с помощью стандартного SASS-препроцессора, затем из полученных фрагментов CSS каждой темы удаляются декларации, дублирующие декларации соответствующих селекторов дефолтной темы, и наконец оставшийся CSS объединяется. Удаление избыточных деклараций позволяет заметно сократить размер бандла.

Для просмотра итогового CSS компонента, можно прописать его имя в массиве saveCssFilePatterns в файле src/build-utils/webpack-scss-loader.js. При работе сторибука или CRA, CSS-файл такого компонента будет сохраняться по соседству с SCSS файлом. Для временного отключения кастомного процессинга SCSS-модуля (например в отладочных
целях), можно в первой строке модуля разместить коммент // skipTheming.

Если библиотека будет собираться только с единственной дефолтной темой, кастомный процессинг SCSS не должен создавать бо́льшую вычислительную нагрузку чем стандартный. Если всё же потребуется его отключить, сделать это можно в файлах src/build-utils/webpackFinal.js, для сторибука/CRA, и rollup.config.js для бандла (в rollup.config.js нужно будет заменить use: ['scss-custom-loader'] на use: ['sass']). Компоненты импортирующие файл стилей src/scss/_core.scss не будут ломать сборку библиотеки после отключения кастомного процессинга, т.к. в этом файле определены переменная $curThemeClass и облегчённая версия функции get, обеспечивающие правильную генерацию дефолтной темы.

Бандлинг

Tree Shaking

Tree Shaking - механизм используемый вебпаком для удаления из бандла проекта неиспользуемого кода. Библиотека совместима с данным механизмом. Для обеспечения его работы в приложениях-consumer'ах, используются следующие средства:

  • бандл создаётся в формате ESM (ECMAScript modules), этим обеспечивается tree shaking JS кода;
  • стили инжектятся в JS бандла с помощью rollup-plugin-styles, умеющего делать их tree shaking совместимыми;
  • используется babel-plugin-pure-static-props для поддержки tree shaking'а функц. компонентов имеющих propTypes и defaultProps.

Проблема с tree shaking'ом функц. компонентов, имеющимх propTypes и defaultProps описана здесь и здесь.

Вообще говоря, если использовать только propTypes (без defaultProps), то проблемы не будет. Механизм перестаёт корректно работать при наличии двух и более присваиваний свойств объекту-функции компонента. babel-plugin-pure-static-props решает эту проблему оборачивая компонент внутри бандла в IIFE:

const Typography = /*#__PURE__*/function () {
    const Typography = function Typography(props) { ... };
    Typography.propTypes = { ... };
    Typography.defaultProps = { ... };
    return Typography;
}();

\ Именно эта манипуляция приводит к отказу сторибука работать с компонентами из бандла, однако поддержка библиотекой tree shaking'а видится более весомой.

Подобная проблема существует и у классовых компонентов, и решить её можно с помощью babel-plugin-no-side-effect-class-properties. defaultProps для функц. компонентов в будущем, вероятно станет deprecated (https://twitter.com/dan_abramov/status/1133878326358171650). В нашей библиотеке propTypes и defaultProps используются из-за требований сторибука. Если поддержка сторибука не нужна, но нужен tree shaking, вероятно, лучше не использовать defaultProps. Тогда можно будет отключить babel-plugin-pure-static-props.

Scoped CSS Classnames

Для уменьшения размера бандла, имена CSS классов заменяются в нём на короткие уникальные хэши. Для формированиия такого хэша используется имя SCSS файла компонента объединённое с исходным именем CSS класса. Функция формирующая хэш определена в файле rollup.config.js (generateScopedName). Может быть модифицирована: например, если компонентов в библиотеке станет много и потребуется увеличить уникальность хэшей.

Возможные ошибки

Иногда при установке пакетов может упасть ошибка.В этом случае рекомендуется переименовать файл .npmrc и запустить установку снова.

0.20.6

2 years ago

0.19.3

3 years ago

0.13.0

3 years ago

0.13.1

3 years ago

0.13.2

3 years ago

0.11.6

3 years ago

0.12.0

3 years ago

0.12.1

3 years ago

0.12.2

3 years ago

0.12.3

3 years ago

0.11.3

3 years ago

0.11.4

3 years ago

0.11.5

3 years ago

0.11.0

3 years ago

0.10.14

3 years ago

0.11.1

3 years ago

0.11.2

3 years ago

0.10.10

3 years ago

0.10.11

3 years ago

0.10.12

3 years ago

0.10.13

3 years ago

0.10.13-beta.0

3 years ago

0.10.13-beta.1

3 years ago

0.10.9

3 years ago

0.10.5

3 years ago

0.10.6

3 years ago

0.10.7

3 years ago

0.10.8

3 years ago

0.10.4

3 years ago

0.10.3

3 years ago

0.10.1

3 years ago

0.10.2

3 years ago

0.9.5

3 years ago

0.10.0

3 years ago

0.9.4

3 years ago

0.9.3

3 years ago

0.9.2

3 years ago

0.9.1

3 years ago

0.9.0

3 years ago

0.8.19

3 years ago

0.8.18

3 years ago

0.8.17

3 years ago

0.8.16

3 years ago

0.8.15

3 years ago

0.8.12

3 years ago

0.8.14

3 years ago

0.8.13

3 years ago

0.8.11

3 years ago

0.8.9

3 years ago

0.8.8

3 years ago

0.8.10

3 years ago

0.8.7

3 years ago

0.8.6

3 years ago

0.8.5

3 years ago

0.8.4

3 years ago

0.8.3

3 years ago

0.8.2

3 years ago

0.8.1

3 years ago

0.8.0

3 years ago

0.7.9

3 years ago

0.7.6

3 years ago

0.7.5

3 years ago

0.7.8

3 years ago

0.7.7

3 years ago

0.7.2

3 years ago

0.7.1

3 years ago

0.7.4

3 years ago

0.7.3

3 years ago

0.7.0

3 years ago

0.6.8

3 years ago

0.6.7

3 years ago

0.6.6

3 years ago

0.6.5

3 years ago

0.6.4

3 years ago

0.6.3

3 years ago

0.6.2

3 years ago

0.6.1

3 years ago