Storybook: @storybook/angular: Expected 'styles' to be an array of strings

Created on 27 Aug 2019  路  31Comments  路  Source: storybookjs/storybook

Describe the bug

Components with SCSS or LESS (probably others too) styleUrls don鈥檛 load in Storybook. The following error message is printed to the console:

zone.js:703 Unhandled Promise rejection: Expected 'styles' to be an array of strings. ; Zone: <root> ; Task: setTimeout ; Value: Error: Expected 'styles' to be an array of strings.
    at assertArrayOfStrings (compiler.js:5668)
    at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata (compiler.js:21024)
    at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getEntryComponentMetadata (compiler.js:21670)
    at compiler.js:21318
    at Array.map (<anonymous>)
    at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNgModuleMetadata (compiler.js:21318)
    at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._loadModules (compiler.js:27376)
    at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents (compiler.js:27357)
    at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler.compileModuleAsync (compiler.js:27317)
    at CompilerImpl.push../node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:143) Error: Expected 'styles' to be an array of strings.
    at assertArrayOfStrings (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:12731:19)
    at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:28087:13)
    at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getEntryComponentMetadata (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:28733:28)
    at http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:28381:53
    at Array.map (<anonymous>)
    at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNgModuleMetadata (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:28381:18)
    at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._loadModules (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:34439:51)
    at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:34420:36)
    at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler.compileModuleAsync (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:34380:37)
    at CompilerImpl.push../node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.compileModuleAsync (http://localhost:6006/vendors~main.34d29019bd40f8e6720a.bundle.js:73681:31)

The referenced stylesheet seems to be loaded as a module, where it should actually be a string (see screenshot below).

To Reproduce
Steps to reproduce the behavior:

  1. ng new test-app
  2. npx -p @storybook/cli@next sb init
  3. In stories/Welcome.stories.ts, use AppComponent instead of Welcome as the component
  4. Launch Storybook.

Expected behavior

The components should successfully show.

Screenshots

image

Code snippets

N/A

System:

  System:
    OS: macOS 10.14.6
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
  Binaries:
    Node: 11.3.0 - ~/.nvm/versions/node/v11.3.0/bin/node
    Yarn: 1.12.3 - /usr/local/bin/yarn
    npm: 6.9.0 - ~/.nvm/versions/node/v11.3.0/bin/npm
  Browsers:
    Chrome: 76.0.3809.132
    Safari: 12.1.2
  npmPackages:
    @storybook/addon-actions: ^5.2.0-beta.40 => 5.2.0-beta.40
    @storybook/addon-links: ^5.2.0-beta.40 => 5.2.0-beta.40
    @storybook/addon-notes: ^5.2.0-beta.40 => 5.2.0-beta.40
    @storybook/addons: ^5.2.0-beta.40 => 5.2.0-beta.40
    @storybook/angular: ^5.2.0-beta.40 => 5.2.0-beta.40
  npmGlobalPackages:
    @storybook/cli: 5.2.0-beta.19
Angular CLI: 8.3.0
Node: 11.3.0
OS: darwin x64
Angular: 8.2.3
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.0
@angular-devkit/build-angular     0.803.0
@angular-devkit/build-optimizer   0.803.0
@angular-devkit/build-webpack     0.803.0
@angular-devkit/core              8.3.0
@angular-devkit/schematics        8.3.0
@angular/cli                      8.3.0
@ngtools/webpack                  8.3.0
@schematics/angular               8.3.0
@schematics/update                0.803.0
rxjs                              6.4.0
typescript                        3.5.3
webpack                           4.39.2

Additional context

This seems to be a reincarnation of https://github.com/storybookjs/storybook/issues/3593. The workarounds from this issue did not work for me.

angular bug high priority

Most helpful comment

@literalpie Storybook hooks into the configuration of Angular in order to provide a zero-configuration environment. While in theory this sounds amazing it actually is troublesome if Angular changes their way of handling webpack stuff. Also troublesome are webpack dependencies that are shared between Angular and Storybook (or possibly installed twice due to version mismatch)

Regarding the webpack stuff: I might have a possible improvement to future changes of Angular CLI but it's still just an idea.

Possible workaround

For running the latest Angular + Storybook version please try to npm i -D [email protected]. It works for me in my companies 60+ stories framework without any trouble. It's not a solution but hopefully a working workaround for most of you

What's going on?

The angular app itself seems to work with 3.1.0 (just an assumption) because it works just fine using 1.0.0. But Storybook for Angular only works if 1.0.0 is installed. It hasn't worked when I tried to manually install 2.0.0.

Still an assumption: @storybook/core and @storybook/angular are having compatibility issues and we haven't noticed. We'll try to figure out a way that is backwards compatible and brings back a zero-configuration environment.

So far so good, I hope the workaround is working for everyone who has trouble right now 馃

All 31 comments

This happens with Angular CLI 8.3.0. As a temp work around you can use 8.2.x

        "@angular-devkit/build-angular": "~0.802.0",
        "@angular/cli": "~8.2.0",

I think this depends on how builds are done using CLI 8.3. The mechanism has changed a bit.
I'm currently blocked on 8.2 because of this.

@shilman I recommend tagging this as a bug or feature request. A new angular project with scss will result in this error. I don't think it's a question. To reproduce:

  • install the latest angular CLI
  • ng new my-project
  • select scss
  • npx -p @storybook/cli sb init --type angular

I would expect the default installation to work. Instead a user would need to find this bug report and then downgrade their Angular version.

Same issue HERE 馃樋

Hi there, I can report that I'm experiencing the same problem.

The @angular/cli and @angular-devkit/build-angular downgrades suggested by @bufke work 馃憤

I've also had to create an empty default project of type application so that storybook can find the angular-cli webpack config - having a library project type as default doesn't seem to work.

Hey, I can reproduce the issue as well.
The default AppComponent is using both templateUrl and styleUrls. However the compiler is loading these data, before getting the error:

image

I do not know the behind-the-scene Angular compiler though, so I do not know if it is perfectly fine or if the issue may be related to this.

@builtbyjay I had the same issue as well, when the first project is a library, I got the same webpack config warning. I think the solution is to create a project named storybook inside your Angular workspace, but it would be nice to have a documentation on this behaviour.

I think the solution is to create a project named storybook

Does anyone have a work around that involves just editing angular.json instead of downgrading Angular CLI? I'd like to get the faster differential builds that 8.3 has. I already have a customized angular.json with a storybook project but it still suffers from this issue.

@bufke afaik, there is no way, if you want to build on the same workspace (and thus on the same NPM modules).

So...no way other then to downgrade angular CLI version?

I got it working in a library only workspace using the following in .storybook/webpack.config.js

module.exports = async ({ config, mode }) => {
    let scssLoader = config.module.rules.find(i => !!'a.scss'.match(i.test));
    scssLoader.use = [
        'to-string-loader',
        {
            loader: 'css-loader',
            options: {
                sourceMap: true
            }
        },
        {
            loader: 'sass-loader',
            options: {
                sourceMap: true
            }
        }
    ];
    let htmlLoader = config.module.rules.find(i => !!'a.html'.match(i.test));
    htmlLoader.loader = 'html-loader';

    return config;
};

To fix the angular-cli webpack config warning you need to add

"styles": [],
"scripts": [],
"outputPath": ""

to angular.json in the build options.

hope this will be fix soon

@Anthbs trying to use your configuration but getting

ERROR in ./src/styles/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/dist/cjs.js??ref--9-3!./src/styles/styles.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialised using an options object that does not match the API schema.
 - options has an unknown property 'includePaths'. These properties are valid:
   object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }

