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

Dynamic imports fail to load in dev SSR #1326

Closed
mattjennings opened this issue May 4, 2021 · 14 comments
Closed

Dynamic imports fail to load in dev SSR #1326

mattjennings opened this issue May 4, 2021 · 14 comments

Comments

@mattjennings
Copy link

mattjennings commented May 4, 2021

Describe the bug
When importing modules dynamically in a page's load function, it only works when the import is a static string and using single/double quotes (not backticks). However, they work in production. It works client-side in dev as well.

Logs
No logs other than the error itself (check the stack trace)

To Reproduce

Add this to any route component or download this repro https://github.com/mattjennings/sveltekit-dynamic-import-bug

<script context="module">
  export async function load({ page }) {
    await import("../lib/Template.svelte"); // works
    await import(`../lib/Template.svelte`); // does not work (note the backticks)
    await import(`../lib/${page.params.slug}.svelte`); // does not work
    await import("../lib/" + "Template" + ".svelte"); // does not work

    return {
      props: {},
    };
  }
</script>

Expected behavior
All imports in snippet should work in dev

Stacktraces

The same error happens for every bad import. Unfortunately, it's not a very helpful error. It would be nice to include a bit more info.

Stack trace
failed to load module for ssr: ../lib/Template.svelte
Error: failed to load module for ssr: ../lib/Template.svelte
    at instantiateModule (/Users/mattjennings/Desktop/dynamic/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-2c03f3f9.js:69022:15)

Information about your SvelteKit Installation:

Diagnostics
  • System:
    OS: macOS 11.2.3
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 97.98 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
    Binaries:
    Node: 15.11.0 - ~/.nvm/versions/node/v15.11.0/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v15.11.0/bin/yarn
    npm: 7.6.0 - ~/.nvm/versions/node/v15.11.0/bin/npm
    Browsers:
    Brave Browser: 90.1.23.75
    Chrome: 90.0.4430.93
    Safari: 14.0.3
    Safari Technology Preview: 14.2
    npmPackages:
    @sveltejs/kit: next => 1.0.0-next.96
    svelte: ^3.34.0 => 3.38.2
    vite: ^2.2.3 => 2.2.4

  • Chrome

  • Tried with no adapter & vercel adapter

Severity
It's annoying in dev but navigating to the page client-side is a fine workaround for now, and it works in production so it's not critical.

Additional context
My specific use-case here was to load a .md file dynamically from a param in the route.

@JBusillo
Copy link
Contributor

JBusillo commented May 4, 2021

I'm doing a little research on this. I've traced the problem by looping through the vite plugins -- it looks like it's happening in vite:import-analysis. I'll research a little more later on. This does look like it's a vite bug, not svelte-kit.

@mattjennings
Copy link
Author

mattjennings commented May 4, 2021

Gotcha - thanks for the help! I should have searched vite's github for this, it appears there's already an issue on it vitejs/vite#3087 and potentially a fix on the way vitejs/vite#2934.

I'll try out one of these latest vite builds and see if it's fixed for svelte-kit. In the meantime, I'll close this since it's not svelte-kit related.

edit: unfortunately, it doesn't fix the issue yet.

@JBusillo
Copy link
Contributor

JBusillo commented May 4, 2021

Researching this further -- I think the Vite issues/fixes that you mentioned only relate to imports from node_modules. I pinpointed the problem to es-module-lexer (a separate open source module) -- it does not return any dynamically generated import names, perhaps by design. I conjured up a little test with your four import scenarios -- it doesn't return a "specifier" (n:) value for those dynamic import names.
Even if es-module-lexer returned the 'specifier' as is, Vite is in its 'setup' phase for HMR and SSR -- it wants to load any imported modules before the actual SSR application code even executes -- it doesn't have access to any runtime parameters yet. This would cause Vite to fail.

BTW, I'm just doing this for fun -- It's a good way of learning the inner workings of Vite and SvelteKit. I need to get a life :)

// your test cases
async function load({ page }) {
        const a = await import("../lib/Template.svelte"); // works
        const b = await import(`../lib/Template.svelte`); // does not work (note the backticks)
        const c = await import(`../lib/${page.params}.svelte`); // does not work
        const d = await import("../lib/" + "Template" + ".svelte"); // does not work
        return { props: {} };
}

