Storybook: Official svelte typescript support

Created on 13 Oct 2020  ·  6Comments  ·  Source: storybookjs/storybook

As Svelte does now officially support the typescript language,
I decided to do the migration by following the linked official guide.

Unfortunately, this creates a crash issue on storybook launch (npm run storybook):

ERROR in ./src/components/Copy.svelte
Module build failed (from ./node_modules/svelte-loader/index.js):
Error: ParseError: Unexpected token (4:20)
2:   import { createEventDispatcher } from 'svelte';
3: 
4:   export let content: string;
                       ^
5:   export let showContent: boolean = true;
6:   export let title: string = 'Copy content';
    at /home/sullivan/p/gitlab.com/nexylan/svelty/node_modules/svelte-loader/index.js:181:12
 @ ./src/components/Copy.stories.js 65:0-33 69:13-17 73:15-19 98:15-19
 @ ./src/components sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.js)$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./node_modules/@storybook/addon-a11y/dist/a11yRunner.js-generated-other-entry.js ./node_modules/@storybook/addon-a11y/dist/a11yHighlight.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined

It looks like Storybook is not going to interpret typescript as it should.

Maybe I have to change some configuration for Storybook, but I can't found anything about this on the documentation and the issues.

Does Storybook support Svelte with Typescript?

You may test the issue by cloning this branch: https://gitlab.com/nexylan/svelty/-/merge_requests/67

svelte has workaround question / support typescript

Most helpful comment

@soullivaneuh this seemed to work for me.


// .storybook/main.js

module.exports = {
  webpackFinal: async  (config) => {
    const svelteLoader = config.module.rules.find(
      (r) => r.loader && r.loader.includes("svelte-loader"),
    )
    svelteLoader.options.preprocess = require("svelte-preprocess")({})
    return config
  },
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
}

All 6 comments

I was able to reproduce with a blank installation:

  1. Setup a new svelte project and convert it to typescript following the blog post:
npx degit sveltejs/template svelte-typescript-app
cd svelte-typescript-app
node scripts/setupTypeScript.js
  1. Install storybook following the official guide:
npx -p @storybook/cli sb init --type svelte
  1. Edit one story component to add some typescript:
<script lang="ts">
  import './button.css';
  import { createEventDispatcher } from 'svelte';
  /**
   * Is this the principal call to action on the page?
   */
  export let primary: boolean = false;

  /**
   * What background color to use
   */
  export let backgroundColor;
  /**
   * How large should the button be?
   */
  export let size = 'medium';
  /**
   * Button contents
   */
  export let label = '';

  let mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';

  let style = backgroundColor ? `background-color: ${backgroundColor}` : '';

  const dispatch = createEventDispatcher();

  /**
   * Optional click handler
   */
  function onClick(event) {
    dispatch('click', event);
  }
</script>

<button
  type="button"
  class={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
  {style}
  on:click={onClick}>
  {label}
</button>

And run npm run storybook: Badaboum.

+1. Can also replicate. Guess will need svelte preprocessor to translate to javascript first.

@soullivaneuh this seemed to work for me.


// .storybook/main.js

module.exports = {
  webpackFinal: async  (config) => {
    const svelteLoader = config.module.rules.find(
      (r) => r.loader && r.loader.includes("svelte-loader"),
    )
    svelteLoader.options.preprocess = require("svelte-preprocess")({})
    return config
  },
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
}

@ritchieanesco I took the webpackFinal part of your example and this works for me too, thanks!

I suppose adding the svelte-preprocess to the storybook configuration as default would solve many issue for svelte integration.

@ritchieanesco Hmm... this is working to launch the storybook but not for the tests:

 FAIL  src/components/Copy.test.js
  ● Test suite failed to run

    ParseError: Unexpected token

      at error (node_modules/svelte/src/compiler/utils/error.ts:25:16)
      at Parser$1.error (node_modules/svelte/src/compiler/parse/index.ts:100:3)
      at Parser$1.acorn_error (node_modules/svelte/src/compiler/parse/index.ts:93:8)
      at Object.read_script [as read] (node_modules/svelte/src/compiler/parse/read/script.ts:49:10)
      at tag (node_modules/svelte/src/compiler/parse/state/tag.ts:203:27)
      at new Parser$1 (node_modules/svelte/src/compiler/parse/index.ts:52:12)
      at parse (node_modules/svelte/src/compiler/parse/index.ts:215:17)
      at Object.compile (node_modules/svelte/src/compiler/compile/index.ts:78:14)
      at Object.process (node_modules/jest-transform-svelte/index.js:26:26)
      at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:463:35)

 PASS  src/storybook.test.js
  ● Console

    console.warn
      Unexpected error: Unexpected token (4:20)
      2:   import { createEventDispatcher } from 'svelte';
      3: 
      4:   export let content: string;
                             ^
      5:   export let showContent: boolean = true;
      6:   export let title: string = 'Copy content';

      at Object.warn (node_modules/@storybook/client-logger/dist/index.js:53:73)
      at node_modules/@storybook/core/dist/client/preview/loadCsf.js:149:34
          at Array.forEach (<anonymous>)
      at node_modules/@storybook/core/dist/client/preview/loadCsf.js:142:20
          at Array.forEach (<anonymous>)
      at node_modules/@storybook/core/dist/client/preview/loadCsf.js:141:12
      at ConfigApi.configure (node_modules/@storybook/client-api/dist/config_api.js:26:7)
      at node_modules/@storybook/core/dist/client/preview/loadCsf.js:326:17

Content of storybook.test.js:

import initStoryshots from '@storybook/addon-storyshots';

initStoryshots();

Content of Copy.test.js

import { render } from '@testing-library/svelte';
import Copy from './Copy.svelte';

test('Copy ', async () => {
  const { container } = await render(Copy, {
    props: {
      content: 'test-copy',
    },
  });
  expect(container.innerHTML.includes('test-copy')).toBe(true);
});

Note: The Copy.test.js is not related to storybook, but we have the same message as a warning from the storybook test file.

@soullivaneuh check out svelte jester and how it uses transforms to run svelte preprocessor

Was this page helpful?
0 / 5 - 0 ratings