Storybook: Angular 2 support

Created on 22 Jun 2016  ·  76Comments  ·  Source: storybookjs/storybook

I realize Angular 2 support was on the roadmap, and I'm pretty happy about that.
I wanted to share my related attempt at adapting the repo to that end, and didn't find a relevant thread here yet, so figured I might as well make one.
I hadn't managed to put a PoC together yet, but perhaps the Angular bits from my first commit here may help provide some inspiration. I realize it's forking an outdated version of this repo too, but I guess the concepts should still apply.

angular feature request help wanted

Most helpful comment

All 76 comments

We've made our core UI into a separate app. We are planning to use it for NG2 directly. See: https://github.com/kadirahq/storybook-ui

Cool. Looking forward to it! :)

Hey, @arunoda, so what's gonna be the approach for this one?
Do we want to create an ng2 specific storybook UI? Just curious to get a high level description of what you guys want to achieve and see if I can help

Angular 2 APIs have become stable with the release of RC5. There won't be any breaking changes now. So its a good time to start developing it. cc: @arunoda @mnmtanish

@arunoda: I'm inclined to think this is low on the roadmap, but so in the Angular case, in this split the idea would be for a theoretical ng2-storybook to let storybook-ui's React interface embed Angular components then? Has that been done?

@tycho01 You are right. It's kind a low on our priority.
I hope we could start with storybook-ui as the base. So, most of the addons could use that.
I am looking for help for someone to start working on it. If so, ping me on our Slack. Let's talk more.

@tycho01 , @arunoda you guys let me know if you start working on this.

@alterx: Pointers I got: storybook-react is separate from storybook-ui (runs inside an iframe); next step is to experiment to see if it could be replaced with an Angular version. Haven't started since my last attempt.

@tycho01, I checked the source and they have a completely separate react component that's basically a glorified iframe (https://github.com/storybooks/react-storybook/blob/master/src/client/manager/preview.js). We should be able to load the ng2 stories in that preview iframe.

react-storybook basically extends the Provider provided by storybook-ui, renders the aforementioned Preview and handles the story api. Then, a new instance of this provider is passed to the renderStorybookUI

import renderStorybookUI from '@kadira/storybook-ui';
import Provider from './provider';

const rootEl = document.getElementById('root');
renderStorybookUI(rootEl, new Provider());

