storybook Angular:全局样式入口点被捆绑到JS中,而不是单独的CSS文件中

8qgya5xd  于 2022-10-29  发布在  Angular
关注(0)|答案(8)|浏览(230)

描述Bug

老实说,这是其中的一件事,它似乎是如此明显的一个问题,我半期待你告诉我,我误解了😅
如您所知,在angular.json中,您在项目中提供了"styles": []-这些是全局入口点,当您运行ng build时,它们将通过webpack构建作为单独的CSS文件被吐出。
然而,在构建storybook的时候,尽管我可以看到它在幕后使用angular devkit的webpack配置样式,但它并没有遵守这一点,而是将全局CSS文件捆绑到JS包中。这绝对不是我想要的。

重现

我使用angular预设从头开始创建了一个全新的Nx工作区,并简单地添加了故事书,不需要其他任何东西:https://github.com/JamesHenry/storybook-test的最大值
若要重现,只需在运行nx buildnx build-storybook后比较相关的dist条目。

系统

System:
    OS: macOS 11.4
    CPU: (8) x64 Apple M1
  Binaries:
    Node: 14.17.0 - ~/.volta/tools/image/node/14.17.0/bin/node
    Yarn: 1.22.10 - ~/.volta/tools/image/yarn/1.22.10/bin/yarn
    npm: 7.12.1 - ~/.volta/tools/image/npm/7.12.1/bin/npm
  Browsers:
    Safari: 14.1.1
  npmPackages:
    @storybook/angular: ^6.2.7 => 6.3.0 
    @storybook/builder-webpack5: ^6.2.7 => 6.3.0 
    @storybook/manager-webpack5: ^6.3.0 => 6.3.0

其他上下文

如果你最后告诉我这是故事书中的预期行为,那么请提供一些指导,告诉我如何解决它。我有一个用例,我非常需要吐出单独的全局CSS文件(基于客户端的主题化)。

pkwftd7m

pkwftd7m1#

@shilman你已经删除了bug并添加了支持,那么这是否意味着你说这是预期的行为,而故事书是故意覆盖angular CLI的标准行为?

noj0wjuj

noj0wjuj2#

在我们同意这是一个bug之前,这需要一些讨论--现在对我来说这更像是一个问题。

niwlg2el

niwlg2el3#

我想帮你找一个解决方案,但我不太明白😁你是如何处理主题的变化?
如果你有几个主题,只有一个项目与角styles把所有的东西放在一个文件?
您没有父类,例如dark-theme

0s7z1bwu

0s7z1bwu4#

@ThibaudAV请允许我把这一切都分解一下,希望这会有所帮助:

Angular CLI构建部分的工作原理和工作方式

  • 我们称之为my-app的应用程序是由一家公司为几个客户开发的,这些客户有自己的应用程序主题,适合他们的品牌-徽标、色差等。因此,开发时需要确保并非所有可能的样式都包含在应用程序的每个部署中。
  • 因此,我们绝对不希望基于切换类的主题化方法,因为这意味着将所有可能的CSS发送到所有可能的部署。
  • Angular CLI在项目上有一个"styles"配置属性,允许您在Webpack编译中指定全局入口点。

下面是一个真实的配置的匿名示例:

  • 得益于Angular CLI的webpack配置,当您构建应用时,这些入口点最终会成为.css文件,它们不会被 Package 在JS包中。

这正是我们想要的。
apps/my-app/src/styles.scss -> styles.css
始终存在/必需的应用程序的全局基础样式。此文件由Angular CLI自动注入index.html。
libs/shared/client-configuration/src/lib/default/styles.scss -> styles-default.css
libs/shared/client-configuration/src/lib/foo/styles.scss -> styles-foo.css
libs/shared/client-configuration/src/lib/bar/styles.scss -> styles-bar.css
特定于主题的样式(颜色等),根据客户端/客户部署进行区分(“default”只是不需要任何定制的客户的默认主题)。这些文件 * 不会 * 自动注入HTML标记(多亏了"inject": false),我们将仅在适合特定客户端/客户部署的情况下提供。例如styles-bar.css将永远不会用于名为“foo”的客户。

