Storybook: Como posso incluir estilos globais (scss) uma vez para todos os iframes do Storybook?

Criado em 1 abr. 2019  ·  39Comentários  ·  Fonte: storybookjs/storybook

Descreva o bug
Tenho tentado várias maneiras de incorporar estilos globais (scss) uma vez para todos os Iframes do Storybook e não tive sucesso. Não parece haver uma maneira clara e concisa de fazer isso.

Reproduzir
Tentativas:


    • Importe os estilos globais em cada componente.

    • Resultados: os estilos são aplicados, mas vários estilos global.scss são repetidos {story #} x vezes.

    • Um lugar recomenda criar um decorador para Storybook e aplicar o css "global" dessa forma.
    • Resultado: não funcionaria para o que estou tentando fazer (vários estilos, mixins, variáveis, etc.) Isso só funciona para pequenas alterações de CSS
    • Na configuração em .storybook require ('../ libs / storybook / global-styles.scss'); dentro da função loadStories
    • Resultado: nada
    • Tentei importar os estilos globais do Storybook index.ts
    • Resultado: nada
    • Tentei adicionar os estilos globais por meio do arquivo angular.json

      • Resultado: nada

Comportamento esperado
Eu esperaria poder importar arquivos globais (scss) em um lugar para que pudessem ser aplicados a cada iframe da história. Pode haver uma definição de configuração da qual não estou ciente?

Sistema:

  • SO: MacOS
  • Dispositivo: Macbook Pro 2015
  • Navegador: Chrome
  • Estrutura: Angular
  • Complementos: - [addon-centered, addon-viewport, addon-info]
  • Versão: [^ 5.0.1]

Contexto adicional
Espero que esteja faltando alguma configuração no livro de histórias que tornaria isso simples de resolver.

angular has workaround inactive question / support

Comentários muito úteis

Olá @omaracrystal, aqui está como eu fiz:
nos arquivos .storybook/config.js , adicione a importação com os carregadores corretos alinhados:

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

Em seguida, adicione / importe todos os estilos de que você precisa no arquivo 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;
}

A solução proposta por @kroeder funciona contanto que você use componentes de um aplicativo Angular, mas para bibliotecas, você não pode adicionar a propriedade styles no arquivo angular.json

Todos 39 comentários

Tente adicionar seu arquivo global.scss em angular.json

Verifique seu defaultProject (há uma propriedade defaultProject dentro do json) e adicione-o à lista de estilos

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

Eu faço assim e funciona muito bem. Isso é uma opção para você?

Olá a todos! Parece que não tem havido muito nesta edição ultimamente. Se ainda houver perguntas, comentários ou bugs, sinta-se à vontade para continuar a discussão. Infelizmente, não temos tempo para abordar todos os problemas. Estamos sempre abertos a contribuições, portanto, envie-nos uma solicitação de pull se quiser ajudar. Os problemas inativos serão fechados após 30 dias. Obrigado!

Olá @omaracrystal, aqui está como eu fiz:
nos arquivos .storybook/config.js , adicione a importação com os carregadores corretos alinhados:

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

Em seguida, adicione / importe todos os estilos de que você precisa no arquivo 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;
}

A solução proposta por @kroeder funciona contanto que você use componentes de um aplicativo Angular, mas para bibliotecas, você não pode adicionar a propriedade styles no arquivo angular.json

Tente adicionar seu arquivo global.scss em angular.json

Verifique seu defaultProject (há uma propriedade defaultProject dentro do json) e adicione-o à lista de estilos

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

Eu faço assim e funciona muito bem. Isso é uma opção para você?

Eu fiz exatamente isso, mas não parece carregar isso para mim quando executo o livro de histórias

Olá a todos! Parece que não tem havido muito nesta edição ultimamente. Se ainda houver perguntas, comentários ou bugs, sinta-se à vontade para continuar a discussão. Infelizmente, não temos tempo para abordar todos os problemas. Estamos sempre abertos a contribuições, portanto, envie-nos uma solicitação de pull se quiser ajudar. Os problemas inativos serão fechados após 30 dias. Obrigado!

Olá, sou eu de novo! Vou encerrar este problema para ajudar nossos mantenedores a se concentrarem no atual roteiro de desenvolvimento. Se o problema mencionado ainda é uma preocupação, abra um novo tíquete e mencione o antigo. Parabéns e obrigado por usar o Storybook!

Olá @omaracrystal, aqui está como eu fiz:
nos arquivos .storybook/config.js , adicione a importação com os carregadores corretos alinhados:

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