After this, storybook-ui is in control, it builds the context (which includes the provider) and creates the app (using mantra-core's createApp). The provider (along with the other context props) are then injected to the ui module (https://github.com/storybooks/storybook-ui/blob/master/src/modules/ui/routes.js) that builds the preview using the renderPreview method defined when we created it in react-storybook

@arunoda , please let me know if I'm missing something

@amcdnl, that looks promising. Would you mind giving me a quick overview of how it works? (nothing fancy, just the big picture)

@amcdnl: thanks for linking, will check it out.
Edit: would you perhaps have any demo with it? I'm having trouble finding anything ready to run.

@MikeRyan52 ^^

@alterx Yep. You are 100% correct.
We also need to expose an API similar to React Storybook to create stories.

Possible imported from angular-storybook or similar.

@arunoda Do you have a url for the angular-storybook you mentioned, google is coming up dry.

@bcowgill afaik this doesn't exist yet, aside from @amcdnl's mentioned above

There is also this now - http://www.angularplayground.it/

So Storybook for Vue is going to be released soon 🎉

This adds a pretty good example of how a version for NG2 could be done.
Are there any brave souls watching this thread that would be willing to work together and make it happen?

I could take a look, do you have a repo url handy, @ndelangen ?

You're looking at it 😄

Storybook is a monorepo, we do have packages in here, published to npm separately.

Currently the vue app isn't in master yet, so here are 3 links to get to going:
https://github.com/storybooks/storybook/tree/release/3.2/app/vue
https://github.com/storybooks/storybook/blob/release/3.2/app/vue/src/client/preview/render.js
https://github.com/storybooks/storybook/blob/release/3.2/app/vue/src/server/config/webpack.config.js#L40

The render.js is where most of the Vue specific code is and on the server part there's a webpack config that's different.

It's OK to duplicate a lot of code at first! We will address that later. After we find what is really common and what isn't.

Just to get started, I'd say

  1. duplicate the entirety of app/vue to app/angular (we're talking about angular2 and up right?)
  2. tweak the webpack config, so it loads code some angular stuff and compiles.
  3. tweak render.js until something shows up, preferably the component you expected
  4. Try some addons
  5. Fix bugs
  6. Try what is now possible
  7. Write documentation, list what addons work
  8. Draft blogpost (I can do it, or add your account to our medium publication)
  9. Plan release
  10. Do alpha release
  11. Fix bugs
  12. Actual release, publish blogpost, tweet announcement
  13. Fix more bugs
  14. Try and add support for more addons

@shilman Is our release master chef 👨‍🍳

You can join us on slack to get a slightly faster chat experience then github 💬

https://storybooks-slackin.herokuapp.com

Perfect, @ndelangen!
I'll take a look at the code and join the Slack channel :D

@alterx Are you working on it now? I'm cloning the vue.js version now

@Jordan-Hall, there's already a PR in with a basic app working.
Please refer to #1474
I'm currently checking the add-ons to see which work out of the box. Would you mind joining the Slack channel so we can coordinate?

@alterx Sure. What's the channel https://storybooks-slackin.herokuapp.com appears to be down?

Whops, that's supposed to be it 🤔
Maybe @ndelangen can help with that.
For the time being, my PR covers the basic work (rendering a component, sending inputs). It's a bit different from what others did with vue and react but angular's way of doing stuff (NgModules) required some changes.

We're aiming to include Angular (2+) support as part of the 3.3 release.

Yeah heroku decided to shut down the app, so i just deployed to now.sh:
https://now-examples-slackin-nqnzoygycp.now.sh/

¯\_(ツ)_/¯

I don't get why people don't just use gitter for this kind of projects xD

Hey Guys just wanted to see if anyone is still actively working on this one?

Yup, I need to find some time today to submit some changes I have in my computer. Will probably do it during lunch 😄

Congrats on the merge!
Am I able to npm i -g @storybook/[email protected] and try this out or is a more manual setup required to have a play?

Would love to help test this out and contribute 👍

@shilman @alterx I was under the impression an alpha release had been made with the angular app?
Seems like that is not yet the case?

How soon could we do 1? @tomatosource here is willing to do some testing for us 🙇

@shilman mentioned that he'd like to release it "in the next few days" in the Angular slack channel so I guess it just hasn't been released :)

any updates? :-)

@Hypnosphi how do you actually install this? Unsupported Project type. (code: UNDETECTED)

@aaronksaunders Do you have a repo you can share with us to help us debug the CLI? Also if you want to do it by hand, there is an example app here with a full setup: https://github.com/storybooks/storybook/tree/release/3.3/examples/angular-cli

@alterx @tomatosource Sorry for the delay in releasing -- it's out now and would love your help testing!

what version of angular does it support?

@Insayt @LTiger14 @MTariqAziz @MathieuFouillet @Quramy @RemiAWE @VadimDez @aitboudad @bermanboris @cheapsteak @christian-bromann @diagramatics @dlcardozo @elad-morphisec @jbueza @johannesjo @jshthornton @justinlee0777 @mixn @npatta01 @qrrock @realappie @ruedap @tiny-dancer @tycho01 @priley86

Angular2+ support is in alpha (3.3.0-alpha.4 to be precise) thanks to a herculean effort from @alterx to get it working. Please help us test it out so we can get it release-ready!

Here's how to get started in just a minute:

cd my-angular-project
yarn add @storybook/cli@alpha
yarn getstorybook
yarn storybook
open http://localhost:6006

Here's what the examples/angular-cli storybook from our repo looks like, and you should see a stripped down version in your browser:

storybook

Please give it a spin and let us know here if you have any problems. You can also join us in the Storybook slack #angular channel for realtime help.

Many thanks for your help!

@shilman running yarn getstorybook throw the following error:

