Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript and Preprocessors support #4

Closed
engineforce opened this issue Mar 10, 2021 · 22 comments · Fixed by benbender/addon-svelte-csf#1
Closed

TypeScript and Preprocessors support #4

engineforce opened this issue Mar 10, 2021 · 22 comments · Fixed by benbender/addon-svelte-csf#1
Assignees
Labels
bug Something isn't working

Comments

@engineforce
Copy link

Describe the bug

Trying to use TypeScript in the stories.svelte caused error: ParseError: Unexpected token

<script lang="ts">
  import type { IRoute } from './IRoute';

  const ROUTES: IRoute[] = [
    {
      url: '/',
      title: 'Home',
    },
   ...
  ]

</script>

Expected behavior

TypeScript should work using svelte preprocessor: https://svelte.dev/docs#svelte_preprocess

Screenshots and/or logs

WARNING in ./src/modules/presentational/components/nav-bar2/NavBar2.stories.svelte
Module build failed (from ./node_modules/@storybook/addon-svelte-csf/dist/parser/svelte-stories-loader.js):
ParseError: Unexpected token
    at error (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:16752:20)
    at Parser$1.error (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:16828:10)
    at Parser$1.acorn_error (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:16822:15)
    at Object.read_script [as read] (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:7501:17)
    at tag (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:15887:34)
    at new Parser$1 (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:16787:22)
    at parse$3 (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:16919:21)
    at Object.compile (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/svelte/compiler.js:29918:18)
    at extractStories (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/@storybook/addon-svelte-csf/dist/parser/extract-stories.js:49:32)
    at Object.transformSvelteStories (/Users/pli/my/git/engineforce/super-core/clients/boson/node_modules/@storybook/addon-svelte-csf/dist/parser/svelte-stories-loader.js:64:52)
 @ \.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx|svelte))$ (./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx|svelte))$) ./modules/presentational/components/nav-bar2/NavBar2.stories.svelte
 @ ./.storybook/generated-stories-entry.js

Environment

  • OS: MacOS Catalina 10.15.7
  • Node.js version: v12.13.1
  • NPM version: 6.12.1
  • svelte@3.35.0
  • @storybook/svelte@6.1.21
  • @storybook/addon-svelte-csf@1.0.0
@engineforce engineforce added the bug Something isn't working label Mar 10, 2021
@j3rem1e
Copy link
Contributor

j3rem1e commented Mar 10, 2021

I didn't think TypeScript/Preprocessor supports is important for stories, but I'll try to add it soon 😄

It will reuse the configuration of storybook, inside main.js in svelteOptions.preprocessor

@j3rem1e j3rem1e changed the title [Bug] TypeScript and Preprocessors support Mar 10, 2021
@j3rem1e j3rem1e self-assigned this Mar 10, 2021
@mpeg
Copy link

mpeg commented Mar 21, 2021

A problem with the lack of typescript support is that it also won't automatically detect props/events/slots/etc on typescript components, not just that the stories themselves can't be written in TS

I think it would be a great addition to this addon

@Nick-Mazuk
Copy link

I second mpeg's observation. As soon as you add a single TypeScript definition, props/slots etc. aren't automatically detected.

@j3rem1e
Copy link
Contributor

j3rem1e commented Mar 30, 2021

I am waiting for Storybook v6.2 before adding this feature.

That's said, vscode check/autocompletion is not related to this issue. the vscode svelte plugin supports typescript checking without explicitly configuring a preprocessor.

@jesperp
Copy link

jesperp commented Jun 26, 2021

Was just searching for TS support in svelte native format but ending up here. But now I also learned why some events/slots don't show up in SB 😄
Any news on this? 😊

@benbender
Copy link

@j3rem1e any news on this one? Don't want to be pushy, but as ts-support is maturing in svelte, I would like to argue that this missing feature breaks the promise of "native" stories in storybook for svelte in a way. And (as in my case) it would be very convenient, to be able to write ts through the whole codebase and don't have to think about the context :) Thanks for your efforts!

@iva2k
Copy link

iva2k commented Oct 21, 2021

Storybook is great and Svelte+Storybook+Typescript could be a very potent combination.

I'm using this workaround in .storybook/main.js to use Typescript components while the issue is being fixed:

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
  },
  ...
};

@aberndtiteratec
Copy link

Storybook is great and Svelte+Storybook+Typescript could be a very potent combination.

I'm using this workaround in .storybook/main.js to use Typescript components while the issue is being fixed:

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
  },
  ...
};

Was anyone able to make it work with vite aswell?

@blindfish3
Copy link

Was anyone able to make it work with vite aswell?

I'm still working on it; but this runs OK (so far: I only have a skeleton project with no vendor imports):

./storybook/main.js

module.exports = {
	stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
	addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-svelte-csf'],
	framework: '@storybook/svelte',
	core: { builder: 'storybook-builder-vite' },
	async viteFinal(config, { configType }) {
		config.preprocess = preprocess({
			scss: {
				prependData: "@import './static/style.scss';"
			}
		});
		return config;
	}
};

I've seen examples where you handle preprocess like this:

svelteOptions: {
		"preprocess": import("../svelte.config.js").preprocess
	},

...but I couldn't get that to work; so I'm currently duplicating the config :/

I also had issues related to module imports. To get around that I added ./storybook/package.json:
{ "type": "commonjs" }

Storybook seems to run fine with my TS components and my scss is processed correctly; but at the moment the Docs > code view sometimes shows <Proxy<RenderContext> instead of the component's tag.

@aberndtiteratec
Copy link

Was anyone able to make it work with vite aswell?

I'm still working on it; but this runs OK (so far: I only have a skeleton project with no vendor imports):

./storybook/main.js

module.exports = {
	stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
	addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-svelte-csf'],
	framework: '@storybook/svelte',
	core: { builder: 'storybook-builder-vite' },
	async viteFinal(config, { configType }) {
		config.preprocess = preprocess({
			scss: {
				prependData: "@import './static/style.scss';"
			}
		});
		return config;
	}
};

I've seen examples where you handle preprocess like this:

svelteOptions: {
		"preprocess": import("../svelte.config.js").preprocess
	},

...but I couldn't get that to work; so I'm currently duplicating the config :/

I also had issues related to module imports. To get around that I added ./storybook/package.json: { "type": "commonjs" }

Storybook seems to run fine with my TS components and my scss is processed correctly; but at the moment the Docs > code view sometimes shows <Proxy<RenderContext> instead of the component's tag.

Are you also able to use TypeScript inside of your .stories.svelte-files? I can also use components written in TypeScript in my stories. However, when I try to define a typed variable in a .stories-file, I get an error.

@blindfish3
Copy link

Are you also able to use TypeScript inside of your .stories.svelte-files?

I hadn't tried; but no: I also get errors when I try typing something in one of those files :/

bfanger added a commit to bfanger/storybook-builder-vite that referenced this issue Feb 12, 2022
bfanger added a commit to bfanger/storybook-builder-vite that referenced this issue Feb 12, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Feb 12, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Feb 12, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Feb 12, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Feb 13, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Feb 13, 2022
bfanger added a commit to bfanger/storybook-builder-vite that referenced this issue Feb 16, 2022
bfanger added a commit to bfanger/storybook-builder-vite that referenced this issue Feb 16, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Feb 24, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Apr 9, 2022
@benmccann
Copy link
Contributor

I'm not sure how the various repos fit together, but I sent a fix for this in builder-vite: storybookjs/builder-vite#428

IanVS pushed a commit to storybookjs/builder-vite that referenced this issue Jul 8, 2022
Partially reverts #382

The reason given there was that:
> which may not be what storybook users want / expect, since their production config may be different from the storybook config (same reason we don't automatically merge vite.config.js)

However, I think that users would expect their `svelte.config.js` to be taken into account. E.g. right now the user's preprocessing configuration is ignored. The user can still pass custom `svelteOptions` in `.storybook/main.cjs` if they need to override their normal options for some reason (although I can't think of a reason off the top of my head why this would be necessary)

You can see a number of people complaining preprocessing doesn't work here: storybookjs/addon-svelte-csf#4
@carusog
Copy link

carusog commented Aug 11, 2022

I set up a fresh-install repo with a simple TypeScript component.
You can find 2 FIXME tasks in the code that highlight the issues.

I hope it can be useful to test this issue out.

The only two issues are currently:

  1. TypeScript components are not supported.
  2. OT: Unresolved alias imports. I.E. trying to import components from ($lib/etc…) doesn't work.

Is there anything else we can do to help with this? More than happy to help.