// output from es-module-lexer
[
  { n: '../lib/Template.svelte', s: 57, e: 81, ss: 50, se: 0, d: 50 },
  { n: undefined, s: 117, e: 141, ss: 110, se: 0, d: 110 },
  { n: undefined, s: 206, e: 236, ss: 199, se: 0, d: 199 },
  { n: undefined, s: 280, e: 314, ss: 273, se: 0, d: 273 }
]

@mattjennings
Copy link
Author

oh nice, I definitely appreciate the deep dive! Thankfully, there's another PR specifically for that issue that I gave a try and everything worked as expected with kit. Hopefully it'll get merged in soon!

@JBusillo
Copy link
Contributor

JBusillo commented May 5, 2021

Ah, I see. The fix is to resolve the import at a higher level if it wasn't resolved at the lower (deep) level. It makes me wonder why the deep level code even exists -- but not enough for me to explore any further! Now I can sleep.

@brittneypostma
Copy link
Contributor

I am running into a similar issue as Matt. I am trying to import a md file on a windows machine and the import path is coming out with / when windows is trying to use .

	export async function load({ page }) {
		const { slug } = page.params
		const post = await import('./posts/' + slug + '/index.md')
		return {
			props: {
				post: post.default
			}
		}
	}

also tried using backticks for the import and get the same result.

Error message 500 failed to load module for ssr: /Users/Britt/Documents/Coding/Jamstack/Svelte/tailwind-blog/C:\Users\Britt\Documents\Coding\Jamstack\Svelte\tailwind-blog\src\routes\blog/posts/first-post/index.md

Error: failed to load module for ssr: /Users/Britt/Documents/Coding/Jamstack/Svelte/tailwind-blog/C:\Users\Britt\Documents\Coding\Jamstack\Svelte\tailwind-blog\src\routes\blog/posts/first-post/index.md
at instantiateModule (C:\Users\Britt\Documents\Coding\Jamstack\Svelte\tailwind-blog\node_modules.pnpm\[email protected]\node_modules\vite\dist\node\chunks\dep-e9a16784.js:68148:15)

@Shackless
Copy link

Same here as @brittneypostma. Could you please elaborate on the workaround if you actually want to take page.params.slug into account for the dynamic import? Thank you!

@vish01
Copy link

vish01 commented Jul 6, 2021

Any updates on this? I'm having the same issue as well.

@Eugeniegrandit
Copy link

Same issue...

@vish01
Copy link

vish01 commented Jul 8, 2021

Actually, nvm. The path I was trying to access was wrong. I was trying to access src folder which is 2 steps above my current folder. So technically, it's supposed to be "../../". However, For some weird reason(Probably the way how dynamic imports works?), I had to do "../src/" to reach to src folder and it worked!
@Eugeniegrandit try to access your component by changing your path a little and see if that works for you.

@Eugeniegrandit
Copy link

Thank you @vish01! I tried to change my path a little and it worked. Actually, the folder I was trying to access is in the same folder as my file, but instead of ./ I used ../../src/routes/ and surprisingly, the warning disappeared in the console. Thanks!

@vish01
Copy link

vish01 commented Jul 14, 2021

I've noticed one thing, when I make it work for npm run dev, it fails on npm run build.
I'm trying to import a component like this:
var component = await import(`../../../src/assets/${ComponentToLoad}.svelte`);
It works fine on npm run dev but I get this error on npm run build and npm run preview:
Error: Unknown variable dynamic import: ../../../src/assets/Asset1.svelte
Hope we get a solution to this.

@subhasishdas159
Copy link

subhasishdas159 commented Oct 15, 2021

Was having the exact same dynamic import issue.
At first I was importing path like "$lib/something". This causes problems
the "../" thing instead of "$lib/" import fixed it in dev. However after deploying in cloudflare workers, it's again same error.

@benblazak
Copy link
Contributor

For anyone running across this because it's one of the only google results for Unknown variable dynamic import.

I was getting this error when building (not in dev) because the variable I had in my dynamic import had a / in it. Turns out vite doesn't like that: https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#globs-only-go-one-level-deep .

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

8 participants