9

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

  • 可以运行 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 教程,以及在 Nx 中设置 Storybook的指南,我生成了一个 UI 库,并设置了一个 Storybook 示意图(如果这是正确的说法)对于那个 lib 目录。

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

我成功地构建了一个 UI 库和其中的两个组件。我在该库中成功设置了 Storybook。然后,我UIModuleindex.tsUI 库中的文件(公共 API)导入,并在我的模板中使用了两个组件之一。

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

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

有没有办法在不彻底改变 NX 设置的情况下做到这一点?到目前为止,我已经探索了两个主要选项。一种是将所有组件分解为它们自己的 UI 库,将它们全部导入为 Storybook 设置的单独应用程序中,然后将它们单独导入到主应用程序中。像这样(尝试#1):

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

但是,这并不理想,原因如下:

  • 它不会对组件进行分组。
  • 它涉及更多的 lib 样板。
  • 它不会为每个组件自动生成故事。
  • 它要求开发人员记住为每个组件添加一个故事到故事书中。

作为第二次尝试(#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 扩展名时,我得到了一个。
  • 我必须为每个 UI 组件在一个库中生成一个库和一个组件。这是额外的样板和额外的代码以及额外的错误机会。
  • 在我看来,Storybook 不应该是一个应用程序,因为它可以正常服务,但有自己的服务命令。

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

有谁知道满足这些理想规范的惯用/最佳实践方式(与单个导出组件共享故事书库,或在 NX 中使用自动生成的故事拆分组件)?

4

2 回答 2

3

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

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

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

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

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

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

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

这一切都感觉有点hacky,尤其是生成器脚本。但它有效!

于 2020-04-01T16:14:56.443 回答
3

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

nrwl/nx 中的 Angular 库必须包含至少一个模块(数据库除外),就像您的普通 Angular 项目必须包含 app.module 一样。但这并不意味着您不能在整个 lib 中拥有多个模块 exportet。使用多个模块,您可以从您的库中独立导入它们。

例子

import { module1 } from '@mylib'
import { module2 } from '@mylib'
于 2020-04-15T10:11:23.933 回答