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

Preprocessing with Babel makes svelte components imports to be dropped #521

Closed
Andarist opened this issue May 30, 2022 · 4 comments
Closed

Comments

@Andarist
Copy link
Contributor

I've seen related issues regarding TypeScript compiler but I couldn't find any related to Babel.

I've successfully worked around my issue but I wonder if this issue is known and if perhaps at least some note to the docs could be added about it.

Basically the problem is that the script and the template parts are preprocessed separately and thus when using @babel/preset-typescript the import like this gets dropped:

import ChildComp from './ChildComp.svelte';

Babel doesn't recognize that the ChildComp was actually referenced at the "runtime position" in the original source because that part of the source is not being given to it.

The workaround that I've used is to use this preset-level option onlyRemoveTypeImports: true

@dummdidumm
Copy link
Member

onlyRemoveTypeImports sounds very much like the new TS flag preserveValueImports which was introduced in TS 4.5. The announcement blog post explains the rationale quite nicely, and also why this happens for Babel, too.
Do you if it's possible to pass onlyRemoveTypeImports: true here so this option is enabled for Babel by default? Alternatively, we should add a note to the docs.
Out of curiosity: Why are you using Babel to transpile the script contents and not TypeScript?

@Andarist
Copy link
Contributor Author

Andarist commented Jun 1, 2022

Do you if it's possible to pass onlyRemoveTypeImports: true here so this option is enabled for Babel by default?

I don't think this is supported. Those flags there are mainly targeting @babel/preset-env (although perhaps not exclusively that). I think there is a potential for this to be introduced though so a feature request could be created in Babel. I wonder if this wouldn't lead to some confusing behaviors too but maybe ultimately it would be a positive change.

Out of curiosity - have you ever considered appending some dummy runtime expressions to the end of the transformed content that would be stripped away after a transform does its job? That would allow referenced imports to be recognized by Babel/TS and potentially would avoid issues at consumer sites. I know that, especially with Babel, that wouldn't be completely safe (Babel plugins could do some weird things to the injected code) but in most setups this should work quite well.

Alternatively, we should add a note to the docs.

That would definitely be appreciated.

Out of curiosity: Why are you using Babel to transpile the script contents and not TypeScript?

More flexibility around the actual output. My "library packager" of choice (https://github.com/preconstruct/preconstruct/) only supports Babel right now. I imagine that people might end up with similar problems with other, modern, transpilers though - esbuild, SWC, etc. There is an increasing interest in using TypeScript just for typechecking and not for the actual transpilation of the sources.

dummdidumm pushed a commit that referenced this issue Jun 4, 2022
@dummdidumm
Copy link
Member

Out of curiosity - have you ever considered appending some dummy runtime expressions to the end of the transformed content that would be stripped away after a transform does its job? That would allow referenced imports to be recognized by Babel/TS and potentially would avoid issues at consumer sites. I know that, especially with Babel, that wouldn't be completely safe (Babel plugins could do some weird things to the injected code) but in most setups this should work quite well.

We actually did that for the TypeScript preprocessor in #392. It works, but it's somewhat hacky and brittle, and it requires two passes of the Svelte parser, so it's slower. Since preserveValueImports was introduced which handles exactly this use case ("hey TS, don't remove this even if it looks unused to you") I prefer that option since it's part of TS and more reliable. Consequently, I think that onlyRemoveTypeImports: true is the better choice - I added a note about it in the docs.

@Andarist
Copy link
Contributor Author

Andarist commented Jun 5, 2022

We actually did that for the TypeScript preprocessor in #392. It works, but it's somewhat hacky and brittle, and it requires two passes of the Svelte parser, so it's slower.

Oh, cool! I definitely can get behind the hacky argument :P I'm not exactly sure why this was requiring a double pass of a Svelte parser - but I trust your word on it.

Since preserveValueImports was introduced which handles exactly this use case ("hey TS, don't remove this even if it looks unused to you") I prefer that option since it's part of TS and more reliable.

To some extent - yet. The problem is that it requires you to structure your imports in a different way than usual, and it's even more aggressive that the restrictions of the isolatedModules. And thus it requires education which is suboptimal.

I respect your decision and all though - it's good that we have a dedicated note in the docs now about onlyRemoveTypeImports for Babel users. I think this is enough to close this ticket.

@Andarist Andarist closed this as completed Jun 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants