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

"browser" export condition is not set when testing with jsdom #7215

Closed
rChaoz opened this issue Jan 11, 2025 · 5 comments
Closed

"browser" export condition is not set when testing with jsdom #7215

rChaoz opened this issue Jan 11, 2025 · 5 comments

Comments

@rChaoz
Copy link

rChaoz commented Jan 11, 2025

Describe the bug

When testing SvelteKit code, various parts can depend on whether running in the browser like so:

if (browser) window.addEventListener(...)

where browser is defined using esm-env, which does it using conditional exports in package.json:

"exports": {
	...
	"./browser": {
		"browser": "./true.js",
		"development": "./false.js",
		"production": "./false.js",
		"default": "./browser-fallback.js"
	},
	...
}

Now, development is set, so unless browser is also set, it will always be false. I know you can set export conditions in Vite, but I haven't seen anything similar in Vitest. I'd expect it to be set when using a browser environment, probably using an option or similar.

Reproduction

Stackblitz: https://stackblitz.com/edit/sveltejs-kit-template-default-muke8nsy
Steps: Just wait for install and run vitest in console

Workaround

I found this way to mock it, it works for me but I believe the property is also used by SvelteKit's vite plugin, which won't see this change, so there's some edge cases in which it might not work:

vi.mock(import("esm-env"), async (importOriginal): Promise<typeof import("esm-env")> => {
    const module = await importOriginal()
    if (typeof window == "object")
        return {
            ...module,
            BROWSER: true,
        }
    else return module
})

Interestingly you cannot wrap the entire call in an if (typeof window == "object") as the mock somehow leaks into tests for which the check fails, this way it re-mocks it and removes the property for those.

Copy link

Hello @rChaoz. Please provide a minimal reproduction using a GitHub repository or StackBlitz (you can also use examples). Issues marked with needs reproduction will be closed if they have no activity within 3 days.

@rChaoz
Copy link
Author

rChaoz commented Jan 12, 2025

@hi-ogawa hi, just added a stackblitz repro

@hi-ogawa
Copy link
Contributor

Technically you can add conditions in the same way as Vite via resolve.conditions https://stackblitz.com/edit/vitest-dev-vitest-hpqypsft?file=vite.config.ts

However, not doing this for jsdom/happy-dom is probably intentional since they are only emulation on Node and forcing browser condition for all packages can cause more issues on Vitest. For example, even loading jsdom seems to be causing an issue with browser condition.

@rChaoz
Copy link
Author

rChaoz commented Jan 12, 2025

For example, even loading jsdom seems to be causing an issue with browser condition.

I did not know that, but I guess it makes sense, so mocking esm-env might be the best solution.

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Jan 13, 2025

Let me close this as resolve.conditions with browser technically works with a caveat that some packages can get broken as they don't expect to be used on Node.

If you need to mock esm-env mocking on svelte-kit testing, then that sounds like its own big topic, so please follow up in a separate issue.

@github-actions github-actions bot locked and limited conversation to collaborators Jan 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants