Skip to content

TS enums no longer get transpiled as expected starting with [email protected] in *.svelte files #961

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

Closed
ndom91 opened this issue Aug 15, 2024 · 15 comments
Labels
documentation Improvements or additions to documentation

Comments

@ndom91
Copy link

ndom91 commented Aug 15, 2024

Describe the bug

We have a component which uses an enum as a value in a .svelte file. When using @sveltejs/[email protected] the following works as expected. However, when upgrading to @sveltejs/[email protected], we begin seeing errors about ReferenceError: Can't find variable: Action

<script lang="ts">
	enum Action {
		Create = 'createPr',
		CreateDraft = 'createDraftPr'
	}

	const actions = Object.values(Action);
	const labels = {
		[Action.Create]: 'Create PR',
		[Action.CreateDraft]: 'Create Draft PR'
	};
  ...

In 3.1.1 the code above produced compiled output like this:

var Action = /* @__PURE__ */
((Action2) => {
    Action2["Create"] = "createPr";
    Action2["CreateDraft"] = "createDraftPr";
    return Action2;
})(Action || {});

Whereas in 4.0.0-next.0 that output is missing entirely. This seems to only be effecting enums in .svelte files. Enums used like this in .ts files are unaffected.

Reproduction URL

https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAA1WQwWrDMAyGX8WIQVoWuu2aNoWy3Rd6rXtwPWV4c-Rgy4UR8u7Ddrt2B2NL-iV9_ifojcUAzWECUgNCA7txhBr4Z0xBOKNlhBqCi16nzCZob0YWVtFnK4GDhK0kyUhxEDvNxpGYUkLyq0fFKFpR6fzqfFXfV9686vlWzmHnqySZJaVLOwosVJ4aRCveT1-oeXVWNmJYlG3L9U1p1QltEl4IDkWyKvuOjaguTN3-ivJfkhnudAWx2xeovCkdiyy0i5ToHwIrxsVz5iDJfaTigiHtcUDixfLKU3oeW_Gyvvxy81T8TB7S5hSZHQlH2hr93U5_I-bscc6GRkx5Tu4uHVuoYXAfpjf4AQ37iPNx_gWxO40x3AEAAA==

Reproduction

In the above svelte-5 playground URL, you can see that the enum Action also results in the error "Action is not defined".

This link leads to a PR of our project where I bumped the dependencies and moved the enum Action down from the <script lang="ts" context="module"> to the normal <script /> tag because the enum was no longer being imported from anywhere and it's simpler that way. The PR also includes bumping a few Svelte related packages, except the vite-plugin-svelte, because that was giving us troubles.

Logs

No response

System Info

System:
  OS: Linux 6.10 NixOS 24.05 (Uakari) 24.05 (Uakari)
  CPU: (14) x64 Intel(R) Core(TM) Ultra 7 155U
  Memory: 16.20 GB / 30.87 GB
  Container: Yes
  Shell: 5.2.26 - /run/current-system/sw/bin/bash
Binaries:
  Node: 20.14.0 - /nix/store/ilkfhnqz4xczrliqjva8770x2svbfznd-nodejs-20.14.0/bin/node
  npm: 10.7.0 - /nix/store/ilkfhnqz4xczrliqjva8770x2svbfznd-nodejs-20.14.0/bin/npm
  pnpm: 9.5.0 - /nix/store/zw38hg36phakmnk3lxglyzvjwf2pivsa-corepack-nodejs-20.14.0/bin/pnpm
  bun: 1.1.20 - /run/current-system/sw/bin/bun
Browsers:
  Chromium: 127.0.6533.88
@ndom91 ndom91 added bug Something isn't working triage Awaiting triage by a project member labels Aug 15, 2024
@dominikg
Copy link
Member

svelte5 understands ts syntax in .svelte files without needing a preprocessor, however it does not work with typescript features that have code output. for that to work you have to change vitePreprocess() to vitePreprocess({script: true}) in svelte.config.js

@ndom91
Copy link
Author

ndom91 commented Aug 15, 2024

Ah okay, I'm curious why that's the default? 🤔

But thanks for the quick response!

@ndom91 ndom91 closed this as completed Aug 15, 2024
@dominikg
Copy link
Member

Ah okay, I'm curious why that's the default? 🤔

But thanks for the quick response!

we might reevaluate that default. in general i think most users/components don't need this feature so it would save processing time. But it is kind of opaque and the current feedback isn't great as you already experienced.

