storybook: import markdown.md for addons "Cannot find module"

Issue details

I want to use markdown.md with addons but I can’t import it

Steps to reproduce

I got error import README1 from ‘…/src/framework/content/README1.md’; error TS2307: Cannot find module '../src/framework/content/README1.md'.

Please specify which version of Storybook and optionally any affected addons that you’re running

-storybook/addon-notes": “^3.3.11”, -storybook/angular": “^3.4.0-alpha.5”,

Screenshots / Screencast / Code Snippets (Optional)

35622048-80ae5544-0697-11e8-9d4f-fd547f5f17cc

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 3
  • Comments: 31 (10 by maintainers)

Most upvoted comments

Try putting this in your TS code:

declare module '*.md';

in CRA with typescript, can support markdown by editing react-app-dev.d.ts, add the declaration

declare module '*.md' {
  const value: string;
  export default value;
}

and in your component

import tReadme from '../readme.md';

We were having trouble with this exact same issue because we had "**/*.stories.*", in as an element in exclude in our tsconfig.json. We had originally placed it there to prevent stories files from being compiled into our bundles in our component library, but it was also causing this issue.

Removing it and separately adding *.stories* into our .npmignore fixed the issue while continuing to prevent the story files from getting bundled with our published package.

Hope this helps someone having the same issue!

For me the errors go away if i switch the extension from ‘stories.tsx’ to just ‘tsx’

edit: actually any other extension that ‘stories.tsx’ works, even ‘story.tsx’

For those using Angular CLI with Storybook 3.4.0 release - you may have to add the typedef changes suggested by @amorenew in the typings.d.ts file in the src directory. That’s what got this to work for me!

Thanks for saving me a night of headaches tracking this down.

Hi guys, I’m still getting errors here. I’m making a simple documentation using Angular Material components. Here’s my brief Storybook configuration:

ng-cli

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 7.2.1
Node: 11.9.0
OS: darwin x64
Angular: 7.2.0
... common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.12.0
@angular-devkit/build-angular     0.12.0
@angular-devkit/build-optimizer   0.12.0
@angular-devkit/build-webpack     0.12.0
@angular-devkit/core              7.2.1
@angular-devkit/schematics        7.2.1
@angular/animations               7.2.2
@angular/cdk                      7.3.0
@angular/cli                      7.2.1
@angular/material                 7.3.1
@ngtools/webpack                  7.2.0
@schematics/angular               7.2.1
@schematics/update                0.12.1
rxjs                              6.3.3
typescript                        3.2.2
webpack                           4.23.1

package.json

{
  "name": "test-storybook-angular",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "storybook": "start-storybook -p 9001 -c .storybook"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "7.2.2",
    "@angular/cdk": "7.3.0",
    "@angular/common": "7.2.0",
    "@angular/compiler": "7.2.0",
    "@angular/core": "7.2.0",
    "@angular/forms": "7.2.0",
    "@angular/material": "7.3.1",
    "@angular/platform-browser": "7.2.0",
    "@angular/platform-browser-dynamic": "7.2.0",
    "@angular/router": "7.2.0",
    "core-js": "2.5.4",
    "hammerjs": "^2.0.8",
    "rxjs": "6.3.3",
    "tslib": "1.9.0",
    "zone.js": "0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "0.12.0",
    "@angular/cli": "7.2.1",
    "@angular/compiler-cli": "7.2.0",
    "@angular/language-service": "7.2.0",
    "@babel/core": "7.2.2",
    "@storybook/addon-actions": "4.1.11",
    "@storybook/addon-knobs": "4.1.11",
    "@storybook/addon-links": "4.1.11",
    "@storybook/addon-notes": "4.1.11",
    "@storybook/addon-options": "4.1.11",
    "@storybook/addons": "4.1.11",
    "@storybook/angular": "4.1.11",
    "@types/angular": "1.6.53",
    "@types/jasmine": "2.8.8",
    "@types/jasminewd2": "2.0.3",
    "@types/node": "8.9.4",
    "@types/storybook__addon-notes": "4.0.1",
    "autoprefixer": "9.4.7",
    "babel-loader": "8.0.5",
    "codelyzer": "4.5.0",
    "css-loader": "2.1.0",
    "html-loader": "0.5.5",
    "jasmine-core": "2.99.1",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "3.1.1",
    "karma-chrome-launcher": "2.2.0",
    "karma-coverage-istanbul-reporter": "2.0.1",
    "karma-jasmine": "1.1.2",
    "karma-jasmine-html-reporter": "0.2.2",
    "markdown-loader": "5.0.0",
    "postcss-loader": "3.0.0",
    "protractor": "5.4.0",
    "sass-loader": "7.1.0",
    "ts-node": "7.0.0",
    "tslint": "5.11.0",
    "typescript": "3.2.2"
  }
}

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": ["node_modules/@types", "./typings.d.ts"],
    "lib": ["es2018", "dom"]
  }
}

