21

I am trying to load a custom global style file, theme-default.scss in storybook. Although my components are loading in storybook but styles are not being applied.I followed this tutorial Storybook official docs of custom webpack config. (I am not very familiar to webpack though)

here is my .storybook/main.js file

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//import '!style-loader!css-loader!../src/stories/stories.scss'; // for scss
module.exports = {
  stories: ['../src/**/*.stories.ts'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-notes'],
  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;
  }
};

It is giving me following error

ERROR in ./src/app/app.component.scss
Module build failed (from ./node_modules/@angular-devkit/build-angular/node_modules/sass-loader/dist/cjs.js):
SassError: Invalid CSS after "v": expected 1 selector or at-rule, was 'var api = require("'
        on line 1 of D:\code2\mawani\mawani-angular-client\dpd-billing\src\app\app.component.scss
>> var api = require("!../../node_modules/style-loader/dist/runtime/injectStyle
   ^

 @ ./src/app/app.component.ts 45:18-49 45:61-92 45:104-135 45:147-178
 @ ./src/app/app.module.ts
 @ ./src/stories/containers/SearchBar.stories.ts
 @ ./src sync ^\.\/(?:(?:(?!\.)(?:(?:(?!(?:|[\\/])\.).)*?)[\\/])?(?!\.)(?=.)[^\\/]*?\.stories\.ts[\\/]?)$
 @ ./.storybook/generated-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/preview.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true ./src/theme-default.scss ./src/styles.scss

ERROR in ./src/app/modules/feature/public/page-not-found/page-not-found.component.scss
Module build failed (from ./node_modules/@angular-devkit/build-angular/node_modules/sass-loader/dist/cjs.js):
SassError: Invalid CSS after "v": expected 1 selector or at-rule, was 'var api = require("'
        on line 1 of D:\code2\mawani\mawani-angular-client\dpd-billing\src\app\modules\feature\public\page-not-found\page-not-found.component.scss
>> var api = require("!../../../../../../node_modules/style-loader/dist/runtime
   ^

 @ ./src/app/modules/feature/public/page-not-found/page-not-found.component.ts 12:18-60 12:72-114 12:126-168 12:180-222
 @ ./src/app/app.module.ts
 @ ./src/stories/containers/SearchBar.stories.ts
 @ ./src sync ^\.\/(?:(?:(?!\.)(?:(?:(?!(?:|[\\/])\.).)*?)[\\/])?(?!\.)(?=.)[^\\/]*?\.stories\.ts[\\/]?)$
 @ ./.storybook/generated-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/preview.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true ./src/theme-default.scss ./src/styles.scss

   ^

Then, I tried using inline loader syntax as mentioned in this comment Here is how my .storybook/preview.js looks

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

Inside _common.scss

@import '../src/theme-default.scss';
@import '../src/styles.scss';

Although it is not giving any error but still styles are not getting applied!

Here is my angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "xyz": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/xyz",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/theme-default.scss",
              "src/styles.scss"
            ]
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "xyz:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "xyz:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "xyz:build"
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "xyz:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "xyz:serve:production"
            }
          }
        }
      }
    }
  },
  "defaultProject": "xyz",
  "cli": {
    "analytics": ""
  }
}

I have also tried using this approach sass-resources-loader

I have done a lot of trial and error but could not figure out solution. Any help would be appreciated. Thanks!

ot954
  • 425
  • 5
  • 19
  • 1
    Please provide a codesandbox with minimal reproducible example of your code so it would be easier for people to help you. Thanks! – Aklesh Sakunia Oct 16 '21 at 10:00
  • I import them using inline exactly how you did. FOr the sake of trying, maybe you could import a simple independent "css" file with a simple CSS rule to see if that works. If it does, you will narrow down the problem on the loader or in your scss files – Tonio Oct 26 '21 at 22:19
  • var api = require("!../../node_modules/style-loader/dist/runtime/injectStyle Where this lines come from? your scss or from sass-loader nodemodule? Try to update or rollback to a previous version of this module. If you can provide a sandbox it will be much easier to debug. – Mohammad omar Nov 19 '21 at 09:01

2 Answers2

2

Since Angular 13 and onward, style imports must be added to your storybook-architekt in your angular.json, under your-project > (build-)storybook > options > styles. As importing the stylesheets in .storybook/main.js is no longer supported, you can remove it and instead add the stylesheets like shown below.

angular.json:

"your-project": {
  ...
  "storybook": {
      "builder": "@storybook/angular:start-storybook",
      "options": {
          ...
          "projectBuildConfig": "your-lib:build-storybook",
          "styles": [
              "path-to-the-stylesheet/styles.scss",
              "path-to-the-stylesheet/your-theme.scss"
          ],
          ...
      },
      ...
  
    },
    ...
}

You can find this information in the migration-guide of storybook.

hansi_reit
  • 368
  • 4
  • 16
0

For storybook versions below 6.4.*: If theme-default.scss is used in your app, then you can simply import it into your Angular app's global styles.scss file.