storybookjs / addon-styling-webpack

Successor to @storybook/addon-styling. Configure the styles of your webpack storybook with ease!
MIT License
27 stars 3 forks source link

[Bug] Error when using the plugin in combination with Angular component styleUrls #6

Closed mcaverick closed 1 year ago

mcaverick commented 1 year ago

Hi, I'm having a Storybook setup for a project in Nx, based on Angular. This library is containing components and global styling. I want to load color variables into one of my stories from the global styling files. I have setup the plugin to bundle my scss files and I'm able to import correctly my colors into my story.

The issue that I'm having however is that from the moment I configure a styleUrl in one of my components, the stories where I use a component are broken on this piece of Angular code:

if (meta.styles && meta.styles.length) {
    const styleValues = meta.encapsulation == ViewEncapsulation.Emulated ? compileStyles(meta.styles, CONTENT_ATTR, HOST_ATTR) : meta.styles;
    const styleNodes = styleValues.reduce((result, style) => {
      if (style.trim().length > 0) {
        result.push(constantPool.getConstLiteral(literal(style)));
      }
      return result;
    }, []);
    if (styleNodes.length > 0) {
      definitionMap.set('styles', literalArr(styleNodes));
    }
  }

When debugging is see that meta.styles equals this: [undefined], so the trim() will fail.

I'm using version 0.0.4 of @storybook/addon-styling-webpack.

This is how my main.js file is looking like:

const config = {
  stories: [
    '../**/*.stories.@(js|jsx|ts|tsx|mdx)'
  ],
  addons: ['@storybook/addon-essentials', {
    name: '@storybook/addon-styling-webpack',
    options: {
      rules: [{
        test: /\.scss$/,
        sideEffects: true,
        use: [
          require.resolve('style-loader'),
          {
            loader: require.resolve('css-loader'),
            options: {
              // Want to add more CSS Modules options? Read more here: https://github.com/webpack-contrib/css-loader#modules
              modules: {
                auto: true,
              },
              importLoaders: 2,
            },
          },
          require.resolve('resolve-url-loader'),
          {
            loader: require.resolve('sass-loader'),
            options: {
              // Want to add more Sass options? Read more here: https://webpack.js.org/loaders/sass-loader/#options
              implementation: require.resolve('sass'),
              sourceMap: true,
              sassOptions: {},
            },
          },
        ],
      }, ],
    }
  }],
  framework: {
    name: '@storybook/angular',
    options: {
    },
  },
};
ShaunEvening commented 1 year ago

Hey @mcaverick! @storybook/angular handles sass compilation for all angular styles as we use the same webpack config.

instead you should supply storybook with your global sass files through your angular.json https://storybook.js.org/docs/angular/configure/styling-and-css#styles-arent-being-applied-with-angular

mcaverick commented 1 year ago

@Integrayshaun Thanks for your reply. I think I was not precise enough in my explanation, sorry for that :).

The global style is not an issue and is working perfectly. What I exactly want to do is an import of my scss file into a story, like this:

import colors from '../styles/colors.scss';

colors.scss is containing exported variables (via :export)

and use the variables defined in it to show information about our different colors in a story.

However, when not setting up loaders in the plugin, I will always get:

ERROR in ./libs/shared/ui-design-system/src/styles/colors.scss?ngGlobalStyle 1:0
Module parse failed: Unexpected token (1:0)
File was processed with these loaders:
 * ./node_modules/resolve-url-loader/index.js
 * ./node_modules/@angular-devkit/build-angular/node_modules/sass-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
> .test-class {
|   background: #123456;
| }

So, somehow I need to define a loader, but at the same time it seems it's conflicting with what @storybook/angular is providing

ShaunEvening commented 1 year ago

Hey @mcaverick!

Right, so declaring your colors.scss in your angular.json configuration for storybook like in this stackoverflow answer will make sure your colors are available for your stories

mcaverick commented 1 year ago

hi @Integrayshaun

Have created a minimal repro case for my scenario. It contains a library my-ui-lib containing one story importing a scss file, which is also having the issue with the loaders.

test-storybook.zip

ShaunEvening commented 1 year ago

Hey @mcaverick Where are you finding information about this :export syntax? I can't find a ton of information on it.

The way that you're trying to import the styles looks like css modules but I can't find any information about Angular's support for it.

mcaverick commented 1 year ago

@Integrayshaun Basically I would like to build this concept: https://ben.robertson.is/frontend/color-swatches-storybook/. The ColorPalette of Storybook itself is a very nice component but I want to use the variables from the scss file to have only one source of truth for the color values

ShaunEvening commented 1 year ago

@mcaverick It looks like this is an old implementation of CSS Modules now known as "icss" mode.

This used to work for Angular projects however it no longer works without custom webpack settings which the Angular team recommends against https://github.com/angular/angular-cli/issues/19622

mcaverick commented 1 year ago

@Integrayshaun, thanks for your time looking into this.

I'm going for a solution where I put my variables into :root, after which they become accessible via JavaScript. I'm going to close this issue now as it is unrelated to this webpack addon.