(function (exports, require, module, __filename, __dirname) { import updateNotifier from 'update-notifier';
                                                              ^^^^^^
SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)

changing the file node_modules/@storybook/cli/bin/index.js:1 would solve the issue:

require("babel-register")({
  ignore: /node_modules\/(?!@storybook)/
});

Weird, we actually use babel-register in cli@alpha

@aitboudad which node version do you use?

which node version do you use?

v8.9.0, It's not related to node version but it's about babel which ignore transpiling all files located in the node_modules

@shilman the second issue I have got is

odule build failed: Error: Typescript emitted no output for node_modules/@storybook/angular/dist/client/preview/angular/app.token.ts.

solved by setting transpileOnly to true in /node_modules/@storybook/angular/dist/server/config/webpack.config.js

{
  test: /\.ts?$/,
  use: [
    {
      loader: 'ts-loader',
      options: {
        transpileOnly: true
      }
    },
    { loader: 'angular2-template-loader' }
  ]
}

Missing feature:

Passing a custom NgModule:
Right now there is not way to pass a custom NgModule which make the current implementation very limited.

it's about babel which ignore transpiling all files located in the node_modules

Oh I see, will fix. I wonder how it used to work before

@aitboudad Thanks so much for debugging this! @Hypnosphi fixed the CLI issue and I just released it. Will try to get the angular fixes out soon!

https://github.com/storybooks/storybook/releases/tag/v3.3.0-alpha.4

@aitboudad, we're aware of that missing feature and we're trying to make up for that. The issue with custom NgModules is that, with our current implementation, we build our modules programatically and provide them. I have some changes in my local to allow passing providers and schemas but right now we can't just allow to pass custom modules as a module could potentially contain multiple components.

What's your exact use case? Maybe we can figure something out.

Also, using transpile only will leave you without type checking. We need to look into this before making this change.

@alterx What's your exact use case?

What if my component require some external modules like material or whatever to work, how we could handle it with the current approach?

In that case it should suffice with providers, imports and schemas (in case you need, idk, custom elements). The issue with letting a custom module in is that we can't control the amount of components that an user can submit and it could potentially break. Storybook is about developing and testing component as isolated units. This works a bit different in React and Vue but for angular we need to make some assumptions and limit the scope.

I'm working on something that should allow you to pass providers and schemas, with imports and declarations, it's a bit more complex. This kind of feedback is perfect, we wanted to get something out that could be tested and see what people need.

@aitboudad I tried to replicate your issue with a freshly created @angular/cli app and getstorybook but everything works as expected. Could you provide some more details about your setup? Angular version? TypeScript version?
I won't not be able to test it right away, tho.
screen shot 2017-11-22 at 10 27 33 am

@alterx just tried again and it seems to be working fine with the new alpha version, thanks!

Oh, perfect!
And rest assured, we have plans to support some way to provide imports, providers and so on to the module we create. We just need to figure it out :)

Just tried to run storybook/examples/angular-cli with the following package versions:

  "dependencies": {
    "@angular/animations": "4.3.5",
    "@angular/common": "4.3.5",
    "@angular/compiler": "4.3.5",
    "@angular/core": "4.3.5",
    "@angular/forms": "4.3.5",
    "@angular/http": "4.3.5",
    "@angular/platform-browser": "4.3.5",
    "@angular/platform-browser-dynamic": "4.3.5",
    "@angular/router": "4.3.5",
    "core-js": "2.4.1",
    "rxjs": "5.4.3",
    "zone.js": "0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "1.3.2",
    "@angular/compiler-cli": "4.3.5",
    "@angular/language-service": "4.3.5",
    "@storybook/addon-actions": "3.3.0-alpha.4",
    "@storybook/addon-links": "3.3.0-alpha.4",
    "@storybook/addon-notes": "3.3.0-alpha.4",
    "@storybook/addon-knobs": "3.3.0-alpha.4",
    "@storybook/addons": "3.3.0-alpha.4",
    "@storybook/angular": "3.3.0-alpha.4",
    "@types/jasmine": "2.5.53",
    "@types/node": "6.0.87",
    "codelyzer": "3.1.2",
    "jasmine-core": "2.5.2",
    "jasmine-spec-reporter": "3.2.0",
    "karma": "1.4.1",
    "karma-chrome-launcher": "2.0.0",
    "karma-cli": "1.0.1",
    "karma-coverage-istanbul-reporter": "0.2.3",
    "karma-jasmine": "1.1.0",
    "karma-jasmine-html-reporter": "0.2.2",
    "karma-trx-reporter": "0.2.9",
    "protractor": "5.2.0",
    "ts-node": "3.2.0",
    "tslint": "5.6.0",
    "typescript": "2.4.0"
  }