Em seguida, adicione / importe todos os estilos de que você precisa no arquivo 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;
}

A solução proposta por @kroeder funciona contanto que você use componentes de um aplicativo Angular, mas para bibliotecas, você não pode adicionar a propriedade styles no arquivo angular.json

Isso está funcionando para todos? Não funciona do meu lado :(

@ozanmanav você tentou importá-lo em .storybook/config.js ?

PS: porque para mim funciona, mas eu importo apenas .css arquivo sem webpack-loaders

Isso parece não funcionar mais usando a estrutura de arquivo main.js do Storybook v5.3

@garrettmaring você tentou com .storybook/preview.js vez de .storybook/config.js ?

@garrettmaring
Eu finalmente consegui fazê-lo funcionar para .css arquivos usando import '!style-loader!css-loader!./main.css' .
No início, tentei brincar com a configuração do webpack, mas removi todas as minhas regras personalizadas e as inininei como acima. Obviamente, o npm instala os carregadores.

@shilman sim, foi isso 👍 Ficou bem claro quando vi alguma documentação sobre isso. Pode haver algum espaço para documentos mais claros na documentação principal do Storybook. Achei este artigo muito claro.

@garrettmaring Se importa em enviar um PR para ajudar a melhorar os documentos?

@garrettmaring
Eu finalmente consegui fazê-lo funcionar para .css arquivos usando import '!style-loader!css-loader!./main.css' .
No início, tentei brincar com a configuração do webpack, mas removi todas as minhas regras personalizadas e as inininei como acima. Obviamente, o npm instala os carregadores.

Apenas alguns FYI que acabei de descobrir, essa abordagem faz maravilhas ao servir livro de histórias localmente, mas não funciona (pelo que vi) com livro de histórias de construção.

Minha solução
Adicione <link rel="stylesheet" href="./your-global-styles.css" /> ao preview-head.html. Em seguida, use o sinalizador -s no diretório de your-global-styles.css e copie os estilos para o diretório de construção do livro de histórias. Agora o iframe.html "deveria" estar referenciando your-global-styles.css do mesmo diretório.

O único problema com isso é quando executado localmente, o console do navegador dirá que não pode encontrar localhost/your-global-styles.css mas ainda funciona como planejado.

Se alguém tiver uma maneira melhor de abordar isso, ou souber de uma solução adequada, me avise :)

servimos arquivos scss no livro de histórias usando o seguinte:

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

Isso funciona bem para nós

@blemaire Onde você está usando essa linha?

@blemaire Onde você está usando essa linha?

@lopis apenas crie preview.js na pasta .storybook e coloque essa linha nela

Obrigado a todos. Confirmando que

  • adicionando o arquivo scss a .storybook (ou em qualquer lugar que você deseja colocá-lo).
  • Criando .storybook/preview.js
  • adicionando import '!style-loader!css-loader!sass-loader!./styles.scss'; ao preview.js dir
  • adicionando "css-loader" como uma devDependency a package.json

trabalha para nós; storybook icw uma biblioteca Angular 9 (portanto, nenhuma opção para adicioná-lo ao arquivo angular.json )

Na configuração baseada em nextjs, a linha simples de import "../styles/main.css"; (como no aplicativo principal) para .storybook/preview.js adiciona estilos corretamente.

As soluções acima funcionam se todos os seus caminhos forem relativos ../../src/main.scss mas meu projeto atual usa SCSS global / alias.

Minha configuração de main.js webpack para Storybook pode compilar o alias. Mas quando tento importar SCSS global / alias em meu preview.js , não consigo resolver os caminhos.

Não tenho certeza para onde ir.

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

Tentei fazer isso, mas obtive erro. Eu preciso do Storybook para saber sobre minhas variáveis ​​css globais e mixins.

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

Na configuração baseada em nextjs, a linha simples de import "../styles/main.css"; (como no aplicativo principal) para .storybook/preview.js adiciona estilos corretamente.

Este styles / main.css contém suas variáveis ​​SCSS globais? Eles são aplicados no Storybook? Eu tentei isso, mas ainda consigo SassError: Undefined variable: $my-variable-here

Olá @omaracrystal, aqui está como eu fiz:
nos arquivos .storybook/config.js , adicione a importação com os carregadores corretos alinhados:

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

Em seguida, adicione / importe todos os estilos de que você precisa no arquivo 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;
}

A solução proposta por @kroeder funciona contanto que você use componentes de um aplicativo Angular, mas para bibliotecas, você não pode adicionar a propriedade styles no arquivo angular.json

Isso está funcionando para todos? Não funciona do meu lado :(

Não. Também não me ajuda. Eu recebo este erro agora:

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

Descreva o bug
Tenho tentado várias maneiras de incorporar estilos globais (scss) uma vez para todos os Iframes do Storybook e não tive sucesso. Não parece haver uma maneira clara e concisa de fazer isso.

Reproduzir
Tentativas:


    • Importe os estilos globais em cada componente.

    • Resultados: os estilos são aplicados, mas vários estilos global.scss são repetidos {story #} x vezes.


    • Um lugar recomenda criar um decorador para Storybook e aplicar o css "global" dessa forma.

    • Resultado: não funcionaria para o que estou tentando fazer (vários estilos, mixins, variáveis, etc.) Isso só funciona para pequenas alterações de CSS


    • Na configuração em .storybook require ('../ libs / storybook / global-styles.scss'); dentro da função loadStories

    • Resultado: nada


    • Tentei importar os estilos globais do Storybook index.ts

    • Resultado: nada

    • Tentei adicionar os estilos globais por meio do arquivo angular.json

      • Resultado: nada

Comportamento esperado
Eu esperaria poder importar arquivos globais (scss) em um lugar para que pudessem ser aplicados a cada iframe da história. Pode haver uma definição de configuração da qual não estou ciente?

Sistema:

  • SO: MacOS
  • Dispositivo: Macbook Pro 2015
  • Navegador: Chrome
  • Estrutura: Angular
  • Complementos: - [addon-centered, addon-viewport, addon-info]
  • Versão: [^ 5.0.1]

Contexto adicional
Espero que esteja faltando alguma configuração no livro de histórias que tornaria isso simples de resolver.

Você já resolveu isso? Em caso afirmativo, qual foi a solução? Obrigado!

@caseytrombley A solução é adicionar import '!style-loader!css-loader!sass-loader!./styles.scss'; ao seu preview.js.

Para Create React App + Storybook, adicionei o seguinte a config.js para que meu CSS Reset fosse aplicado ao Storybook.

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

Alguém tem uma solução funcionando para postcss-scss?

Você pode ler o blog que escrevi que fala exatamente sobre a implementação de constantes SCSS para o seu livro de histórias por meio da configuração do webpack personalizado.

Há um defeito que registrei explicando o bug de configuração atual https://github.com/storybookjs/storybook/issues/11052 e o blog que escrevi como uma solução alternativa.

Espero que isto ajude!

Para instalações que têm main.js (ou seja, você executou npx -p @storybook/cli sb init em um projeto CreateReactApp), basta adicionar preview.js como irmão e fazer o seguinte:

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

Se reclamar que um desses carregadores não está instalado (eles deveriam estar se for um projeto CRA), apenas instale-os manualmente (ou seja, yarn add style-loader css-loader ).

Bloquear thread para que as pessoas possam ir até o fundo para encontrar uma solução quando a solução com votos positivos / reprovados falhar?

@garrettmaring você tentou com .storybook/preview.js vez de .storybook/config.js ?

Quando eu crio um arquivo styles.css dentro do mesmo diretório e o importo com import './styles.css'; dentro do meu arquivo preview.js , meu livro de histórias de repente fica parado em um estado de carregamento ... :(

Alguma ideia de como resolver isso?

Eu uso storybook com a configuração open-wc para webcomponents e tenho um preview.js e main.js dentro da minha pasta .storybook .

@dcts pode ser porque seu ./styles.css está fazendo referência aos utilitários do Tailwind, usando alguns recursos que precisam ser pré-processados ​​ou de alguma outra forma "quebrados" como um arquivo independente.

Eu precisava fazer três coisas:

  1. Crie um arquivo css de entrada. Para mim, é css/tailwind.css onde importo tudo o que é necessário para a configuração do Tailwind.
  2. Ao executar o livro de histórias, crie esse arquivo primeiro. Para mim, este foi um comando PostCSS postcss css/tailwind.css -o css/index.css
  3. Em .storybook/preview.js (crie esse arquivo se necessário) adicione import '../css/index.css

Estou usando o Twin e posso usar este componente conforme o esperado:

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

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

Acho que uma solução melhor seria editar a configuração do webpack do livro de histórias para lidar com a etapa postcss.

Estou usando o Vue.js com scss. Meu problema é que, ao importar scss global em preview.js, meu Chrome Devtolls fica muito lento e não pode ser usado. Alguém mais está tendo o mesmo problema? Alguma alternativa? Estou tentando não importar scss global em cada uma das minhas histórias.

As soluções acima funcionaram de uma maneira, mas este método __de documentos oficiais__ elimina o problema em todo o projeto.

Resumindo, precisamos estender a configuração do Webpack para definir os carregadores scss.

Amostra de código de documentos oficiais

// .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;
  },
};

Uso

Agora você pode importar arquivos scss como sempre em .storybook/preview.js :

// .storybook/preview.js

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

// ...

... e até mesmo em seus componentes:

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

<template>
  ...
</template>

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

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

Tive um problema em que importar um projeto SCSS considerável de preview.js estava causando tempos de recompilação de mais de 5 segundos em qualquer alteração em qualquer coisa no projeto. Transformar isso em uma história de alguma forma leva tudo de volta para <1s tempos de recompilação

Estou usando o Storybook com Gatsby e as predefinições scss padrão . Após importar o arquivo global.scss para preview.js os estilos são selecionados, mas se eu definir variáveis ​​em global.scss e usá-las em um componente, o seguinte erro é disparado:

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".

Estou suspeitando que o arquivo global.scss foi carregado tarde demais, mas não sei como configurá-lo corretamente. Talvez seja até um bug, porque adicionar estilos globais a preview.js é o método recomendado.

Atualizar

Não é a ordem. Se eu escrever o seguinte em global.scss.

body {
    background-color: black;
}

e o seguinte em Button.scss:

body {
  background-color:green;
}

A cor de fundo é na verdade verde. Isso significa que Buttons.scss é carregado após Global.scss como deveria, mas as variáveis ​​ainda não são selecionadas.

Solução
Sim, aprendi muito hoje. O principal problema é que as variáveis ​​sass são definidas apenas no arquivo em que são declaradas por padrão. Se você quiser usar variáveis ​​em arquivos, terá que usar sass-modules. A maneira antiga era usar @import , mas a nova forma preferida é @use. Eu começo todos os módulos como button.scss com @use pathtomodule/global.scss . No meu caso, isso torna a importação de preview.js redundante.

Havia outro problema. @use atualmente só é compatível com dart sass. Eu tinha o node-sass instalado ( npm i node-sass --save-dev ). Existe um pacote chamado dart-sass ( npm i dart-sass --save-dev ), mas esse não é o correto para os presets mencionados anteriormente. O atrevimento do dardo tornou-se o atrevimento normal . Você pode simplesmente instalá-lo com npm i sass --save-dev .

Olá @Piepongwong ,

Não estou usando Gatsby, mas no Vue resolvi esse problema colocando todas as importações de mixin e variáveis ​​em um arquivo chamado _common.scss e importando-o em componentes como este:

<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>

Desta forma, sempre tenho certeza de que meus mixins e variáveis ​​existem, mas esteja ciente de que você precisa abstrair todos os seus componentes e variáveis ​​corretamente. Você pode consultar inuitcss para obter as melhores práticas.

Espero que isto ajude.

Olá @omaracrystal, aqui está como eu fiz:
nos arquivos .storybook/config.js , adicione a importação com os carregadores corretos alinhados:

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

Em seguida, adicione / importe todos os estilos de que você precisa no arquivo 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;
}

A solução proposta por @kroeder funciona contanto que você use componentes de um aplicativo Angular, mas para bibliotecas, você não pode adicionar a propriedade styles no arquivo angular.json

Isso está funcionando para todos? Não funciona do meu lado :(

não para mim :( eu tentei com next.js e reatstrap, mas não carregou o app.scss da minha pasta de estilo: /

Olá @omaracrystal, aqui está como eu fiz:
nos arquivos .storybook/config.js , adicione a importação com os carregadores corretos alinhados:

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

Em seguida, adicione / importe todos os estilos de que você precisa no arquivo 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;
}

A solução proposta por @kroeder funciona contanto que você use componentes de um aplicativo Angular, mas para bibliotecas, você não pode adicionar a propriedade styles no arquivo angular.json

Isso está funcionando para todos? Não funciona do meu lado :(

não para mim :( eu tentei com next.js e reatstrap, mas não carregou o app.scss da minha pasta de estilo: /

Tente forma @hayatbiralem - deve funcionar.

Isso funcionou para mim na última versão do livro de histórias @storybook/[email protected] Espero que isso ajude alguém!

// .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;
  },
}
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

rpersaud picture rpersaud  ·  3Comentários

shilman picture shilman  ·  3Comentários

tirli picture tirli  ·  3Comentários

sakulstra picture sakulstra  ·  3Comentários

zvictor picture zvictor  ·  3Comentários