Skip to content

Svelte 5: vitest + jsdom error: mount(...) is not available on the server #11394

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

Closed
ChqThomas opened this issue Apr 30, 2024 · 4 comments
Closed

Comments

@ChqThomas
Copy link

Describe the bug

When testing a component in the jsdom environment using Vitest, you get the following error: mount(...) is not available on the server. This error occurs when you try to instantiate a component using the new mount() function.

The issue is the same with happy-dom.

Reproduction

Simple reproduction available here: Stackblitz

Versions:

Example:

// @vitest-environment jsdom

import { expect, test } from 'vitest';
import Hello from '../src/Hello.svelte';
import { mount } from 'svelte';

test('instantiate component', () => {
  const target = document.createElement('div');
  document.body.appendChild(target);

  mount(Hello, {
    target,
  });

  expect(target.innerHTML).toContain('Hello');
});
 FAIL  test/mount.test.ts > instantiate component
Svelte error: lifecycle_function_unavailable
`mount(...)` is not available on the server
 ❯ Module.lifecycle_function_unavailable node_modules/svelte/src/internal/server/errors.js:9:16
      7|  */
      8| export function lifecycle_function_unavailable(name) {
      9|  const error = new Error(`${"lifecycle_function_unavailable"}\n${`\`${name}(...)\` is not available on the server`}`);
       |                ^
     10| 
     11|  error.name = 'Svelte error';
 ❯ Module.mount node_modules/svelte/src/index-server.js:29:24
 ❯ eval test/mount.test.ts:11:3

Logs

No response

System Info

System:
    OS: Linux 5.15 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
    CPU: (24) x64 13th Gen Intel(R) Core(TM) i7-13700K
    Memory: 12.33 GB / 15.49 GB
    Container: Yes
    Shell: 3.6.4 - /usr/bin/fish
  Binaries:
    Node: 20.11.1 - /usr/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 10.2.4 - /usr/bin/npm
    bun: 1.0.30 - ~/.bun/bin/bun
  npmPackages:
    rollup: ^3.7.0 => 3.20.0

Severity

blocking an upgrade

@paoloricciuti
Copy link
Member

You need to add a specific resolver in your vite config

/// <reference types="vitest" />

// Configure Vitest (https://vitest.dev/config/)

import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';

-export default defineConfig({
+export default defineConfig(({ mode }) => ({
  test: {
    /* for example, use global to avoid globals imports (describe, test, expect): */
    // globals: true,
  },
+  resolve: {
+    conditions: mode === 'test' ? ['browser'] : [],
+  },
  plugins: [svelte()],
-});
+}));

this will instruct vite to use the browser resolution to import stuff which in turn will make mount available even in node environment. Don't forget the conditional or SSR will break in built app too.

https://stackblitz.com/edit/svelte-5-vitest-mount-jsdom-heemji?file=vite.config.ts

@ChqThomas
Copy link
Author

That's exactly what I needed, thanks!

ndelangen added a commit to storybookjs/storybook that referenced this issue Jul 4, 2024
akunzai added a commit to akunzai/svelte-boilerplate that referenced this issue Oct 21, 2024
@lungarella-raffaele
Copy link

Someone knows why this config was necessary in Svelte 4? The config you provided works, and know my component testing is working properly, but there is another issue that I cannot find a way to solve. I have a test about a service that must run in a non-browser environment, so I used the browser from $app/environment to check if am in the browser or not. The problem is that with this resolve the browser variable seems to be set to true and my test fail. Do I need different resolvers?

@connorads
Copy link

connorads commented Dec 31, 2024

I had the same problem, I followed the docs and it works now 👍
https://testing-library.com/docs/svelte-testing-library/setup

import {defineConfig} from 'vitest/config'
import {svelte} from '@sveltejs/vite-plugin-svelte'
import {svelteTesting} from '@testing-library/svelte/vite'

export default defineConfig({
  plugins: [svelte(), svelteTesting()],
  test: {
    environment: 'jsdom',
    setupFiles: ['./vitest-setup.js'],
  },
})

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

4 participants