It crashes in browser console after navigate to _Addon Knobs_ components with the error while trying to get component.__annotations__[0]:

helpers.js:32 Uncaught TypeError: Cannot read property '0' of undefined
    at getComponentMetadata (helpers.js:32)
    at prepareComponent (helpers.js:140)
    at index.js:33
    at withKnobs (index.js:48)
    at client_api.js:109
    at initModule (helpers.ts:87)
    at helpers.ts:167
    at later (helpers.ts:27)
    at ZoneDelegate.invokeTask (zone.js:424)
    at Zone.runTask (zone.js:191)

@ToniaDemchuk Thanks so much for testing it out. How did you set it up on your machine? Can you share a repro? Many thanks!

Hey guys, super pumped on how easy this was to add. Few issues.

I had to add "@storybook/addon-notes": "3.3.0-alpha.4", to package.json as well.

Is there a way for it to respect my local typescript paths? They're defined in tsconfig.
repo: https://github.com/scttcper/ngx-color
I get Cannot find module 'ngx-color/helpers'. because its not picking them up.

@shilman The example you can find here https://github.com/ToniaDemchuk/storybook/tree/angular-4.3.5-sample
Setup commands:

npm i
npm i -g @storybook/cli
npm run storybook

Open localhost:9009 in browser and navigate to _Addon Knobs > Simple_ in menu

This worked:
image

This didn't:
image

Error in console:
image

@neo, I've tried to reproduce, but for me everything is working fine. Can you share more context? Maybe you have a repo?

@shilman , @alterx , Regarding the problem with angular v4.3.5 (@ToniaDemchuk ), I've researched the issue (I am not familiar with angular much, so... ) In the knobs addon, there is code that relies on fact that a component object has a annotations array on it. This array is set by angular/core package in the new version. But in the previous version (in this case v4.3.5) they used a reflect-metadata package (here is the diff where it was removed). I don't really know what to do with it.

Yeah, this change definitely has an impact in how we get the metadata. Will
look into it once I have some free time. Probably sometime over the next
week

On Sat, Dec 9, 2017, 11:41 AM Igor notifications@github.com wrote:

@shilman https://github.com/shilman , @alterx
https://github.com/alterx , Regarding the problem with angular v4.3.5 (
@ToniaDemchuk https://github.com/toniademchuk ), I've researched the
issue (I am not familiar with angular much, so... ) In the knobs addon,
there is code that relies on fact that a component object has a
annotations array on it. This array is set by angular/core package in the
new version. But in the previous version (in this case v4.3.5) they used a
reflect-metadata package (here is the diff
https://github.com/angular/angular/commit/cac130eff9b9cb608f2308ae40c42c9cd1850c4d#diff-635fe23be5795132e3385c8f4899dc3aR58
where it was removed). I don't really know what to do with it.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/storybooks/storybook/issues/269#issuecomment-350492916,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABhRmCjzdKQq2NNVYU7UTc-NVmvd8a9Tks5s-sZEgaJpZM4I70nl
.

@aitboudad, here's the PR to support custom module metadata.
So far I've added examples for Pipes and Services. I need to test Directives, Schemas, etc but they should be working too.

Let me know what you think

@ToniaDemchuk, would you mind checking again with new changes?

I just released 3.3.0-alpha.6 containing a bunch of Angular changes from @alterx @igor-dv @ralzinov

https://github.com/storybooks/storybook/releases/tag/v3.3.0-alpha.6

