NX - UI Library с Storybook и индивидуально экспортируемыми компонентами

Я изучаю Nx с помощью Angular (относительно новичок в обоих) и пытаюсь понять, как создать библиотеку компонентов, которая:

  • Может запускать Storybook и
  • Можно импортировать по одному компоненту за раз, вместо того, чтобы перетаскивать весь модуль / все компоненты в приложение, для которого требуется один компонент. (Чтобы избежать добавления ненужного кода / раздувания в мой комплект).

Итак, идеальная установка примерно такая:

repo
 |--apps
    |--normal-app (can import just card or button, without pulling in both)
 |--libs
    |--ui (lists individually exportable components, and has a servable Storybook)
       |--.storybook
       |--card
       |--button

Следуя как общему руководству по Nx, в котором показано, как создать общую библиотеку компонентов, так и руководству по настройке Storybook в Nx, я создал библиотеку пользовательского интерфейса и настроил схему Storybook (если это правильный способ сказать это) для этого каталога lib.

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

Я успешно создал библиотеку пользовательского интерфейса и два компонента в ней. Я успешно настроил Storybook в этой библиотеке. Затем я импортировалUIModule из index.ts файл (общедоступный API) в библиотеке пользовательского интерфейса и использовал один из двух компонентов в моем шаблоне.

Но затем, когда я создал приложение, которое импортировало библиотеку, производственная сборка содержала оба компонента, хотя я использовал один. Это имеет смысл, поскольку я импортируюUiModule. Однако это не идеально.

Я надеюсь создать настройку, которая позволяет размещать компоненты в библиотеке с настройкой Storybook, которую можно импортировать индивидуально.

Есть ли способ сделать это без радикального изменения настройки NX? На данный момент я изучил два основных варианта. Один из них - разбить все компоненты на их собственные библиотеки пользовательского интерфейса, импортировать их все в отдельное приложение, настроенное для Storybook, и импортировать их по отдельности в основное приложение. Вот так (попытка №1):

repo
 |--apps
    |--storybook-app (imports all)
    |--other-app (imports just button)
 |--libs
    |--button
    |--card

Однако это не идеально по нескольким причинам:

  • Он не группирует компоненты.
  • Он включает в себя гораздо больше шаблонов библиотеки.
  • Он не создает истории для каждого компонента автоматически.
  • Разработчики должны помнить о добавлении истории в сборник рассказов для каждого компонента.

В качестве второй попытки (№2) я попытался сгенерировать каждый из компонентов как отдельные библиотеки в общем каталоге:

repo
 |--apps
    |--storybook-app (imports all)
    |--other-app (imports just button)
 |--libs
    |--ui (just a directory; not a "project")
      |--button (module; has separate component dir beneath)
      |--card

У этого есть ряд собственных недостатков:

  • По-прежнему не могу создавать истории автоматически.
  • Непонятно, где должен быть мой сборник рассказов. Это автономное приложение, как на древовидной диаграмме выше? Это кажется не идиоматическим. Я пытался вставить это вui каталог, но поскольку это не "проект", я получаю Cannot find project 'ui' когда я пытаюсь сделать это с помощью расширения VSCode NX.
  • Мне нужно создать как библиотеку, так и компонент в библиотеке для каждого компонента пользовательского интерфейса. Это дополнительный шаблон, дополнительный код и дополнительная возможность для ошибок.
  • Мне кажется, что Storybook не должен быть приложением, поскольку он может обслуживаться обычным образом, но имеет свои собственные команды обслуживания.

Я мог бы создать одну из описанных выше версий (вероятно, №2), но я подозреваю, что есть лучшие практики для того, что кажется обычным вариантом использования. Похоже, что большая часть моего замешательства связана с внедрением зависимостей Angular. (В приложении React вы можете просто импортировать компонент, но в Angular каждый компонент принадлежит модулю, и его, в частности, тоже нужно внедрить. Разве это плохая практика - иметь модули для конкретных компонентов?)

Кто-нибудь знает об идиоматическом / оптимальном способе достижения этих идеальных характеристик (общая библиотека сборников рассказов с отдельными экспортированными компонентами или разделенные компоненты с автоматически созданными историями в NX)?

4 ответа

Решение

Я не нашел полностью удовлетворительного решения этой проблемы, но вот что я в итоге сделал. Это близко к пункту 2 выше:

  1. Создал libs/ui каталог (не проект)
  2. Создал сценарий генератора, который создает каждый компонент как отдельный модуль в этом каталоге и автоматически создает в нем основу истории.
  3. Создал component-liblib. (Вместо приложения, потому что Storybook имеет свои собственные отдельные команды запуска).
  4. Настройте там конфигурацию Storybook с помощью Nx CLI.
  5. Изменена конфигурация сборника рассказов, чтобы получить все .stories.ts файлы под libs/ui каталог.

Таким образом, component-libкаталог автоматически добавляет каждый новый компонент по мере его добавления, и мне не нужно беспокоиться о кучу шаблонов всякий раз, когда я добавляю компонент. Кроме того, каждый компонент может быть импортирован индивидуально, без перетаскивания пакета.

Я не буду делиться своим скриптом-генератором компонентов целиком, но это базовый JS-файл, который

  1. Запускает генератор библиотеки Nx для создания библиотеки в ui реж
  2. Запускает генератор компонентов Nx для создания компонента в этой библиотеке.
  3. Использует fs написать соответствующий .stories.ts файл в этой библиотеке.

Затем в моем component-lib каталог, я изменил последнюю строку в .storybook/config.jsтребовать все истории подui lib:

configure(require.context('../../ui', true, /\.stories\.tsx?$/), module);

Все это кажется немного взломанным, особенно скрипт генератора. Но работает!

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

Библиотека angular в nrwl/nx должна содержать хотя бы один модуль (исключения - это библиотеки данных), как и ваш обычный проект angular должен содержать app.module. Но это не значит, что вы не можете экспортировать несколько модулей в библиотеке. С несколькими модулями вы можете импортировать их независимо от вашей библиотеки.

пример

import { module1 } from '@mylib'
import { module2 } from '@mylib'

Каждый компонент может иметь свой собственный NgModule, который будет экспортироваться из индексного файла. Автономные компоненты также могут быть экспортированы таким же образом, используя их соответствующий файл ts.

      // index.ts

export * from './lib/components.module'
export * from './lib/footer/components1.module'
export * from './lib/social-media/component2.module'
export * from './lib/back-arrow/standalone-component1.component'

Вы можете найти решение в документе NX https://nx.dev/storybook/overview-angular .

Коротко пошагово:

  1. Установить пряжу https://yarnpkg.com/getting-started/install
  2. Установить плагин сборника рассказовyarn add --dev @nrwl/storybook
  3. Создание конфигурации сборника рассказовnx g @nrwl/angular:storybook-configuration project-name
  4. Бегатьnx run project-name:storybook

Создавать*stries.tsрядом с любым компонентом.

Не забудьте добавить ссылки на файлы историй в main.js и tsconfig.json

Другие вопросы по тегам