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

Svelte for VSCode auto-generates types for in-app .svelte components, but not imported library components. #2325

Open
bmcbarron opened this issue Mar 24, 2024 · 4 comments
Labels
awaiting submitter bug Something isn't working

Comments

@bmcbarron
Copy link

Describe the bug

I have a TS+SvelteKit monorepo with svelte app packages, svelte component libraries, and pure typescript libraries. During development, a file-watching process rebuilds all libraries (via tsc or svelte-package). Library exports point to these generated artifacts. It's worked well for a couple years.

Recently I've switched all exports to point directly to the source .ts and .svelte files and disabled the intermediate builds. Vite handles this well. The app builds and runs in dev or production without issue. There is one issue: VSCode issues Cannot find module errors for library components (e.g. @mono.lib/Thing.svelte), unless the .d.ts files are made available. This is in contrast to app components (e.g. $lib/Thing.svelte) which VSCode handles just fine without explicit type files.

Resolving this discrepancy would allow me to completely eliminate the separate build step, making my dev flow much simpler and more reliable. Even if the requested behavior were not the default, this seems like a straightforward pattern that should be achievable through configuration. I've tried to find references to this situation in this issue repo, in the Svelte docs, and on Stack Overflow, with no luck.

The closest item I've found is vitejs/vite#1873, which is an analogous issue in Vite (now resolved).

Reproduction

Import a component from a workspace component library, symlinked from node_modules as typical.

<script lang="ts">
  import Thing from '@mono.lib/Thing.svelte';

Run svelte-package -w in the library, and export those types through @mono.lib/package.json

  "exports": {
    "./*": {
      "types": "./dist/*.d.ts",
      "svelte": "./src/lib/*"

The above works in both Vite and VSCode. However, if I remove the "types" export, or change it to "./src/lib/*", I get the error:

Cannot find module '@mono.lib/Thing.svelte' or its corresponding type declarations.

For completeness, I also tried an export pattern of "./src/lib/*.d.ts", although I wouldn't expect that to work.

Expected behaviour

VSCode for Svelte should handle this import the same way it would handle:

<script lang="ts">
  import Thing from '$lib/Thing.svelte';

In this case, the types for Thing.svelte are inferred without the presence of an explicit .svelte.d.ts file.

System Info

  • OS: Windows 11
  • IDE: VSCode 1.87.2
  • Plugin: Svelte for VSCode v108.3.3
  • Typescript: tsc 5.3.3

Which package is the issue about?

Svelte for VS Code extension

Additional Information, eg. Screenshots

No response

@bmcbarron bmcbarron added the bug Something isn't working label Mar 24, 2024
@dummdidumm
Copy link
Member

dummdidumm commented Mar 25, 2024

Please provide a reproduction repository, it's hard to decipher just from the steps how the tsconfig and vite config etc look like.

In general we currently don't resolve types for Svelte files inside node modules analogous to how typescript doesn't resolve types for js files inside node modules

@bmcbarron
Copy link
Author

Thanks! Here's a repo.

If anything doesn't work, let me know. This is a subtree of my monorepo which has a lot of tooling not included here. I believe I've made it fully independent, but I might have missed something.

Regarding TS not resolving types in node_modules: That hasn't been my experience. I've included a typescript import in the root route to demonstrate that it works for VSCode and Vite.

@dummdidumm
Copy link
Member

Typescript imports are resolved, but JavaScript imports are not. Typescript does this for performance reasons. We're currently doing something very similar for Svelte files. I'm not sure how to square this circle, because we definitely want to encourage people to ship their Svelte libraries with d.ts type files due to said performance reasons.
As a workaround (untested but should work) you can set a path alias in your tsconfig which resolves the package import to the original src location on disk.

@bmcbarron
Copy link
Author

The svelte library I'm including isn't intended to be shipped. It's an internal detail of the organization of the monorepo. The package is an npm workspace. As a result, npm symlinks it into node_modules. npm's choice of workspace implementation has muddied the waters of node_modules, and thus not all such packages are published/external.

I did try the workaround you suggested. I started with modifying compilerOptions.paths in the typescript handler of svelte.config.js. I can't put it the paths in the app's tsconfig.json without also reproducing the $lib paths, due to the way that tsconfig array merging works (or rather, doesn't). Next, I had to expand the rootDirs to the common ancestor of the app and the library. Then I needed to add the dependency package's files to the "include" pattern. At that point, I think maybe it should have worked, but I was still getting errors about "rootDir is expected to contain all source files". With more investigation I can probably solve that too, but the amount of code that's being added is getting to be substantial and brittle. Do you have any other ideas for workarounds?

If you feel it'd be worthwhile, I'd be willing to take a stab at implementing a svelte PR to provide a more explicit workaround. For example, I could imagine adding some regex to svelte.config.js that identifies the node_module packages that should be considered internal and eligible for type generation. There is some precedent for singling out dependencies with Vite's ssr.external/noExternal. That's just one approach, and I'd be happy to work on whatever other resolution you suggest. Our monorepo is committed to using Svelte, so being able to handle this case is worth our investment.

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

No branches or pull requests

2 participants