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

Support for SvelteKit #17248

Open
bartlomieju opened this issue Jan 2, 2023 · 111 comments · Fixed by #23634
Open

Support for SvelteKit #17248

bartlomieju opened this issue Jan 2, 2023 · 111 comments · Fixed by #23634

Comments

@bartlomieju
Copy link
Member

Prompted by discussion on Discord I tried to get SvelteKit working in Deno.

After an hour of debugging I found the main blocker: by default SvelteKit installed Node adapter, which does a bit of setup that is not needed in Deno and makes the project crash, namely:
https://github.com/sveltejs/kit/blob/e7bc0be2b25aff5ac151e3d83b771ad80cac1ab8/packages/kit/src/exports/node/polyfills.js#L6-L28
which installs polyfills from undici for various Web APIs like fetch or Response. These objects work slightly differently in Deno and arguably installing them in Deno is not needed.

I think the way forward would be to get a Deno dedicated adapter that would essentially be a noop as there's no need to change anything to make SvelteKit work.

Of course it would be very nice if deno run -A npm:create-svelte@latest would set up a project in a way that requires no changes (namely making specifiers use npm: prefixes).

@benmccann
Copy link

Hi @bartlomieju, thanks for taking a look to support SvelteKit! I work on SvelteKit and wanted to better understand the issue to know if there's anything we're doing wrong on our side. Newer versions of Node provide those APIs out-of-the-box, but older versions don't. SvelteKit polyfills those APIs only when they're not already available.

These objects work slightly differently in Deno and arguably installing them in Deno is not needed.

I know very little about Deno. I'd assume if Deno has those APIs then SvelteKit would not polyfill them, but if it doesn't have those APIs then SvelteKit will probably break if they don't get polyfilled. Does Deno do something differently than Node here such as not adding the APIs to globalThis? How should users utilize the APIs in this case?

I think the way forward would be to get a Deno dedicated adapter that would essentially be a noop as there's no need to change anything to make SvelteKit work.

To clarify, would that adapter live in SvelteKit?

Of course it would be very nice if deno run -A npm:create-svelte@latest would set up a project in a way that requires no changes (namely making specifiers use npm: prefixes).

Assuming this is something we'd have to implement on our side, can you clarify what "making specifiers use npm: prefixes" means?

@bartlomieju
Copy link
Member Author

bartlomieju commented Jan 3, 2023

Hi @benmccann, thanks for taking the time.

Newer versions of Node provide those APIs out-of-the-box, but older versions don't. SvelteKit polyfills those APIs only when they're not already available.

I haven't seen this bit - from what I saw in the Node adapter these polyfills were installed unconditionally. I assume there must be some check for Node version that causes the polyfills to be installed. Which version would be required? When polyfilling Node APIs we return version v18.12.1 (latest LTS Node.js version).

I know very little about Deno. I'd assume if Deno has those APIs then SvelteKit would not polyfill them, but if it doesn't have those APIs then SvelteKit will probably break if they don't get polyfilled. Does Deno do something differently than Node here such as not adding the APIs to globalThis? How should users utilize the APIs in this case?

They work the same in Deno as in browsers or with undici, they are present on globalThis. They work the same for all intents and purposes for end-users, but internally they are implemented differently than in browsers or undici and some of our APIs break when certain non-public fields are not present. This becomes non-issue if the polyfills are not installed.

To clarify, would that adapter live in SvelteKit?

I think that's a question for you, whether you're interested in providing an official adapter for Deno, I'll be glad to help in any capacity to make it happen :)

Assuming this is something we'd have to implement on our side, can you clarify what "making specifiers use npm: prefixes" means?

Deno has now built-in support for npm - we do that by using npm: specifiers - more info on that here: https://deno.land/[email protected]/node/npm_specifiers. Long story, short: we currently don't rely (or actually use at all) package.json file to figure out dependencies needed, but instead look at all imports with npm: specifiers to pull relevant packages (and then recursively analyzing them). What I meant by that comment was that it would be nice if Svelte's generator would for example put import svelte from "npm:svelte" instead of import svelte from "svelte" when it sees it's being run in Deno (eg. by checking for typeof globalThis.Deno !== "undefined". Though I think it's a secondary issue at this point - we already added custom templates to https://github.com/bluwy/create-vite-extra that take care of that and we're debating internally if we should support package.json in user code.