Would you be less concerned about this default if a message told you about it?

@ndom91
Copy link
Author

ndom91 commented Aug 16, 2024

Yeah maybe svelte-check could warn if enum's or similar are used in .svelte files 🤔 It'd definitely save folks some headache tryign to figure out what's going on

@frederikhors
Copy link

@dominikg this should be handled with an error at compile time or it will errors on runtime only as in my case.

Plus, I think the default should be changed to handle this by default if I use Typescript.

@frederikhors
Copy link

Can you please re-open this, @ndom91?

@ndom91 ndom91 reopened this Aug 22, 2024
@ndom91
Copy link
Author

ndom91 commented Aug 22, 2024

Can you please re-open this, @ndom91?

Sure, happy to discuss

@dominikg
Copy link
Member

forcing an extra unneeded transpile on all users just because some users use enums or other code generating features of typescript in some files is not great.

Ideally we find a way to avoid this scenario. For the record the breaking changes of 4.0 do mention that scripts are no longer preprocessed for typescript by default

disable script preprocessing in vitePreprocess() by default because Svelte 5 supports lang=ts out of the box (#892)

So this might also just be something that needs better communication / warnings.

There's also the question of how useful enums in .svelte script blocks are. Another way of avoiding this problem is putting them in .ts files and import.

@frederikhors
Copy link

This is not an issue with enums only, with the below code:

<script lang="ts">
    // ...

    $effect(() => {
        // ...

        if (input) {
            input.value = someOne || someTwo;
        }
    });
</script>

I get:

Unexpected token

If you expect this syntax to work, here are some suggestions: 
If you use typescript with `svelte-preprocess`, did you add `lang="ts"` to your `script` tag? 
Did you setup a `svelte.config.js`? 
See https://github.com/sveltejs/language-tools/tree/master/docs#using-with-preprocessors for more info.svelte(js_parse_error)

with someTwo highlighted in red in my IDE.

Or this other code:

<script lang="ts">
    const options: Partial<BaseOptions> = {
        // ...
        onReady() {
            //...
        } // <-- here the red error
    };
</script>

the error:

Unexpected token `}`. Did you mean `&rbrace;` or `{"}"}`?

If you expect this syntax to work, here are some suggestions: 
If you use typescript with `svelte-preprocess`, did you add `lang="ts"` to your `script` tag? 
Did you setup a `svelte.config.js`? 
See https://github.com/sveltejs/language-tools/tree/master/docs#using-with-preprocessors for more info.svelte(js_parse_error)

So now I think we should decide if Svelte 5 can handle typescript or not alone or am I wrong?

@frederikhors
Copy link

So I think the second sentence here is false:

image

@smart
Copy link

smart commented Aug 28, 2024

Just upgraded to 4 and ran into this issue. Took a while to debug with the error messages only being something like expected "{" but got ";", I think the issue was I didn't even know it was enum related until digging deep into the codebase. enabled script: true and it works fine.

@dominikg
Copy link
Member

dominikg commented Sep 3, 2024

vite-plugin-svelte@4 is going to continue to keep script: false as the default. Documentation will be updated to reflect this. svelte itself is going to get better messages to let users know that these features require a preprocessor, which v-p-s can then pick up to suggest enabling script. see sveltejs/svelte@194570d

In general i would recommend not to put ts code that uses these in .svelte files, instead put them into .ts files and import it into .svelte files.

@dominikg dominikg closed this as not planned Won't fix, can't repro, duplicate, stale Sep 3, 2024
@dominikg
Copy link
Member

dominikg commented Sep 3, 2024

docs update #974

@dominikg dominikg added documentation Improvements or additions to documentation and removed bug Something isn't working triage Awaiting triage by a project member labels Sep 3, 2024
@raythurnvoid
Copy link

The current message says

TypeScript language features like enums are not natively supported, and their use is generally discouraged. Outside of <script> tags, these features are not supported. For use within <script> tags, you will need to use a preprocessor to convert it to JavaScript before it gets passed to the Svelte compiler. If you are using vitePreprocess, make sure to specifically enable preprocessing script tags (vitePreprocess({ script: true }))|

Is there any reason why they are discouraged? I'm not aware that the Typescript team is discouraging them at all.

@dominikg
Copy link
Member

dominikg commented Oct 21, 2024

please use our discord #help-svelte-and-kit or https://github.com/sveltejs/svelte/discussions for questions about sveltes typescript support. vite-plugin-svelte is only the messenger here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

5 participants