Storybook:如何导入单个故事的样式

eme*_*his 6 sass webpack vuejs2 webpacker storybook

我在用着@storybook/vue": "^6.5.10"<style>我的组件由每个 .vue 文件底部的块设置样式。还有一些由 Rails webpacker 编译的全局 CSS (Sass) 文件。

为了重现我的故事中的全局 CSS 文件,我编写了装饰器(下面的示例)来重新创建各种 CSS 上下文。问题是我在一个装饰器中加载的 CSS 正在应用于我的其他组件/故事,我不明白为什么!

我的简化装饰器:

// THESE  STYLES ARE SHOWING UP IN STORIES THAT DO NOT USE THIS DECORATOR!
import '!style-loader!css-loader!sass-loader!../../app/javascript/styles/site.sass';

const sitePackDecorator = (story) => {     

    // other irrelevant stuff
        
    return {
      components: { story },
      template: '<story />'
    }
  }
;

export {sitePackDecorator}
Run Code Online (Sandbox Code Playgroud)

然后在我的故事文件中,我将其应用在组件级别,如下所示:

import MyComponent from '../app/javascript/src/site/components/assets/MyComponent'
import { sitePackDecorator } from './utilities/sitePackDecorator';

export default {
  title: 'My Component',
  component: MyComponent,
  parameters: {
    layout: 'fullscreen'
  },
  decorators: [sitePackDecorator]
};
const Template = (args, { argTypes }) => ({
    components: { MyComponent },
    props: Object.keys(argTypes),
    template: '<MyComponent v-bind="$props" />',
  })
Run Code Online (Sandbox Code Playgroud)

这是我的 webpack / webpacker 的 Rails 配置:

const { environment } = require('@rails/webpacker')
const { VueLoaderPlugin } = require('vue-loader')
const vue = require('./loaders/vue')
const sass = require('./loaders/sass')
const pug = require('./loaders/pug')
const customConfig = require('./alias')
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin())
environment.loaders.prepend('sass', sass)
environment.loaders.prepend('vue', vue)
environment.loaders.prepend('pug', pug)
environment.config.merge(customConfig)
environment.plugins.prepend("CleanWebpackPlugin", new CleanWebpackPlugin());

module.exports = environment
Run Code Online (Sandbox Code Playgroud)

...并且 main.js 引用这个 Rails 配置,如下所示:

const custom = require('../config/webpack/development.js');

module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions"
  ],
  "framework": "@storybook/vue",
  webpackFinal: async (config) => {
    return { ...config, module: { ...config.module, rules: custom.module.rules } };
  },
}
Run Code Online (Sandbox Code Playgroud)

注意:我跑了yarn storybook --debug-webpack,我看到: info => Using implicit CSS loaders。我不确定这意味着什么,但听起来可能相关。

我尝试过但不起作用的事情

  1. 将其移至import !style-loader!...故事文件中
  2. 不添加任何有问题的装饰器。即使未使用,样式仍然会加载!
  3. 将 向下移动import !style-loader!...到装饰器的箭头函数中。这会导致错误,因为import必须位于顶层。
  4. 更改为import '.../site.sass'
  5. 更改为命名导入 ( import styles from '.../site.sass'),然后调用use()导入的对象。

eme*_*his 3

这是老套的“解决方案”。我不推荐这个,但这是我目前最好的:

import sitePackCss from '!!raw-loader!sass-loader!../path/to/styles/site.sass';

const sitePackDecorator = (story) => {
          
    return {
      components: { story },
      template: `
      <div>
        <component is="style" type="text/css">${sitePackCss}</component>
        <story />
      </div>`
    }
  }
;

export {sitePackDecorator}
Run Code Online (Sandbox Code Playgroud)

这会将已编译 CSS 的完整内容转储到<style>单个故事的内联标记中。它并不漂亮,但它确实可以防止这些风格“泄漏”到其他故事中。