My options are just like yours tho:

{
            loader: 'sass-loader',
            options: {
                sourceMap: true
            }
        }

any idea?

@Anthbs trying to use your configuration but getting

ERROR in ./src/styles/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/dist/cjs.js??ref--9-3!./src/styles/styles.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialised using an options object that does not match the API schema.
 - options has an unknown property 'includePaths'. These properties are valid:
   object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }

My options are just like yours tho:

{
            loader: 'sass-loader',
            options: {
                sourceMap: true
            }
        }

any idea?

I think its cause your file is empty?
See: https://github.com/webpack-contrib/sass-loader/issues/756

Yes, saw this one as well. I'm not adding any rules myself but I see there are these two:

exclude: Array(2)
0: "C:\Code\Development\Applications\SimaBiz.Web\SimaProNgApp\src\styles\styles.scss"
1: "C:\Code\Development\Applications\SimaBiz.Web\Content\Bootstrap\css\bootstrap-modal.css"
length: 2
__proto__: Array(0)
test: /\.scss$|\.sass$/
use: Array(3)
0: {loader: "raw-loader"}
1: {loader: "postcss-loader", options: {鈥}
2: {loader: "sass-loader", options: {鈥}
length: 3
__proto__: Array(0)
__proto__: Object

and

include: Array(2)
0: "C:\Code\Development\Applications\SimaBiz.Web\SimaProNgApp\src\styles\styles.scss"
1: "C:\Code\Development\Applications\SimaBiz.Web\Content\Bootstrap\css\bootstrap-modal.css"
length: 2
__proto__: Array(0)
test: /\.scss$|\.sass$/
use: Array(4)
0: "style-loader"
1: "C:\Code\Development\Applications\SimaBiz.Web\SimaProNgApp\node_modules\@angular-devkit\build-angular\src\angular-cli-files\plugins\raw-css-loader.js"
2: {loader: "postcss-loader", options: {鈥}
3: {loader: "sass-loader", options: {鈥}
length: 4
__proto__: Array(0)
__proto__: Object

and yes they have incorrect options according to the error I'm getting

I see this is coming from my angular.json which is picked up by storybook. Can I tell storybook which build configuration to use?

module.exports = async ({ config, mode }) => {
let scssLoader = config.module.rules.find(i => !!'a.scss'.match(i.test));
scssLoader.use = [
'to-string-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
];
let htmlLoader = config.module.rules.find(i => !!'a.html'.match(i.test));
htmlLoader.loader = 'html-loader';

return config;

};

How did you make this work?
it just fails

@shilman Could you give an indication on when this could be fixed? It has been high priority for 23 days now. Having an indication on when it could be fixed could help us determine when to upgrade to the latest version.

@simondel I think @kroeder is better positioned to answer that.

I'm also curious if this can be fixed in a way that ensures it won't break again in the future. It's troubling that a CLI release without any breaking changes would cause problems like this. Does this project use unsupported/private functionality of Angular CLI?

@literalpie Storybook hooks into the configuration of Angular in order to provide a zero-configuration environment. While in theory this sounds amazing it actually is troublesome if Angular changes their way of handling webpack stuff. Also troublesome are webpack dependencies that are shared between Angular and Storybook (or possibly installed twice due to version mismatch)

Regarding the webpack stuff: I might have a possible improvement to future changes of Angular CLI but it's still just an idea.

Possible workaround

For running the latest Angular + Storybook version please try to npm i -D [email protected]. It works for me in my companies 60+ stories framework without any trouble. It's not a solution but hopefully a working workaround for most of you

What's going on?

The angular app itself seems to work with 3.1.0 (just an assumption) because it works just fine using 1.0.0. But Storybook for Angular only works if 1.0.0 is installed. It hasn't worked when I tried to manually install 2.0.0.

Still an assumption: @storybook/core and @storybook/angular are having compatibility issues and we haven't noticed. We'll try to figure out a way that is backwards compatible and brings back a zero-configuration environment.

So far so good, I hope the workaround is working for everyone who has trouble right now 馃

. We'll try to figure out a way that is backwards compatible and brings back a zero-configuration environment.

I think breaking changes must happen if it's necessary sir. Hope more good new from you and StorybookJS team.
p/s: Thank for your solution. It's seem working now. You're saving my life sir 鉂わ笍 鉂わ笍 鉂わ笍

@kroeder thanks!

If someone has the time to try this out with v9 BETA, please let us all know if it works too.

According to https://github.com/webpack-contrib/raw-loader/issues/79 this seems to be a general issue, not only a Storybook specific issue

I also found several other issues in other repositories. Although a lot of people saying "use 1.0.0 in order to fix this" I will first check if we can use the latest version or at least raw-loader 2.0.0

@kroeder thanks a lot for your effort, on Sundays too. We appreciate it.

My workaround was to patch angular2-template-loader to be compatible with the latest raw-loader.

You can achieve the same by installing patch-package, adding a postinstall script (as explained in patch-package documentation), and creating patches/angular2-template-loader+0.6.2.patch with this content:

diff --git a/node_modules/angular2-template-loader/index.js b/node_modules/angular2-template-loader/index.js
index 587cf75..f26754b 100644
--- a/node_modules/angular2-template-loader/index.js
+++ b/node_modules/angular2-template-loader/index.js
@@ -11,6 +11,6 @@ function replaceStringsWithRequires(string) {
     if (url.charAt(0) !== ".") {
       url = "./" + url;
     }
-    return "require('" + url + "')";
+    return "require('" + url + "').default";
   });
 }

@urish that's some nice trickery here. Gonna try that too. Thanks.

Mmmh, the @urish trick works.
However it breaks again on this issue https://github.com/storybookjs/storybook/issues/4796.
Edit: caused by another dependency importing React 15. Madness.

@urish thanks for sharing this! I contacted the owner of angular2-template-loader and want to discuss the future of this package.

@kroeder happy to help :-)

If you want the workaround to be backward compatible with the older raw-loader, I'd consider changing that line to:

    return "(require('" + url + "').default||require('" + url + "'))";

Ooh-la-la!! I just released https://github.com/storybookjs/storybook/releases/tag/v5.3.0-alpha.18 containing PR #8269 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

Good golly!! I just released https://github.com/storybookjs/storybook/releases/tag/v5.2.4 containing PR #8269 that references this issue. Upgrade today to try it out!

@shamin seems working on 5.2.4 ;) Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dnlsandiego picture dnlsandiego  路  3Comments

levithomason picture levithomason  路  3Comments

tirli picture tirli  路  3Comments

purplecones picture purplecones  路  3Comments

arunoda picture arunoda  路  3Comments