Storybook: 如何为所有Storybook iframe包含一次全局样式(scss)?

创建于 2019-04-01  ·  39评论  ·  资料来源: storybookjs/storybook

描述错误
我曾经尝试过对所有Storybook iframe合并全局样式(scss)的多种方法,但均未成功。 似乎没有明确的简洁方法可以做到这一点。

重现
尝试次数:


    • 在每个组件中导入全局样式。

    • 结果:应用了样式,但是,多个global.scss样式重复了{story#} x次。

    • 遵循以下指示进行自定义Webpack配置: https ://storybook.js.org/docs/configurations/custom-webpack-config/
    • 结果:看来这仅告诉Storybook读取scss,实际上并未设置适用于所有故事的全局文件
    • 一个地方建议为Storybook创建一个装饰器,然后以这种方式应用“全局” css。
    • 结果:不适用于我要执行的操作(多种样式,mixin,变量等),仅适用于较小的CSS更改
    • 在配置中.storybook require('../ libs / storybook / global-styles.scss'); 在loadStories函数中
    • 结果:一无所有
    • 尝试在Storybook index.ts中导入全局样式
    • 结果:一无所有
    • 尝试通过angular.json文件添加全局样式

      • 结果:一无所有

预期行为
我希望能够在一个地方导入Global(scss)文件,以便可以将其应用于每个Story的iframe。 可能有我不知道的配置设置吗?

系统:

  • 作业系统:MacOS
  • 设备:Macbook Pro 2015
  • 浏览器:Chrome
  • 框架:角度
  • 插件:-[以插件为中心,插件视口,插件信息]
  • 版本:[^ 5.0.1]

其他背景
我希望我缺少故事书中的某些配置,这会使解决起来很简单。

angular has workaround inactive question / support

最有用的评论

@omaracrystal这是我的做法:
.storybook/config.js文件中,添加带有正确内联的装入程序的导入:

import '!style-loader!css-loader!sass-loader!./scss-loader.scss';

然后在scss-loader.scss文件中添加/导入所需的所有样式:

$font-path: '../projects/lib/src/theming/fonts/OpenSans/';

<strong i="13">@import</strong> '../projects/lib/src/theming/reset.scss';
<strong i="14">@import</strong> '../projects/lib/src/theming/main.scss';

html {
  font-family: $font-name;
  font-size: $font-size--small;
}

只要您使用Angular应用程序中的组件即可使用@kroeder提出的解决方案,但对于库,您无法在angular.json文件中添加styles属性

所有39条评论

尝试将您的global.scss文件添加到angular.json

检查您的defaultProject(json中有一个defaultProject属性)并将其添加到样式列表中

"styles": [
              "projects/your-cli-project/src/lib/styles/your-styles.scss"
            ],

我这样做,效果很好。 那是您的选择吗?

嗨,大家好! 似乎最近在这个问题上没有发生太多事情。 如果仍有问题,意见或错误,请随时继续讨论。 不幸的是,我们没有时间解决所有问题。 我们随时欢迎捐款,因此,如果您想提供帮助,请向我们发送请求请求。 不活跃的问题将在30天后关闭。 谢谢!

@omaracrystal这是我的做法:
.storybook/config.js文件中,添加带有正确内联的装入程序的导入:

import '!style-loader!css-loader!sass-loader!./scss-loader.scss';

然后在scss-loader.scss文件中添加/导入所需的所有样式:

$font-path: '../projects/lib/src/theming/fonts/OpenSans/';

<strong i="13">@import</strong> '../projects/lib/src/theming/reset.scss';
<strong i="14">@import</strong> '../projects/lib/src/theming/main.scss';

html {
  font-family: $font-name;
  font-size: $font-size--small;
}

只要您使用Angular应用程序中的组件即可使用@kroeder提出的解决方案,但对于库,您无法在angular.json文件中添加styles属性

尝试将您的global.scss文件添加到angular.json

检查您的defaultProject(json中有一个defaultProject属性)并将其添加到样式列表中

"styles": [
              "projects/your-cli-project/src/lib/styles/your-styles.scss"
            ],

我这样做,效果很好。 那是您的选择吗?

我做了这件事,但是当我运行故事书时似乎并没有为我加载

嗨,大家好! 似乎最近在这个问题上没有发生太多事情。 如果仍有问题,意见或错误,请随时继续讨论。 不幸的是,我们没有时间解决所有问题。 我们随时欢迎捐款,因此,如果您想提供帮助,请向我们发送请求请求。 不活跃的问题将在30天后关闭。 谢谢!

嘿,又是我! 我将解决此问题,以帮助我们的维护人员专注于当前的开发路线图。 如果仍然提到上述问题,请打开一张新票并提及这张旧票。 干杯,感谢您使用Storybook!

@omaracrystal这是我的做法:
.storybook/config.js文件中,添加带有正确内联的装入程序的导入:

import '!style-loader!css-loader!sass-loader!./scss-loader.scss';

然后在scss-loader.scss文件中添加/导入所需的所有样式:

$font-path: '../projects/lib/src/theming/fonts/OpenSans/';

<strong i="14">@import</strong> '../projects/lib/src/theming/reset.scss';
<strong i="15">@import</strong> '../projects/lib/src/theming/main.scss';

html {
  font-family: $font-name;
  font-size: $font-size--small;
}

只要您使用Angular应用程序中的组件即可使用@kroeder提出的解决方案,但对于库,您无法在angular.json文件中添加styles属性

这对每个人有用吗? 没有在我身边工作:(

@ozanmanav您尝试将其导入.storybook/config.js吗?

PS:因为对我来说可以,但是我只导入.css文件而没有webpack-loader

使用Storybook v5.3的main.js文件结构似乎不再起作用

@garrettmaring您尝试使用.storybook/preview.js而不是.storybook/config.js吗?

@garrettmaring
我终于使用import '!style-loader!css-loader!./main.css'使它适用于.css文件。
最初,我尝试玩弄webpack配置,但是我删除了所有自定义规则,并像上面那样内联。 显然,npm安装装载程序。

@shilman是的,做到了👍一旦我看了一些文档,就很清楚了。 故事书的主要文档中可能还有一些空间供更清晰的文档使用。 我发现这篇文章很清楚。

@garrettmaring Mind提交了PR以帮助改善文档?

@garrettmaring
我终于使用import '!style-loader!css-loader!./main.css'使它适用于.css文件。
最初,我尝试玩弄webpack配置,但是我删除了所有自定义规则,并像上面那样内联。 显然,npm安装装载程序。

仅是我想出的一些FYI,这种方法在本地提供故事书时会产生疑惑,但对于build-storybook来说(从我的观察中来看)不起作用。

我的解决方案
<link rel="stylesheet" href="./your-global-styles.css" />到preview-head.html。 然后在your-global-styles.css目录中使用-s标志,将样式复制到Storybook的build目录中。 现在,iframe.html应该从同一目录中引用your-global-styles.css

唯一的问题是在本地运行时,浏览器控制台会说找不到localhost/your-global-styles.css但仍然可以正常工作。

如果有人有更好的方法来解决这个问题,或者知道合适的解决方案,请告诉我:)

我们使用以下方法在故事书中提供scss文件:

导入'!style-loader!css-loader!sass-loader!./ main.scss';

这对我们来说很好

@blemaire您在哪里使用该行?

@blemaire您在哪里使用该行?

@lopis只需在.storybook文件夹中创建preview.js并将该行放入其中

谢谢大家。 确认

  • 将scss文件添加到.storybook (或您希望放置的任何位置)中。
  • 创建.storybook/preview.js
  • import '!style-loader!css-loader!sass-loader!./styles.scss';preview.js目录
  • "css-loader"作为devDependency添加到package.json

为我们工作; 故事书将Angular 9库设为icw(因此无法选择将其添加到angular.json文件中)

在基于nextjs的设置中,将import "../styles/main.css"; (如在主应用程序中)的简单行正确地添加到.storybook/preview.js

如果您所有的路径都是相对../../src/main.scss那么上述解决方案就可以使用,但是我当前的项目使用的是SCSS global / alias。

我的Storybook的main.js webpack配置可以编译别名。 但是,当我尝试将global / alias SCSS导入到我的preview.js它无法解析路径。

不知道要去哪里。

import '!style-loader!css-loader!sass-loader!./scss-loader.scss';

我试过了,但是出错了。 我需要Storybook来了解我的全局CSS变量和Mixins。

ERR! import '!style-loader!css-loader!sass-loader!./scss-loader.scss';
ERR!        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERR! 
ERR! SyntaxError: Unexpected string

在基于nextjs的设置中,将import "../styles/main.css"; (如在主应用程序中)的简单行正确地添加到.storybook/preview.js

这个styles / main.css是否包含您的全局SCSS变量? 它们是否完全适用于Storybook? 我尝试了这个,但仍然得到SassError: Undefined variable: $my-variable-here

@omaracrystal这是我的做法:
.storybook/config.js文件中,添加带有正确内联的装入程序的导入:

import '!style-loader!css-loader!sass-loader!./scss-loader.scss';

然后在scss-loader.scss文件中添加/导入所需的所有样式:

$font-path: '../projects/lib/src/theming/fonts/OpenSans/';

<strong i="15">@import</strong> '../projects/lib/src/theming/reset.scss';
<strong i="16">@import</strong> '../projects/lib/src/theming/main.scss';

html {
  font-family: $font-name;
  font-size: $font-size--small;
}

只要您使用Angular应用程序中的组件即可使用@kroeder提出的解决方案,但对于库,您无法在angular.json文件中添加styles属性

这对每个人有用吗? 没有在我身边工作:(

不。 也没有帮助我。 我现在收到此错误:

ERR! import '!style-loader!css-loader!sass-loader!./scss-loader.scss';
ERR!        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERR! 
ERR! SyntaxError: Unexpected string

描述错误
我曾经尝试过对所有Storybook iframe合并全局样式(scss)的多种方法,但均未成功。 似乎没有明确的简洁方法可以做到这一点。

重现
尝试次数:


    • 在每个组件中导入全局样式。

    • 结果:应用了样式,但是,多个global.scss样式重复了{story#} x次。


    • 遵循以下指示进行自定义Webpack配置: https ://storybook.js.org/docs/configurations/custom-webpack-config/

    • 结果:看来这仅告诉Storybook读取scss,实际上并未设置适用于所有故事的全局文件


    • 一个地方建议为Storybook创建一个装饰器,然后以这种方式应用“全局” css。

    • 结果:不适用于我要执行的操作(多种样式,mixin,变量等),仅适用于较小的CSS更改


    • 在配置中.storybook require('../ libs / storybook / global-styles.scss'); 在loadStories函数中

    • 结果:一无所有


    • 尝试在Storybook index.ts中导入全局样式

    • 结果:一无所有

    • 尝试通过angular.json文件添加全局样式

      • 结果:一无所有

预期行为
我希望能够在一个地方导入Global(scss)文件,以便可以将其应用于每个Story的iframe。 可能有我不知道的配置设置吗?

系统:

  • 作业系统:MacOS
  • 设备:Macbook Pro 2015
  • 浏览器:Chrome
  • 框架:角度
  • 插件:-[以插件为中心,插件视口,插件信息]
  • 版本:[^ 5.0.1]

其他背景
我希望我缺少故事书中的某些配置,这会使解决起来很简单。

您解决了这个问题吗? 如果是这样,解决方案是什么? 谢谢!

@caseytrombley解决方案是将import '!style-loader!css-loader!sass-loader!./styles.scss';到您的Preview.js。

对于Create React App + Storybook,我将以下内容添加到config.js以将CSS重置应用到Storybook。

import '!style-loader!css-loader!../src/reset.css';

有人有适合postcss-scss的解决方案吗?

您可以阅读我写的博客,该实现SCSS常量

我已记录了一些缺陷,以解释当前的配置错误https://github.com/storybookjs/storybook/issues/11052和我作为解决方法撰写的博客。

希望这可以帮助!

对于具有main.js (即您在CreateReactApp项目中运行了npx -p @storybook/cli sb init ),只需添加preview.js作为同级,然后执行以下操作:

// .storybook/preview.js
require('!style-loader!css-loader!../src/css/tailwind-utility-classes.css')

如果它抱怨没有安装这些加载器之一(如果是CRA项目,则应该安装),只需手动安装它们(即yarn add style-loader css-loader )。

锁定线程,以便人们可以在赞成/弃用的解决方案失败时跳到最低处寻求解决方案?

@garrettmaring您尝试使用.storybook/preview.js而不是.storybook/config.js吗?

当我在同一目录中创建styles.css文件并将其与preview.js文件中的import './styles.css';导入时,我的故事书突然陷入了加载状态... :(

知道如何解决吗?

我将故事书与web组件.storybook文件夹中有preview.jsmain.js文件。

@dcts ,可能是因为您的./styles.css引用了Tailwind实用程序,使用了一些需要预处理的功能,或者以其他方式作为独立文件“损坏”。

我需要做三件事:

  1. 创建一个输入CSS文件。 对我来说,这是css/tailwind.css ,我在其中导入Tailwind设置所需的任何内容。
  2. 运行故事书时,请先构建该文件。 对我来说,这是一个PostCSS命令postcss css/tailwind.css -o css/index.css
  3. .storybook/preview.js (如果需要的话创建该文件)中添加import '../css/index.css

我正在使用Twin ,可以按预期使用此组件:

import tw, { styled } from 'twin.macro'

const StyledReactionButton = styled.button`
  ${tw`bg-blue-400 bg-opacity-25`}
`

我认为更好的解决方案是编辑Storybook Webpack配置以处理postcss步骤。

我将Vue.js与scss一起使用。 我的问题是,当在preview.js中导入全局scss时,我的chrome devtoll非常慢且无法使用。 有人遇到同样的问题吗? 还有其他选择吗? 我试图在每个故事中都不导入全局的scss。

上面的解决方案以某种方式起作用,但是此方法(来自官方文档)从整个项目中消除了该问题。

简而言之,我们需要扩展Webpack配置以设置scss加载器。

来自官方文档的示例代码

// .storybook/main.js

const path = require('path');

// Export a function. Accept the base config as the only param.
module.exports = {
  webpackFinal: async (config, { configType }) => {
    // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
    // You can change the configuration based on that.
    // 'PRODUCTION' is used when building the static version of storybook.

    // Make whatever fine-grained changes you need
    config.module.rules.push({
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../'),
    });

    // Return the altered config
    return config;
  },
};

用法

现在,您可以在.storybook/preview.js远处导入scss文件:

// .storybook/preview.js

import "../src/styles/main.scss";

// ...

...甚至在您的组件中:

<!-- src/components/MyComponent.vue -->

<template>
  ...
</template>

<script>
// ...
</script>

<style lang="scss">
<strong i="18">@import</strong> "../styles/components/components.my-component";
</style>

我遇到了一个问题,其中从preview.js导入一个相当大的SCSS项目会导致对项目中任何内容的任何更改造成5秒钟以上的重新编译时间。 将其转移到故事中可以使所有内容恢复到小于1s的重新编译时间。

我正在将Storybook与Gatsby和标准的scss预设一起使用。 将global.scss文件导入到preview.js ,将拾取样式,但是如果我在global.scss定义变量并将其用于组件中,则会触发以下错误:

ERROR in ./src/stories/button.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/stories/button.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable: "$black".

我怀疑global.scss文件加载为时已晚,但是我不知道如何正确配置它。 甚至可能是一个错误,因为建议将全局样式添加到preview.js

更新资料

这不是命令。 如果我在global.scss中编写以下内容。

body {
    background-color: black;
}

以及Button.scss中的以下内容:

body {
  background-color:green;
}

背景颜色实际上是绿色。 这意味着Buttons.scss会像它应该加载的那样在Global.scss之后加载,但是仍然没有选择变量。


Yeez,我今天学到很多东西。 主要问题是,sass变量仅在默认情况下在声明它们的文件中定义。 如果要跨文件使用变量,则必须使用sass-modules。 旧方法是使用@import ,但新的首选方法是@use。 我使用@use pathtomodule/global.scss启动每个像button.scss这样的模块。 在我的情况下,这会使preview.js的导入变得多余。

还有另一个收获。 当前仅dart sass支持@use 。 我安装了node-sass( npm i node-sass --save-dev )。 有一个名为dart-sassnpm i dart-sass --save-dev )的程序包,但是对于前面提到的预设而言,它不是正确的程序包。 箭s已成为普通ass 。 您可以简单地使用npm i sass --save-dev安装它。

@Piepongwong

我没有使用Gatsby,但是在Vue中,我解决了将所有mixin和变量导入放入一个名为_common.scss并将其导入这样的组件中的问题:

<style lang="scss">
<strong i="9">@import</strong> 'path/to/styles/_common.scss';
<strong i="10">@import</strong> 'path/to/styles/components/_components.component.scss';
</style>

通过这种方式,我始终可以确保我的mixins和变量存在,但是请注意,您需要正确地抽象所有组件和变量。 您可以查看inuitcss以获得最佳实践。

希望这可以帮助。

@omaracrystal这是我的做法:
.storybook/config.js文件中,添加带有正确内联的装入程序的导入:

import '!style-loader!css-loader!sass-loader!./scss-loader.scss';

然后在scss-loader.scss文件中添加/导入所需的所有样式:

$font-path: '../projects/lib/src/theming/fonts/OpenSans/';

<strong i="15">@import</strong> '../projects/lib/src/theming/reset.scss';
<strong i="16">@import</strong> '../projects/lib/src/theming/main.scss';

html {
  font-family: $font-name;
  font-size: $font-size--small;
}

只要您使用Angular应用程序中的组件即可使用@kroeder提出的解决方案,但对于库,您无法在angular.json文件中添加styles属性

这对每个人有用吗? 没有在我身边工作:(

不适合我:(我尝试了next.js和reactstrap,但是它没有从我的样式文件夹中加载app.scss:/

@omaracrystal这是我的做法:
.storybook/config.js文件中,添加带有正确内联的装入程序的导入:

import '!style-loader!css-loader!sass-loader!./scss-loader.scss';

然后在scss-loader.scss文件中添加/导入所需的所有样式:

$font-path: '../projects/lib/src/theming/fonts/OpenSans/';

<strong i="16">@import</strong> '../projects/lib/src/theming/reset.scss';
<strong i="17">@import</strong> '../projects/lib/src/theming/main.scss';

html {
  font-family: $font-name;
  font-size: $font-size--small;
}

只要您使用Angular应用程序中的组件即可使用@kroeder提出的解决方案,但对于库,您无法在angular.json文件中添加styles属性

这对每个人有用吗? 没有在我身边工作:(

不适合我:(我尝试了next.js和reactstrap,但是它没有从我的样式文件夹中加载app.scss:/

尝试@hayatbiralem方式-应该可以。

这对我在最新版本的故事书@storybook/[email protected]有用,希望这对某人有帮助!

// .storybook/main.js
const path = require('path');

module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)",
    "../app/frontend/components/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    '@storybook/preset-scss'
  ],
  webpackFinal: async (config) => {
    // this sets the default path for modules
    config.resolve.modules = [
      ...(config.resolve.modules || []),
      path.resolve(__dirname, "../app/frontend"),
    ];

    config.module.rules.map(rule => {
      if (rule.test instanceof RegExp && rule.test.toString() === '/\\.s[ca]ss$/') {
        rule.use.push({
          loader: require.resolve('sass-resources-loader'),
          options: {
            resources: [
              path.resolve(__dirname, '../app/frontend/styles/base/_variables.scss')
            ]
          }
        })
      }
      return rule
    })
    return config;
  },
}
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

shilman picture shilman  ·  3评论

purplecones picture purplecones  ·  3评论

tlrobinson picture tlrobinson  ·  3评论

ZigGreen picture ZigGreen  ·  3评论

sakulstra picture sakulstra  ·  3评论