NX - UI 带有 Storybook 和单独导出组件的库

NX - UI Library with Storybook and individually exported components

我正在使用 Angular 探索 Nx(两者都比较陌生)并试图弄清楚如何生成一个组件库:

所以理想的设置是这样的:

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 in Nx,我生成了一个 UI 库,并设置了一个 Storybook该 lib 目录的示意图(如果这是正确的说法)。

我希望将我所有的共享组件放在一个库中,并设置 Storybook 为每个组件自动生成和提供故事——但随后能够将组件从该库中单独拉入其他应用程序 没有拉入整个笨重的UI库。

我成功构建了一个 UI 库和其中的两个组件。我在该库中成功设置了 Storybook。然后我从 index.ts 文件(public API)导入 UI 库中的 UIModule,并在我的模板中使用了两个组件之一。

但是当我构建导入库的应用程序时,生产构建包含两个组件,尽管我使用了一个。这是有道理的,因为我正在导入 UiModule。然而,这并不理想。

我希望创建一个允许在带有故事书设置的库中并置组件的设置,可以单独导入

有没有办法在不彻底改变 NX 设置的情况下做到这一点?到目前为止,我已经探索了两个主要选项。一种是将所有组件分解成它们自己的 UI 库,将它们全部导入到为 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

这有其自身的一些缺点:

我可以构建上述版本之一(可能是#2),但我怀疑对于看似常见的用例有最佳实践。看来我的大部分困惑源于 Angular 依赖注入。 (在 React 应用程序中,您可以只导入一个组件,但在 Angular 中,每个组件都属于一个模块,具体而言,还需要注入。拥有特定于组件的模块是一种不好的做法吗?)

有谁知道 idiomatic/best-practice 满足这些理想规范的方法(具有单独导出组件的共享故事书库,或在 NX 中具有自动生成故事的拆分组件)?

对于这个问题,我还没有找到一个完全令人满意的解决方案,但这是我最终所做的。它接近上面的#2:

  1. 创建了一个 libs/ui 目录(不是项目)
  2. 构建了一个生成器脚本,将每个组件创建为该目录中的独立模块,并在其中自动创建故事脚手架。
  3. 创建了一个 component-lib 库。 (而不是应用程序,因为 Storybook 有自己单独的 运行 命令)。
  4. 使用 Nx CLI 在其中设置 Storybook 配置。
  5. 更改了 Storybook 配置以获取 所有 .stories.ts 目录下的 libs/ui 文件。

这样,component-lib 目录会在添加每个新组件时自动添加它,我不必担心每次添加组件时都会出现一堆样板文件。此外,每个组件都可以单独导入,而无需拖入包中。

我不会分享我的整个组件生成器脚本,但它是一个基本的 JS 文件

  1. 运行 Nx 库生成器以在 ui 目录中生成一个库
  2. 运行 Nx 组件生成器以在该库中生成组件。
  3. 使用 fs 在该库中编写适当的 .stories.ts 文件。

然后,在我的 component-lib 目录中,我修改了 .storybook/config.js 中的最后一行,以要求 ui 库下的 all 个故事:

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

这一切都让人觉得有点老套,尤其是生成器脚本。但它有效!

您也可以使用您最初的方法并为您要提供的每个组件集(甚至只有一个组件)生成一个模块(不是库)。然后导出 index.ts

中的所有模块

nrwl/nx 中的 angular 库必须包含至少一个模块(数据库除外),就像您的正常 angular 项目必须包含 app.module。但这并不意味着您不能在整个库中导出多个模块。对于多个模块,您可以独立于您的库导入它们。

示例

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