typings.d.ts

declare module '*.md' {
  const content: string;
  export default content;
}

.storybook/addons.js

/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */

import '@storybook/addon-options/register';
import '@storybook/addon-knobs/register'
import '@storybook/addon-actions/register';
import '@storybook/addon-notes/register';

.storybook/config.js

/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved, import/extensions */
import { configure, addDecorator } from '@storybook/angular';
import { withOptions } from '@storybook/addon-options';
import { withKnobs } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

import '@angular/material/prebuilt-themes/deeppurple-amber.css';

addDecorator(
  withOptions({
    name: 'Storybook Angular Material',
    addonPanelInRight: true
  })
);

addDecorator(withKnobs);

addDecorator(withNotes);

// import all files ending in *.stories.ts
const req = require.context('../src/', true, /.stories.ts$/);
function loadStories() {
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);

src/app/material/mat-button.stories.ts

import { storiesOf, moduleMetadata } from '@storybook/angular';
import { MatButtonModule, MatIconModule } from '@angular/material';
import basicDoc from '../notes/mat-button-basic.md';

import { boolean, select, text } from '@storybook/addon-knobs';

import { withNotes } from '@storybook/addon-notes';

storiesOf('Button', module)
  .addDecorator(
    moduleMetadata({
      imports: [MatButtonModule, MatIconModule],
      providers: []
    })
  )
  .add('Basic', () => {
    return {
      template: `<button mat-raised-button [disabled]="disabled" [disableRipple]="disableRipple" [color]="color">
        <span>{{ label }}</span>
        <mat-icon
          *ngIf="!!icon"
          [attr.aria-label]="'Icon ' + icon"
          style="margin-left: 0.25em;">
            {{ icon }}
          </mat-icon>
      </button>`,
      props: {
        label: text('label', 'Basic'),
        disabled: boolean('disabled', false),
        disableRipple: boolean('disableRipple', false),
        color: select(
          'color',
          {
            none: '',
            primary: 'primary',
            accent: 'accent',
            warn: 'warn'
          },
          ''
        ),
        icon: select(
          'icon',
          {
            none: '',
            favorite: 'favorite',
            home: 'home',
            weekend: 'weekend',
            sort: 'sort',
            gesture: 'gesture'
          },
          ''
        )
      },
      notes: { markdown: basicDoc }
    };
  });

src/app/notes/mat-button-basic.md

# Button

Lorem ipsum dolor sit amet consectetur adipliscig elit...

Still getting error when compiling:

ERROR in /Users/ifthenelse/Sites/test/test-storybook-angular-material/src/app/material/mat-button.stories.ts
ERROR in /Users/ifthenelse/Sites/test/test-storybook-angular-material/src/app/material/mat-button.stories.ts(3,22):
TS2307: Cannot find module '../notes/mat-button-basic.md'.

Am I missing something?

@cwmrowe check my tsconfig.json I have

"typeRoots": [
      "node_modules/@types","./typings.d.ts"
    ],

and In typings.d.ts

declare module "*.md" {
    const value: string;
    export default value;
}

Full repo https://github.com/amorenew/travel-angular/blob/master/.storybook/webpack.config.js but I still on alpha.5, not 8

create global.d.ts at the root level and add the single line of code below.

declare module ‘*.md’;

putting declare module '*.md'; in index.ts not working

image

I followed angular docs and then I made typings.d.ts file in root and I added in it

declare module "*.md" {
    const value: string;
    export default value;
}

and in tsconfig.json at compilerOptions I added

"typeRoots": [
      "node_modules/@types","./typings.d.ts"
    ],

it works no error but I don’t think it returns value because withNotes addons doesn’t show text

aassa while without readme.md it show a value

image

@vasinkevych import * as readme from '../app/components/popup/README.md'; works

storiesOf('Component', module)
  .add('With Markdown', withNotes(readme)(() => ({
    component: HeadComponent,
    props: {
        text: '😀 😎 👍 💯'
    }
})));

not import README1 from '../src/framework/content/README1.md';

Thanks a lot all.

Can you please create a GitHub repo with minimal reproduction of your issue?

@cwmrowe did you solve your question? i use import * as docs from './button.md'; but still error TS2307: Cannot find module './button.md'

@amorenew, right

hi @amorenew, I’ve used your approach and added ‘marked’ module there is my story:

`import * as marked from ‘marked’; import * as readme from ‘…/app/components/popup/README.md’;

storiesOf(‘comp’, module) .addDecorator(withKnobs) .add( ‘withNotes’, withNotes({ text: marked(readme) })(() => ({ …story there })) ); `

👌 Will check tomorrow

@igor-dv mind taking a look?