Thanks for dropping by and helping with this problem!

@benmccann
Copy link

these polyfills were installed unconditionally

Oops! My bad. That was outdated info. It seems as of sveltejs/kit#7675 that you're correct. It appears we had to do it unconditionally to overwrite the Node-provided version which is an older version of Undici and is broken (sveltejs/kit#7673). Maybe with Node 20 or SvelteKit 2 we'll be able to do something nicer 😄

from what I saw in the Node adapter

Ah! I was pointed here by an issue in the SvelteKit repo which talked about the dev command, which I guess was broken by the fact that we now polyfill unconditionally. The adapters are only run with the build command. The node adapter was really only meant for Node.js, but we do have a Deno adapter that a community member developed and I'm assuming this issue would not be present there: https://github.com/pluvial/svelte-adapter-deno.

I'm not quite sure what the best fix for the dev mode issue would be. Maybe we could detect node vs deno and only install the polyfills on Node. I'd prefer if there were a nicer way to do this, but maybe it's just temporary until Node 20 / SvelteKit 2 anyway so we can live with it being imperfect. I'll have to check with the other maintainers though

@bartlomieju
Copy link
Member Author

Oops! My bad. That was outdated info. It seems as of sveltejs/kit#7675 that you're correct. It appears we had to do it unconditionally to overwrite the Node-provided version which is an older version of Undici and is broken (sveltejs/kit#7673). Maybe with Node 20 or SvelteKit 2 we'll be able to do something nicer 😄

Thanks for a quick response. That's exactly the problem that I've faced.

I'm not quite sure what the best fix for the dev mode issue would be. Maybe we could detect node vs deno and only install the polyfills on Node. I'd prefer if there were a nicer way to do this, but maybe it's just temporary until Node 20 / SvelteKit 2 anyway so we can live with it being imperfect. I'll have to check with the other maintainers though

A bit quick and dirty, but that would solve the problem at hand and would allow us and Deno users to leverage Svelte with Vite. I'm eager to hear what you decide to do. Let me know if there's anything I can help with to move this issue forward.

@benmccann
Copy link

Hopefully this is fixed in SvelteKit 1.0.4: https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md#104

Thanks for tracking down the issue and sharing enough details to help get it fixed! Let me know if there's anything else to be done on the SvelteKit side.

@bartlomieju
Copy link
Member Author

Hopefully this is fixed in SvelteKit 1.0.4: https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md#104

Thanks for tracking down the issue and sharing enough details to help get it fixed! Let me know if there's anything else to be done on the SvelteKit side.

Thank for a quick turnaround @benmccann, I can confirm that latest version fixes the problem. I'm gonna keep this issue open for a little longer as we might take approach of supporting SvelteKit running in Vite as-is, without any changes (eg. npm: specifiers).

@jpaquim
Copy link

jpaquim commented Jan 6, 2023

I also confirm that updating fixes the issue with running the development server. I've also been trying to integrate svelte-adapter-deno to generate the production build itself for Deno: https://github.com/jpaquim/sveltekit-deno

I'm getting this error, though:

error: Uncaught TypeError: Could not resolve 'file:///Users/<user>/sveltekit-deno/.svelte-kit/output/server/index.js' from 'file:///Users/<user>/sveltekit-deno/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/core/prerender/prerender.js'.
  Caused by:
    could not find npm package for 'file:///Users/<user>/sveltekit-deno/.svelte-kit/output/server/index.js'
    at async prerender (file:///Users/<user>/sveltekit-deno/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/core/prerender/prerender.js:100:31)
[vite-plugin-sveltekit-compile] Prerendering failed with code 1
error during build:
Error: Prerendering failed with code 1
    at ChildProcess.<anonymous> (file:///Users/<user>/sveltekit-deno/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/exports/vite/index.js:551:15)
    at ChildProcess.emit (https://deno.land/[email protected]/node/_events.mjs:379:28)
    at https://deno.land/[email protected]/node/internal/child_process.ts:229:16

The file (.svelte-kit/output/server/index.js) is generated correctly, but for some reason importing it seems to be failing, maybe due to the way the dynamic import is being built here? https://github.com/sveltejs/kit/blob/master/packages/kit/src/core/prerender/prerender.js#L100

@jpaquim
Copy link

jpaquim commented Jan 6, 2023

I also had to manually remove the @neoconfetti/svelte import as it wasn't working even with the npm: specifier. Same thing with the @import '@fontsource/fira-mono' in styles.css, commented out for now.

@jakubdonovan
Copy link

jakubdonovan commented Jan 7, 2023

Hopefully this is fixed in SvelteKit 1.0.4: https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md#104
Thanks for tracking down the issue and sharing enough details to help get it fixed! Let me know if there's anything else to be done on the SvelteKit side.

Thank for a quick turnaround @benmccann, I can confirm that latest version fixes the problem. I'm gonna keep this issue open for a little longer as we might take approach of supporting SvelteKit running in Vite as-is, without any changes (eg. npm: specifiers).

It looks like the sk patch was reviewed and merged by rich harris yesterday. sveltejs/kit#8338

What's the process of installing sveltekit in a deno project now? I've ran deno run -A npm:create-vite-extra and selected the deno-svelte template with typescript and then went to vite.config.mts and replaced the svelte plugin with sveltekit like so

import { defineConfig } from 'npm:vite@^4.0.0'
import { svelte } from 'npm:@sveltejs/vite-plugin-svelte@^2.0.0'
import { sveltekit } from 'npm:@sveltejs/kit/vite'
import 'npm:svelte@^3.54.0'

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [sveltekit()]
})

ran deno task dev and still got the pesky undefined body error. When looking through my deno.lock, I noticed that the pre-patched version of sveltekit (1.0.1) was imported and that my file structure has things missing (app.html, the routes folder, no +page.svelte) etc

A clarification will be highly appreciated! How would we go about getting a deno-sveltekit template in create-vite-extra?

@bartlomieju
Copy link
Member Author

What's the process of installing sveltekit in a deno project now? I've ran deno run -A npm:create-vite-extra and selected the deno-svelte template with typescript and then went to vite.config.mts and replaced the svelte plugin with sveltekit like so

Most likely the template needs to be updated - I created these templates about 3 months ago so they might be outdated by now.

ran deno task dev and still got the pesky undefined body error. When looking through my deno.lock, I noticed that the pre-patched version of sveltekit (1.0.1) was imported and that my file structure has things missing (app.html, the routes folder, no +page.svelte) etc

If you have used Svelte before and used unversioned import you might get a version from cache. Either use version import or run with --reload to force Deno to pull latest version.

A clarification will be highly appreciated! How would we go about getting a deno-sveltekit template in create-vite-extra?

I just opened a PR to create-vite-extra that essentially copy-pasted existing templates and adjusted them to be Deno compatible (by changing imports to use npm: specifiers and list all dependencies in vite.config.mts.

@fernandolguevara
Copy link

fernandolguevara commented Jan 18, 2023

I'm trying to run vite build script
deno run -A --unstable --node-modules-dir npm:vite build
on a deno + sveltekit + unocss project

but got this error

error: Uncaught TypeError: Could not resolve 'file:///Users/anon/deno-sk-uno/.svelte-kit/output/server/index.js' from 'file:///Users/anon/deno-sk-uno/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/core/prerender/prerender.js'.
  Caused by:
    could not find npm package for 'file:///Users/anon/deno-sk-uno/.svelte-kit/output/server/index.js'
    at async prerender (file:///Users/anon/deno-sk-uno/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/core/prerender/prerender.js:102:31)
[vite-plugin-sveltekit-compile] Prerendering failed with code 1
error during build:
Error: Prerendering failed with code 1
    at ChildProcess.<anonymous> (file:///Users/anon/deno-sk-uno/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/exports/vite/index.js:551:15)
    at ChildProcess.emit (https://deno.land/[email protected]/node/_events.mjs:379:28)
    at https://deno.land/[email protected]/node/internal/child_process.ts:229:16

The issue has occurred on the child process spawned for the pre-render stage...
the generated files on output/*.js don't follow deno import syntaxt for npm packages

@benmccann
Copy link

It appears this will be fixed by future updates to Deno: #17475

@bartlomieju
Copy link
Member Author

running deno task build in a skeleton-app created with create-svelte results in an error

develop/reproductions/denokit ❯ deno task build
Warning Currently only basic package.json `scripts` are supported. Programs like `rimraf` or `cross-env` will not work correctly. This will be fixed in the upcoming release.
Task build vite build

vite v4.1.4 building SSR bundle for production...
transforming (72) src/routes/styles.css"confetti" is imported from external module "@neoconfetti/svelte" but never used in "src/routes/sverdle/+page.svelte".
✓ 74 modules transformed.
6:23:26 PM [vite-plugin-svelte] ssr compile done.
package    files      time       avg
denokit        9    91.3ms    10.1ms
error: Uncaught Error: Argument list too long (os error 7)
    at spawnChildInner (internal:runtime/js/40_spawn.js:45:17)
    at spawnChild (internal:runtime/js/40_spawn.js:65:10)
    at Command.spawn (internal:runtime/js/40_spawn.js:322:12)
    at new ChildProcess (internal:deno_node/polyfills/internal/child_process.ts:108:16)
    at spawn (internal:deno_node/polyfills/child_process.ts:102:12)
    at Object.fork (internal:deno_node/polyfills/child_process.ts:93:12)
    at file:///home/dominikg/develop/reproductions/denokit/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/utils/fork.js:39:32
    at new Promise (<anonymous>)
    at fn (file:///home/dominikg/develop/reproductions/denokit/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/utils/fork.js:38:10)
    at Object.handler (file:///home/dominikg/develop/reproductions/denokit/node_modules/.deno/@[email protected]/node_modules/@sveltejs/kit/src/exports/vite/index.js:648:28)

Reported on Discord by @dominikg

@fernandolguevara
Copy link

@bartlomieju It is not possible to run the vite build on deno for a svelte-kit project ... it seems deno doesn't implement process.send used in the sveltekit prerender stage for the ipc

https://github.com/sveltejs/kit/blob/master/packages/kit/src/core/postbuild/prerender.js#L16
https://github.com/sveltejs/kit/blob/master/packages/kit/src/utils/fork.js#L14

@lfmaciasr
Copy link

lfmaciasr commented Apr 6, 2023

@fernandolguevara @bartlomieju @benmccann It's seems to me (I might be wrong, of course) that since one of Deno's main design goals is providing "A runtime that resembles the web, using browser APIs that work on the server" thus going the web workers APIs way to create an IPC between parent and child process, maybe the SvelteKit team could consider addressing this particularity by branching https://github.com/sveltejs/kit/blob/master/packages/kit/src/utils/fork.js#L14 according to, for example, https://medium.com/deno-the-complete-reference/going-from-node-js-to-deno-part-5-child-process-bde9cd21d3d6

@benmccann
Copy link

The reason SvelteKit does prerendering in a subprocess is so that we can call process.exit to ensure it's fully killed (e.g. to support cases where the user's app does something like leave a database connection we need to kill) without killing the main process (see sveltejs/kit#5306).

I'm not familiar with web workers, but we would need to be able to call process.exit from one without killing the main process. It sounds like that's what happens so it should be a viable alternative: https://nodejs.org/api/worker_threads.html#class-worker

If anyone wants to send a PR, this sounds like something we could accept a PR for in SvelteKit assuming it doesn't massively complicate things.

@andocodes
Copy link

Could anyone gauge how much effort it would take for say, Svelte and SvelteKit to provide an actual native Deno package? Seems like a huge opportunity?

@EthanThatOneKid
Copy link

Could anyone gauge how much effort it would take for say, Svelte and SvelteKit to provide an actual native Deno package? Seems like a huge opportunity?

As a community member, it's challenging to gauge the effort it would take to provide a native Deno package for Svelte and SvelteKit, and it's better left to SvelteKit or Deno core developers. However, there is some relevant information to consider.

Currently, we can use the Svelte compiler module from NPM in Deno, as shown in the example below:

import { compile } from "npm:svelte/compiler";

const result = compile("Hello world", {
    format: "esm",
    filename: "hello-world.svelte",
});

console.log({ result });

This allows us to use the Svelte compiler in Deno. However, SvelteKit, the framework, relies on other Svelte language tools that are not fully compatible with Deno, such as the Svelte LSP which is built for the Node.js toolchain.

It appears that several Svelte tools would need to be refactored in order to fully support Deno. Therefore, determining the effort required to provide a native Deno package for Svelte and SvelteKit would require closer collaboration between the SvelteKit and Deno core developers.

@benmccann
Copy link

SvelteKit, the framework, relies on other Svelte language tools that are not fully compatible with Deno, such as the Svelte LSP which is built for the Node.js toolchain

I guess you're talking about the check script that's included in new projects when you choose to enable type checking in the new project creation wizard? While svelte-check is a very nice tool for type checking your .svelte files, you can still fully use SvelteKit without it. It's probably best to discuss svelte-check in a separate ticket because it's a different project with a different set of developers from SvelteKit. Unfortunately I don't know anything about the svelte-check internals.

For SvelteKit itself, the only thing I'm aware of that's needed is switching the subprocess to a worker as mentioned in #17248 (comment). It's not a priority for the Svelte team as we focus on Svelte 4, but if anyone wants to send a PR I'm happy to advise and we will review it!

@slacktracer
Copy link

I very much hope this moves forward, and soon. By the issues I've been looking Deno and SvelteKit don't know each other very well but having spent a good chunk of time getting to know both I am very confident they would be a match made in heaven... 🤞🏼

@Afrowave
Copy link

This is an excellent thread. I recently committed all my future frontend work to be done in SvelteKit, having come from a more "traditional" Design > HTML5/CSS > frontend route.

SvelteKit works the way I think frontend frameworks should. 😁 Deno is the future for "tidy" front-end web development. Once we throw in WebAssembly and Domain-Specific-Languages like Rust and Python, wrapped in single binary executable, then we will be in business. 😃

@dominikg
Copy link

fyi, you can already use deno to run sveltekit applications, it's building that doesn't work currently.
So eg. have a multi-stage Dockerfile where the first stage builds your app with node, then copies the result to a runner stage from a deno image of the same arch, call deno with appropriate permission flags and you're good to go.

@Afrowave
Copy link

Thank you @dominikg,

That is very good to know. I should try this out and report back. Better still, do you have or where can one find a repo with something like you have explained?

1 similar comment
@Afrowave
Copy link

Thank you @dominikg,

That is very good to know. I should try this out and report back. Better still, do you have or where can one find a repo with something like you have explained?

@about-hector
Copy link

fyi, you can already use deno to run sveltekit applications, it's building that doesn't work currently. So eg. have a multi-stage Dockerfile where the first stage builds your app with node, then copies the result to a runner stage from a deno image of the same arch, call deno with appropriate permission flags and you're good to go.

@dominikg do you mind sharing an example dockerfile for the basic svelte starter app?
I'm not quite getting the part where you copy the result to the runner stage. Most likely my bad for not understanding deno and docker well enough.

@lukeed
Copy link
Contributor

lukeed commented Oct 11, 2024

[email protected] was released to support this

@mjdNjhNJ
Copy link

Hi, I'm getting following warning when running SvelteKit project:

Task dev vite dev
▲ [WARNING] Cannot find base config file "./.svelte-kit/tsconfig.json" [tsconfig.json]

    tsconfig.json:2:12:
      2 │   "extends": "./.svelte-kit/tsconfig.json",
        ╵              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Here is my project structure:
image

I'm on Svelte 5 btw.

@dominikg
Copy link

dominikg commented Oct 13, 2024

that warning occurs when the generated types in .svelte-kit are not present yet, eg the very first time you call vite dev. You can call svelte-kit sync to create it beforehand. see https://kit.svelte.dev/docs/cli#svelte-kit-sync

edit: please ask these questions on svelte discord: https://svelte.dev/chat to not spam all the lovely people in this specific issue with unrelated things

@jakubdonovan
Copy link

jakubdonovan commented Oct 14, 2024

that warning occurs when the generated types in .svelte-kit are not present yet, eg the very first time you call vite dev. You can call svelte-kit sync to create it beforehand. see https://kit.svelte.dev/docs/cli#svelte-kit-sync

edit: please ask these questions on svelte discord: https://svelte.dev/chat to not spam all the lovely people in this specific issue with unrelated things

I still seem to be getting issues running sveltekit on Deno.

deno run -A npm:create-svelte testing
Screenshot 2024-10-15 at 03 16 31
Deno doesn't yet support path in the tsconfig.ts so the import path has to be manually specified.

@benmccann
Copy link

The latest SvelteKit is now on sirv 3. Happy to help review and land any other code changes needed for Deno support.

@benmccann
Copy link

It appears that Deno 2.0 is now a package manager with deno install. If we could get #25342 prioritized that would help us support that functionality in Svelte's CLIs

@sspilleman
Copy link

FYI: The "ERR_EMPTY_RESPONSE" or "can't open the page" error is tracked here #26115

Is this being worked on? I have the feeling the solution is to force "every package" to comply with the "node:" or "npm:" specifiers because deno needs it... It simply doesn't feel like "deno can be used as a drop-in replacement for node/bun" as stated in the "deno 2 release video/notes/etc." ... I'm ok with having issues, no probs at all... I like deno a lot, switched completely from nodejs and never looked back I'm used to having issues with a lot of npm packages, been there, done that.... Just don't state node compat if it requires the node ecosystem to change their code...

Would it be a temp solution to "just" try assuming without specifiers it's either node: or npm: for the time being?

@cam-mcevenue
Copy link

cam-mcevenue commented Oct 16, 2024

Any idea how to get sveltekit generated types, modules and path aliases to work with deno LSP in VSCode? The svelte LSP resolves types fine in .svelte files. Deno LSP doesn't check those currently. But all the other .ts files like +page can't resolve $app/* types, ./$types generated types, or $lib path alias.

deno.json typescript compiler options doesn't yet support path or rootDir config.

To reproduce

Run deno init in an empty repo, clear out the deno.json config and files generated.

deno run -A npm:create-svelte@latest and install the sverdle demo project

deno install --allow-scripts

deno run dev to generate the types

Open any of the .ts files that use $app/*, $lib or ./$types. You'll see the deno-ts errors I'm talking about

Current workaround is to disable the Deno LSP for the src directory

.vscode/settings.json

{
  "deno.enable": true,
  "deno.lint": true,
  "deno.disablePaths": ["./src"]
}

@jakubdonovan
Copy link

jakubdonovan commented Oct 17, 2024

Any idea how to get sveltekit generated types, modules and path aliases to work with deno LSP in VSCode? The svelte LSP resolves types fine in .svelte files. Deno LSP doesn't check those currently. But all the other .ts files like +page can't resolve $app/* types, ./$types generated types, or $lib path alias.

deno.json typescript compiler options doesn't yet support path or rootDir config.

To reproduce

Run deno init in an empty repo, clear out the deno.json config and files generated.

deno run -A npm:create-svelte@latest and install the sverdle demo project

deno install --allow-scripts

deno run dev to generate the types

Open any of the .ts files that use $app/*, $lib or ./$types. You'll see the deno-ts errors I'm talking about

Current workaround is to disable the Deno LSP for the src directory

.vscode/settings.json

{
  "deno.enable": true,
  "deno.lint": true,
  "deno.disablePaths": ["./src"]
}

Yes, I would also like to know if there is a way to get denols to properly pick up sveltekit generated types. I'm not getting any type safety in these instances at all.
Screenshot 2024-10-17 at 07 51 30

@lts20050703
Copy link

@cam-mcevenue @jakubdonovan At least for $lib, it can be solved by adding a import map to deno.json or deno.jsonc

{
	// ...
	"imports": { "$lib": "./src/lib", "$lib/": "./src/lib/" }
	// ...
}

I looked at the SvelteKit tsconfig file (./.svelte-kit/tsconfig.json) and only saw mentions of $lib in compilerOptions.paths. @benmccann do you know what $env and $app (as well as ./$types) maps to?

@lts20050703
Copy link

lts20050703 commented Oct 17, 2024

@jakubdonovan I was able to solve $env with the following additions to the import map

// deno.json or deno.jsonc
{
	"imports": {
		"$lib": "./src/lib",
		"$lib/": "./src/lib/",
		"$env/static/public": "./.svelte-kit/ambient.d.ts",
		"$env/static/private": "./.svelte-kit/ambient.d.ts",
		"$env/dynamic/public": "./.svelte-kit/ambient.d.ts",
		"$env/dynamic/private": "./.svelte-kit/ambient.d.ts"
	}
}

As for ./$types, I found that it maps to ./svelte-kit/types/src/routes/.../$types.d.ts.

For example, in the file ./src/routes/api/version/+server.ts, importing ./$types will map to ./.svelte-kit/types/src/routes/api/version/$types.d.ts

Of course it is possible to just list out all of the paths of the SvelteKit app, but I think you can imagine how tedious it would be.

@bartlomieju I wonder if the import map support like somehow reading the file path and then substitute it? I imagine something like "./src/routes/**/$types": "./.svelte-kit/types/src/routes/**/$types.d.ts"

Finally, for $app stuff, it looks like it maps to @sveltejs/kit/src/runtime/app/..., for example $app/environment maps to @sveltejs/kit/src/runtime/app/environment/index.js. However, because the package.json exports field doesn't export that path, it is impossible to import it. I had to add something like the following

// @sveltejs/kit/package.json
{
	"exports": {
		// ...
		"./environment": {
			"types": "./src/runtime/app/environment/types.d.ts",
			"import": "./src/runtime/app/environment/index.js"
		}
	}
}

and then add the following to the import path

	"imports": {
		// ...
		"$app/environment": "npm:@sveltejs/kit/environment",
	}

for it to work. @benmccann Is there any reason you guys don't export the src/runtime/app/ stuff?

@jakubdonovan
Copy link

@benmccann Any update on this?

@StevenStavrakis
Copy link

StevenStavrakis commented Oct 21, 2024

@cam-mcevenue @jakubdonovan At least for $lib, it can be solved by adding a import map to deno.json or deno.jsonc

{
	// ...
	"imports": { "$lib": "./src/lib", "$lib/": "./src/lib/" }
	// ...
}

I looked at the SvelteKit tsconfig file (./.svelte-kit/tsconfig.json) and only saw mentions of $lib in compilerOptions.paths. @benmccann do you know what $env and $app (as well as ./$types) maps to?

I could not get the deno.json import paths to work for this. I ended up creating a tsconfig file and putting the import paths in there, and now it works fine, though I don't know what side effects that might have for the project as a whole, if any.

For additional context, I use Deno env imports on the server, not the SvelteKit one's, so I haven't had $env problems yet.

@Malix-Labs
Copy link

Also see sveltejs/cli#214

@StevenStavrakis
Copy link

Interestingly, the solution provided in the comment above works for env variables, but not for $lib

@phoenisx
Copy link

phoenisx commented Oct 28, 2024

Not sure if this works already, cause I wasn't able to figure out a proper solution to this.

I'm trying to create a barrel file to export specific Svelte Components from a folder, but Deno lint is throwing an error, also Deno is unable to resolve the import/export statements for *.svelte modules.

E.g. Following doesn't work for me, maybe I'm doing something wrong.

// src/lib/components/exports.ts
export { default as Component } from "./Component.svelte";

Maybe this works: declare module "*.svelte" {} in global.d.ts to resolve all svelte imports in .ts modules, but this might affect Svelte Component typings.

@Malix-Labs
Copy link

Interestingly, the solution provided in the comment above works for env variables, but not for $lib

Did you found a fix @StevenStavrakis ?

@StevenStavrakis
Copy link

Interestingly, the solution provided in the comment above works for env variables, but not for $lib

Did you found a fix @StevenStavrakis ?

Only thing that worked for me was creating a tsconfig and doing the import aliasing there. Ultimately, I moved my project off of Deno and onto Bun, but I'm not using any special Bun features so it might as well be on standard node with pnpm at this point.

@Malix-Labs
Copy link

I have some rough edge with svelte on deno too

@jakubdonovan
Copy link

Interestingly, the solution provided in the comment above works for env variables, but not for $lib

Did you found a fix @StevenStavrakis ?

Only thing that worked for me was creating a tsconfig and doing the import aliasing there. Ultimately, I moved my project off of Deno and onto Bun, but I'm not using any special Bun features so it might as well be on standard node with pnpm at this point.

Yep, that's what I did, after about two days of battling issue after issue and no real response from the Deno staff. I really like what they're doing, but unfortunately support is not all there yet. I will try again in 6 months and see how things have changed.

@bartlomieju
Copy link
Member Author

Hey folks sorry for slow response, we got a ton of issues getting opened after the release of Deno 2 and we're trying to tackle them to unblock as many use cases as soon as possible.

We understand that you are all excited to use Svelte/SvelteKit with Deno and we have not forgotten about it. We're addressing stuff like #26311 to make it easier to use Svelte with Deno. We also have a few bigger challenges like figuring out how to make auto-generated types work properly as well as how to make Svelte language server and Deno's language server play nicely.

I can assure you that we will tackle these things one, by one, so please bear with us. If you hit a specific problem it might be beneficial to help us prioritize if you open a separate issue - it's easy to lose something in this very long thread.

Thanks for your patience.

@Malix-Labs
Copy link

Malix-Labs commented Nov 1, 2024

#25342 has just been closed 🚀

@bartlomieju
Copy link
Member Author

bartlomieju commented Nov 7, 2024

Hey again folks 🖐️

So I was about to write out separate GH issues for various problems we distilled from this issue in the past few weeks and... I have trouble doing so.

We identified several, distinct problems:

  1. The main issue using Svelte is with the LSP, there's a lot of red squiggly lines in every .svelte file
  2. Having unstable: sloppy-imports still requires to exclude no-slippy-imports lint rule
  3. If there’s no unstable-sloppy-import imports enabled, then most imports in .svelte files are resulting in LSP deno(no-local) diagnostics. But that diagnostics doesn’t suggest a solution like adding unstable-sloppy-imports.
  4. ./$types imports are not resolved and result in the same error. They use tsconfig.json and use rootDirs option.
  5. Another big problem is that we use “NodeNext”-ish resolution but it uses “bundler” resolution

That said, I wanted to test this from scratch, so I did:

deno run -A -r npm:create-svelte@latest

Which resulted in:

'npm create svelte' has been replaced with 'npx sv create'

Fine, I did:

deno run -A --reload npm:sv create svelte-kit-app

Used default options, as well as a lot of additional dependencies like tailwind, playwright, etc.

But when I opened the VSCode and installed Svelte extension (again, starting from scratch), everything seems to work just fine...

No red squiggly lines, no resolution errors, no diagnostics.

Screenshot 2024-11-07 at 02 08 41


May I kindly ask you to open separate issues with problems you are running into in your existing projects or new ones that you create?

This will greatly help us identify common problems that need to be addressed one-by-one. At this point this issue is a catch-all and makes it hard to figure out what are the pitfalls you are running into :(

Thanks again!


EDIT: Oooops, my bad.

All is good in .svelte files, but everything breaks in .ts files:
Screenshot 2024-11-07 at 02 22 26

So the list I provided above is actually correct.

@vladjerca
Copy link

vladjerca commented Nov 17, 2024

@jakubdonovan I was able to solve $env with the following additions to the import map

// deno.json or deno.jsonc
{
	"imports": {
.         <REDACTED>
	}
}

As for ./$types, I found that it maps to ./svelte-kit/types/src/routes/.../$types.d.ts.

For example, in the file ./src/routes/api/version/+server.ts, importing ./$types will map to ./.svelte-kit/types/src/routes/api/version/$types.d.ts

Of course it is possible to just list out all of the paths of the SvelteKit app, but I think you can imagine how tedious it would be.

@bartlomieju I wonder if the import map support like somehow reading the file path and then substitute it? I imagine something like "./src/routes/**/$types": "./.svelte-kit/types/src/routes/**/$types.d.ts"

Finally, for $app stuff, it looks like it maps to @sveltejs/kit/src/runtime/app/..., for example $app/environment maps to @sveltejs/kit/src/runtime/app/environment/index.js. However, because the package.json exports field doesn't export that path, it is impossible to import it. I had to add something like the following

// @sveltejs/kit/package.json
{
	"exports": {
.         <REDACTED>
	}
}

and then add the following to the import path

	"imports": {
.         <REDACTED>
	}

for it to work. @benmccann Is there any reason you guys don't export the src/runtime/app/ stuff?

For those brave souls seeking to harness the untamed power of the Deno LSP, here lies the forbidden deno.json configuration.

{
  "imports": {
    "$lib": "./src/lib",
    "$lib/": "./src/lib/",
    "$env/static/public": "./.svelte-kit/ambient.d.ts",
    "$env/static/private": "./.svelte-kit/ambient.d.ts",
    "$env/dynamic/public": "./.svelte-kit/ambient.d.ts",
    "$env/dynamic/private": "./.svelte-kit/ambient.d.ts",
    "$app/forms": "../../node_modules/@sveltejs/kit/types/index.d.ts",
    "$app/environment": "../../node_modules/@sveltejs/kit/types/index.d.ts",
    "$app/navigation": "../../node_modules/@sveltejs/kit/types/index.d.ts",
    "$app/server": "../../node_modules/@sveltejs/kit/types/index.d.ts",
    "$app/stores": "../../node_modules/@sveltejs/kit/types/index.d.ts"
  }
}

But heed this warning, intrepid coder: The node_modules path is a fickle beast. Adapt it to your workspace, lest it consume your project whole.

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

Successfully merging a pull request may close this issue.