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 выше:
- Создал
libs/ui
каталог (не проект) - Создал сценарий генератора, который создает каждый компонент как отдельный модуль в этом каталоге и автоматически создает в нем основу истории.
- Создал
component-lib
lib. (Вместо приложения, потому что Storybook имеет свои собственные отдельные команды запуска). - Настройте там конфигурацию Storybook с помощью Nx CLI.
- Изменена конфигурация сборника рассказов, чтобы получить все
.stories.ts
файлы подlibs/ui
каталог.
Таким образом, component-lib
каталог автоматически добавляет каждый новый компонент по мере его добавления, и мне не нужно беспокоиться о кучу шаблонов всякий раз, когда я добавляю компонент. Кроме того, каждый компонент может быть импортирован индивидуально, без перетаскивания пакета.
Я не буду делиться своим скриптом-генератором компонентов целиком, но это базовый JS-файл, который
- Запускает генератор библиотеки Nx для создания библиотеки в
ui
реж - Запускает генератор компонентов Nx для создания компонента в этой библиотеке.
- Использует
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 .
Коротко пошагово:
- Установить пряжу https://yarnpkg.com/getting-started/install
- Установить плагин сборника рассказов
yarn add --dev @nrwl/storybook
- Создание конфигурации сборника рассказов
nx g @nrwl/angular:storybook-configuration project-name
- Бегать
nx run project-name:storybook
Создавать*stries.ts
рядом с любым компонентом.
Не забудьте добавить ссылки на файлы историй в main.js и tsconfig.json