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

Unable to test files with $app/stores import after migrating to new vite.config.js format #5525

Closed
illogic-al opened this issue Jul 14, 2022 · 12 comments

Comments

@illogic-al
Copy link

Describe the bug

I had previously set up a project with vitest and, after migrating this project to the new vite.config.js I kept getting the error:

[HMR][Svelte] Unrecoverable HMR error in <Header>: next update will trigger a full reload with the following backtrace:

TypeError: Cannot read properties of undefined (reading 'page')
 ❯ getStores .svelte-kit/runtime/app/stores.js:23:22
     21|        return {
     22|                page: {
     23|                        subscribe: stores.page.subscribe
       |                      ^
     24|                },
     25|                navigating: {
 ❯ Object.subscribe .svelte-kit/runtime/app/stores.js:45:17
 ❯ subscribe node_modules/.pnpm/[email protected]/node_modules/svelte/internal/index.mjs:55:25
 ❯ Module.component_subscribe node_modules/.pnpm/[email protected]/node_modules/svelte/internal/index.mjs:64:34
 ❯ instance$ src/components/Header.svelte:72:24
 ❯ Module.init node_modules/.pnpm/[email protected]/node_modules/svelte/internal/index.mjs:1891:11
 ❯ new Header$ src/components/Header.svelte:89:25
 ❯ Module.createProxiedComponent node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-hmr/runtime/svelte-hooks.js:341:9
 ❯ new ProxyComponent node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-hmr/runtime/proxy.js:242:6
 ❯ new Proxy<Header> node_modules/.pnpm/[email protected][email protected]/node_modules/svelte-hmr/runtime/proxy.js:349:11

I assume this has something to do with HMR not working the same now as it did with the old svelte.config.js method but I am not certain.

I tried adding the following to disable HMR in vite but it didn't change the outcome.

server: {
    hmr: false
},

I'm pretty new to sveltekit and svelte so it's entirely possible I'm donig something wrong, but given that this worked before the config format change, and doesn't now, that's the likely culprit in my mind. Minimal repo that allows you to reproduce the issue is given below

Reproduction

  1. Pull https://github.com/illogic-al/store-test
  2. Use pnpm i to install dependencies.
  3. Run vite test

The error I showed above will be present in the terminal. Again, this was not occurring pre @sveltejs/[email protected]

Logs

No response

System Info

System:
    OS: macOS 12.4
    CPU: (8) arm64 Apple M1 Pro
    Memory: 199.22 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.11.0 - /usr/local/bin/node
    npm: 8.13.1 - /usr/local/bin/npm
  Browsers:
    Firefox: 101.0.1
    Safari: 15.5
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.59
    @sveltejs/kit: next => 1.0.0-next.372
    svelte: ^3.44.0 => 3.49.0
    vite: ^2.9.13 => 2.9.14

Severity

blocking all usage of SvelteKit

Additional Information

No response

@benmccann
Copy link
Member

I know Storybook has to do some stuff to disable HMR. I'd hope the Vitest setup wouldn't have to be as complicated though

@illogic-al
Copy link
Author

That doesn't really help me figure out how to disable hot module reloading. I looked at the Plugin interface and there is no hot option I can set to false there (the Plugins[] are being returned by sveltekit()).

So what would I pass to sveltekit from import { sveltekit } from '@sveltejs/kit/vite'; to disable it (assuming that's the problem).

Or is vitest not meant to be used w/ sveltekit anymore? I don't care either way, I was just trying to "stay within the ecosystem" and trying vitest out.

@illogic-al
Copy link
Author

I see this in the link you provided: sveltejs/vite-plugin-svelte#321 (comment)
Am I supposed to add this to my vite config instead? And then pass it the hot: false option?

I was under the assumption that vite-plugin-svelte isn't being used anymore because create-svelte doesn't put it in the generated vite.config.js file.

@benmccann
Copy link
Member

I'm guessing that this was caused by the new version of vite-plugin-svelte, which now requires you to put it as vitePlugin.hot in svelte.config.js. Can you try setting the option there instead?

@illogic-al
Copy link
Author

illogic-al commented Jul 14, 2022

That didn't change the output at all.
https://github.com/illogic-al/store-test/blob/eb36d846f1203c2b3a9e05700aa35cf5f2bf9e0c/svelte.config.js#L13

And I looked at the type info for Option and vitePlugin isn't mentioned. Though this implies that it does exist: https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#config-file-resolving

Do i need to install vite-plugin-svelte manually?

@benmccann
Copy link
Member

Oh, you're using outdated dependencies. I sent you a PR to update: illogic-al/store-test#1

I'm not seeing anything related to HMR, so I think that was a red herring and the real issue is related to $app/stores being undefined. I'm not exactly sure how it would have worked before. Would you also be able to share a project where it was working without the vite.config.js?

I haven't used Vitest myself, so don't have much experience with this. @Davidpon do you have any experience using stuff from $app/stores? It could be a cool thing to demo in svelte-add-vitest

@illogic-al
Copy link
Author

So, I went back and looked at my branch. I also was using the vitest-svelte-kit package (kit 357 -> 372, see package-lock file for other versions.

Given that I wasn't using stock packages I can't actually claim this was working with sveltekit + vitest before, and given the code I see in the vitest-svelte-kit src, it probably wasn't working.

I don't knoe if this becomes a feature request for svelte or vitest, but if it is a svelte thing, I could try my hand at making the changes (w/ some guidance) :-)

@benmccann
Copy link
Member

Ah, yeah, that's why it was working for you. That package provides some mocks: nickbreaton/vitest-svelte-kit#16 (comment)

I'm going to close this as a duplicate of #1485, which was asking for the mocking ability

@wd-David
Copy link

I haven't used Vitest myself, so don't have much experience with this. @Davidpon do you have any experience using stuff from $app/stores? It could be a cool thing to demo in svelte-add-vitest

I haven't tested with runtime modules like $app, but here is a workable solution using vi.mock in order to test Header.svelte in SvelteKit Demo App:

// setupTest.js for Vitest
vi.mock('$app/stores', async () => {
	const { readable, writable } = await import('svelte/store');
	/**
	 * @type {import('$app/stores').getStores}
	 */
	const getStores = () => ({
		navigating: readable(null),
		page: readable({ url: new URL('http://localhost'), params: {} }),
		session: writable(null),
		updated: readable(false)
	});
	/** @type {typeof import('$app/stores').page} */
	const page = {
		subscribe(fn) {
			return getStores().page.subscribe(fn);
		}
	};
	/** @type {typeof import('$app/stores').navigating} */
	const navigating = {
		subscribe(fn) {
			return getStores().navigating.subscribe(fn);
		}
	};
	/** @type {typeof import('$app/stores').session} */
	const session = {
		subscribe(fn) {
			return getStores().session.subscribe(fn);
		}
	};
	/** @type {typeof import('$app/stores').updated} */
	const updated = {
		subscribe(fn) {
			return getStores().updated.subscribe(fn);
		}
	};
	return {
		getStores,
		navigating,
		page,
		session,
		updated
	};
});

BTW, the person you tagged wasn't me 😅.

@illogic-al
Copy link
Author

@davipon That did indeed work, thanks for that! And now that I know these have to be mocked I can do so next time. Thanks again!

@janosh
Copy link
Contributor

janosh commented Jan 7, 2023

What's the current state here? Wondering if there's now a solution without mocking?

@benjiegarcia
Copy link

I haven't used Vitest myself, so don't have much experience with this. @Davidpon do you have any experience using stuff from $app/stores? It could be a cool thing to demo in svelte-add-vitest

I haven't tested with runtime modules like $app, but here is a workable solution using vi.mock in order to test Header.svelte in SvelteKit Demo App:

// setupTest.js for Vitest
vi.mock('$app/stores', async () => {
	const { readable, writable } = await import('svelte/store');
	/**
	 * @type {import('$app/stores').getStores}
	 */
	const getStores = () => ({
		navigating: readable(null),
		page: readable({ url: new URL('http://localhost'), params: {} }),
		session: writable(null),
		updated: readable(false)
	});
	/** @type {typeof import('$app/stores').page} */
	const page = {
		subscribe(fn) {
			return getStores().page.subscribe(fn);
		}
	};
	/** @type {typeof import('$app/stores').navigating} */
	const navigating = {
		subscribe(fn) {
			return getStores().navigating.subscribe(fn);
		}
	};
	/** @type {typeof import('$app/stores').session} */
	const session = {
		subscribe(fn) {
			return getStores().session.subscribe(fn);
		}
	};
	/** @type {typeof import('$app/stores').updated} */
	const updated = {
		subscribe(fn) {
			return getStores().updated.subscribe(fn);
		}
	};
	return {
		getStores,
		navigating,
		page,
		session,
		updated
	};
});

BTW, the person you tagged wasn't me 😅.

This works for me, thanks!

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

5 participants