与Storybook的相关性和问题

  • 当在Storybook中为这个和其他客户端主题应用程序开发组件时,我们自然希望能够不时地切换我们正在处理的客户端主题,以便我们可以看到我们工作的实际最终结果。
  • 因此,我创建了一个非常简单的Storybook工具栏插件(感谢你让这个插件如此容易实现),它是一个客户端/主题名称的下拉列表,在更改时最终会将<link>标记与所选主题的相应样式表交换。它工作得很好-到目前为止,一切都很好!
  • 然而,报告此问题的原因归结为Storybook的服务和构建-由于某种原因,Storybook在内部某处更改了Angular CLI的已解析webpack配置的行为,因为它不是从上述"styles"配置生成.css文件,而是将所有全局CSS源代码 Package 在JS包中。
  • 目前解决这个问题的唯一方法是首先构建完整的应用程序,然后服务或构建故事书,同时将其作为静态目录指向应用程序的dist。当然,这是非常低效的,并且随着应用程序的增长只会变得更糟!
  • 我还没有能够想到一个原因,为什么你会 * 需要 * 改变Angular CLI的逻辑在这方面,使故事书的工作,所以希望这是可以修改的东西。

希望现在一切都清楚了,如果不清楚请告诉我。如果我们可以调整Storybook Angular中的逻辑,使其停止覆盖Angular CLI的webpack配置,那么这个问题将得到解决。

yizd12fk

yizd12fk5#

托普!我更明白👍
对于另一个主题,我在这里稍微详细介绍一下棱角的逻辑

15246(备注)

确实如此,我不知道这是一个bug还是一个缺失的特性^^
Storybook使用了一些angular.json部分,由angular-cli代码的一些部分读取。但并不是只完成它需要完成的全局webpack配置。我认为这是一个计划外的情况🤷‍♂️

还有一个问题^^

为什么要在angular.json中添加同一个项目+配置中客户端的所有样式?
我知道在一个建筑里你可以做你客户所有风格
但是您必须在构建之后执行手动操作来添加正确的样式,对吗?
为什么不这样做:

  • angular.json中的多个项目(每个客户端配置一个)
  • 并使用fileReplacementsstyles来完成,默认情况下会覆盖这些配置

在这两种情况下,每个客户端都有一个构建版本,其中直接包含正确的样式文件
这并不能真正解决问题,除非你想开始一个故事书每个客户🤷‍♂️
抱歉,我没有完美的解决方案😞
有时间的话,我会去找故事书中缺少的东西来做这件事,但我担心的不仅仅是棱角部分;但故事书的行为却包有棱角🤷‍♂️

g9icjywg

g9icjywg6#

正如@JamesHenry完美描述的那样,我们公司有一个非常相似的用例。
我们是一个前端库,可以处理许多不同的主题(颜色、亮/暗模式、不同的对比度)。我们还需要在Angular应用程序中(所以在同一个应用程序中)使用一个主题切换器来展示这些主题。
angular.json中,我们指定这些主题应该被注入到应用程序中,我们通过一个主题切换器动态加载它们。但是Storybook一次加载所有的主题,每个主题覆盖前一个主题。
我们目前被这一点阻止,因为我们不想大幅改变我们的故事书应用程序,因为我们需要在Angular 应用程序的功能。

dced5bon

dced5bon7#

首先,感谢@JamesHenry创建这个并很好地解释了这个问题!我和我的团队也面临着类似的问题。
@ThibaudAV,在我们的项目中,延迟加载css解析不会在编译时发生。我们一次编译和部署所有资产。我们有一个ngnix路由器,它可以理解dns请求并将租户id作为请求头。然后在应用程序初始化时,我们通过阅读头解析租户id,并在运行时动态追加相应的css文件。

dw1jzc5e

dw1jzc5e8#

@蒂博AV
为什么不这样做:

  • angular.json中的多个项目(每个客户端配置一个)
  • 或多个配置并使用文件替换或样式来完成,则缺省情况下会覆盖这些配置

应用程序在功能上是相同的--多次构建它(这两个建议都暗示)即使只有两个客户端,也绝对不可取,而且没有太多的额外时间(然而,在我们的例子中,有两个以上,所以从时间的Angular 来看,它根本不能很好地伸缩)。我们应该构建一次,在我们的例子中,将哪个主题css文件与应用程序打包在一起是一个部署时的问题。
告诉大家最新情况,我最终建立了一个完全自定义的(因此我担心不可共享)Angular CLI builder/Nx executor),以便使用与storybook内部相同的angular-devkit webpack样式解析来编译样式文件。我在storybook运行之前运行该构建器,并将storybook指向编译后的css文件(作为--static-dir)。然后,我有一个自定义的故事书工具栏插件,允许我在故事书UI运行时切换到不同的主题文件。
再次道歉,我将无法分享任何这是根据一个咨询合同,所以请不要问😅
FWIW @ThibaudAV,即使angular-devkit中的类型信息不一致,我必须在现有的故事书逻辑上做的唯一重要的事情是将extractCss: true添加到您传递给getStylesConfig(...)的对象的buildOptions属性中。
我只是通过查看angular-devkit源代码来确定它应该为样式生成css文件还是js文件,从而发现了这一点。
希望这对你有帮助!

相关问题