The relevant Angular changes include:

  • Added type annotation to helpers, added ts declaration files for angu… #2459
  • Adding extra metadata to module/components #2526
  • Fix ng component prop output override #2456
  • [WIP] Angular versions support #2467
  • Angular Add custom pipes support #2518

Please try upgrading to this version in your projects, and let us know if you run into any issues. I'm hoping this will be the last RC release, and we can do a proper 3.3 release by tomorrow!

@alterx that's exactly what I'm looking for, thanks!

it would be nice if we can provide the template content instead of component:

storiesOf('Welcome', module).add('to Storybook', () => ({
  moduleMetadata: { imports: [FormModule] },
  template: '<dynamic-forms [form]="form"></dynamic-forms>',
  props: {
    form: [{ key: name }]
  },
}));

@shilman for 3.3.0-alpha.6 looks good to me, the only issue I noticed is the addons are not included in the package like @storybook/angular, solved by

yarn add @storybook/addon-actions@alpha @storybook/addon-links@alpha @storybook/addon-notes@alpha

@igor-dv, Thanks for response. Now it's working fine.

@shilman, Some changes broke the angular-cli example, now NameComponent and ServiceComponent are not compiling due to typings:

ERROR in ./src/stories/index.ts
(200,19): error TS2345: Argument of type '() => { component: typeof NameComponent; props: { field: string; }; moduleMetadata: { imports: an...' is not assignable to parameter of type 'IGetStory'.
  Type '{ component: typeof NameComponent; props: { field: string; }; moduleMetadata: { imports: any[]; s...' is not assignable to type '{ props?: { [p: string]: any; }; moduleMetadata?: { [p: string]: NgModuleMetadata; }; component: ...'.
    Types of property 'moduleMetadata' are incompatible.
      Type '{ imports: any[]; schemas: any[]; declarations: (typeof CustomPipePipe)[]; providers: any[]; }' is not assignable to type '{ [p: string]: NgModuleMetadata; }'.
        Property 'imports' is incompatible with index signature.
          Type 'any[]' is not assignable to type 'NgModuleMetadata'.

I suppose that the moduleMetadata?: { [p: string]: NgModuleMetadata; } in the IGetStory should be as moduleMetadata?: NgModuleMetadata. After casting module metadata in examples to any everything works as expected.

I have also faced some problems with scss loaders for angular, similar to the issue @neo described above.
I solved the issue with the following webpack config rule:

    storybookBaseConfig.module.rules.push({
      test: /\.scss$/,
      loaders: ["to-string-loader", "css-loader", "sass-loader"],
      include: path.resolve(__dirname, '../')
    });

It looks like the angular does not work with style-loader and you need to use to-string-loader instead.
It would be nice to provide documentation and(or) example how to use components with scss stylesheets.

@ToniaDemchuk Yes you right issue with moduleMetadata?: { [p: string]: NgModuleMetadata; }. Actually i fixed that already here with moduleMetadata?: Partial<NgModuleMetadata>;

I published @ralzinov 's change at 3.3.0-rc.0 which is under the NPM tag rc instead of alpha.

@ToniaDemchuk please try it out and let us know if that fixes it for you.

Thanks everybody for your patience and hard work to help us get this out!

Still have the error with scss loader and angular storybook v3.3.3 with @ralzinov changes:

node_modules/@storybook/: grep -r "moduleMetadata?: Partial"
angular/index.d.ts: moduleMetadata?: Partial<NgModuleMetadata>;

npm run storybook
https://gist.github.com/karlos1337/18e4538b37128818ec3e4b507b3b3a3c

Thanks.

@karlos1337 , take a look at this issue - #2616.

Released in 3.3! 🎉

Closing this issue, and if you're having problems with storybook for angular, please file a separate issue. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

purplecones picture purplecones  ·  3Comments

dnlsandiego picture dnlsandiego  ·  3Comments

shilman picture shilman  ·  3Comments

miljan-aleksic picture miljan-aleksic  ·  3Comments

levithomason picture levithomason  ·  3Comments