@AcePetrucci
Copy link

Any planned fixes for the two issues @carusog brought up?

@carusog
Copy link

carusog commented Sep 7, 2022

As a temporary workaround, I've set up my main.cjs file as follow:

const sveltePreprocess = require('svelte-preprocess');
const path = require('path');

module.exports = {
	stories: [
		'../src/**/*.stories.mdx',
		'../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'
	],
	addons: [
		'@storybook/addon-links',
		'@storybook/addon-essentials',
		'@storybook/addon-interactions',
		'@storybook/addon-svelte-csf'
	],
	framework: '@storybook/svelte',
	core: {
		builder: '@storybook/builder-vite'
	},
	svelteOptions: {
		preprocess: [
			sveltePreprocess({
				postcss: true // (1)
			})
		]
	},
	features: {
		storyStoreV7: false
	},
	async viteFinal(config, { configType }) { // (2)
		/** @type {import('vite').UserConfig} */
		return {
			...config,
			resolve: {
				alias: [
					{
						find: '$lib',
						replacement: path.resolve(__dirname, '../src/lib')
					},
				]
			},
		};
	}
};

Notice that I am:

  1. duplicating Svelte options in here 🤷🏻‍♂️
  2. duplicating (since Svelte itself is supposed to do so already) aliases in here as well

I am far away to be an expert, but I suspect this may be an issue with Vite interoperability features between CommonJS files and ES6 Modules files.

FYI @AcePetrucci

@AcePetrucci
Copy link

In the end I had to give up on Svelte and SvelteKit for now since there's still so many issues trying to make them work with type definitions, storybook and exporting the components as WebComponents. Truly a shame since like Svelte as library so much.

But before that I also got it working too, somewhat similar to how you did:

const path = require('path');
const { loadConfigFromFile, mergeConfig } = require('vite');

module.exports = {
	stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
	addons: [
		'@storybook/addon-links',
		'@storybook/addon-essentials',
		'@storybook/addon-interactions',
		'@storybook/addon-svelte-csf'
	],
	framework: '@storybook/svelte',
	core: {
		builder: '@storybook/builder-vite'
	},
	svelteOptions: {
		preprocess: import('../svelte.config.js').then((module) => {
			return module.preprocess;
		})
	},
	features: {
		storyStoreV7: false
	},
	async viteFinal(config, { configType }) {
		const { config: userConfig } = await loadConfigFromFile(
			path.resolve(__dirname, '../vite.config.js')
		);

		const plugins = userConfig.plugins
			.flat(1)
			.filter(
				(p) => !p.name.startsWith('vite-plugin-svelte') || p.name === 'vite-plugin-svelte-kit'
			);

		return mergeConfig(config, {
			...userConfig,
			plugins
		});
	}
};

I hope that can help anyone on the same boat

@carusog
Copy link

carusog commented Sep 8, 2022

Thanks, @AcePetrucci, it looks like a more elegant solution. I'll give it a try later this week. 🙏

bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Sep 12, 2022
bfanger added a commit to bfanger/addon-svelte-csf that referenced this issue Oct 3, 2022
@JReinhold JReinhold self-assigned this Dec 14, 2022
@ryu-man
Copy link

ryu-man commented Jan 7, 2023

Using typescript does not work in .stories.svelte with @storybook/addon-svelte-csf@3.0.0-next.3 and vite preprocess or svelte-preprocess in storybook@7 beta
this is what prints on the console

WARN 🚨 Extraction error on src\stories\Button.stories.svelte: Unexpected token (5:10)
WARN 3:   import Button from "./Button.svelte";
WARN 4: 
WARN 5:   let value: string;
WARN               ^
WARN 6: </script>
WARN 7:
CompileError [ParseError]: Unexpected token

@JReinhold
Copy link
Collaborator

@ryu-man is what you're experiencing the same as #88?

@ryu-man
Copy link

ryu-man commented Jan 10, 2023

@JReinhold yes the same issue

@Tyneor
Copy link

Tyneor commented Aug 16, 2023

I started a fresh repo and I don't have any issues with typescript inside the .stories.svelte using the default configuration.
I think this is fixed ?

@JReinhold
Copy link
Collaborator

You might be right @Tyneor, I'll close this. If anyone is still experiencing this with the latest versions of packages, feel free to write again with a link to a reproduction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet