Svelte + Vite node module import error: Error when evaluating SSR module, failed to import module
Asked Answered
S

1

7

I am using Svelte for the first time in a setup with SvelteKit + Vite. I am trying to import a rich-text editor from a node module into a component of my app. Here is the snippet:

<script>
    import { Jodit } from 'jodit';
    import { onMount } from 'svelte';

    onMount(async () => {
        Jodit.make('#editor');
    });
</script>

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jodit/3.24.9/jodit.min.css" />

<div class="flex flex-col">
    <div class="text-orange-400">This is gonna be the editor</div>

    <textarea id="editor" />
</div>

<style lang="postcss">
</style>

When I am trying to load the page in the browser, I get the following error:

11:26:06 [vite] Error when evaluating SSR module /src/components/SimpleTextBox/SimpleTextBox.svelte: failed to import "jodit"
|- ReferenceError: self is not defined
    at Object.<anonymous> (path-to-my-project\node_modules\jodit\build\jodit.min.js:1:224)
    at Module._compile (node:internal/modules/cjs/loader:1112:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1166:10)
    at Module.load (node:internal/modules/cjs/loader:988:32)
    at Module._load (node:internal/modules/cjs/loader:834:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:409:24)
    at async nodeImport (file:///path-to-my-project/node_modules/vite/dist/node/chunks/dep-f7d05e3f.js:54391:17)

11:26:06 [vite] Error when evaluating SSR module /src/routes/+page.svelte: failed to import "/src/components/SimpleTextBox/SimpleTextBox.svelte"
|- ReferenceError: self is not defined
    at Object.<anonymous> (path-to-my-project\node_modules\jodit\build\jodit.min.js:1:224)
    at Module._compile (node:internal/modules/cjs/loader:1112:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1166:10)
    at Module.load (node:internal/modules/cjs/loader:988:32)
    at Module._load (node:internal/modules/cjs/loader:834:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:409:24)
    at async nodeImport (file:///path-to-my-project/node_modules/vite/dist/node/chunks/dep-f7d05e3f.js:54391:17)

Internal server error: self is not defined
      at Object.<anonymous> (path-to-my-project\node_modules\jodit\build\jodit.min.js:1:224)
      at Module._compile (node:internal/modules/cjs/loader:1112:14)
      at Module._extensions..js (node:internal/modules/cjs/loader:1166:10)
      at Module.load (node:internal/modules/cjs/loader:988:32)
      at Module._load (node:internal/modules/cjs/loader:834:12)
      at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
      at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
      at async Promise.all (index 0)
      at async ESMLoader.import (node:internal/modules/esm/loader:409:24)
      at async nodeImport (file:///path-to-my-project/node_modules/vite/dist/node/chunks/dep-f7d05e3f.js:54391:17)
ReferenceError: self is not defined
    at Object.<anonymous> (path-to-my-project\node_modules\jodit\build\jodit.min.js:1:224)
    at Module._compile (node:internal/modules/cjs/loader:1112:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1166:10)
    at Module.load (node:internal/modules/cjs/loader:988:32)
    at Module._load (node:internal/modules/cjs/loader:834:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:409:24)
    at async nodeImport (file:///path-to-my-project/node_modules/vite/dist/node/chunks/dep-f7d05e3f.js:54391:17)

Additionally, here's my dependencies and devDependencies from the package.json:

    "devDependencies": {
        "@sveltejs/adapter-auto": "^2.0.0",
        "@sveltejs/kit": "^1.5.0",
        "@types/quill": "^2.0.10",
        "@typescript-eslint/eslint-plugin": "^5.45.0",
        "@typescript-eslint/parser": "^5.45.0",
        "autoprefixer": "^10.4.14",
        "eslint": "^8.28.0",
        "eslint-config-prettier": "^8.5.0",
        "eslint-plugin-svelte": "^2.26.0",
        "postcss": "^8.4.23",
        "prettier": "^2.8.0",
        "prettier-plugin-svelte": "^2.8.1",
        "svelte": "^3.54.0",
        "svelte-check": "^3.0.1",
        "tailwindcss": "^3.3.2",
        "tslib": "^2.4.1",
        "typescript": "^5.0.0",
        "vite": "^4.3.0",
        "vitest": "^0.25.3"
    },
    "type": "module",
    "dependencies": {
        "@popperjs/core": "^2.11.7",
        "bcrypt": "^5.1.0",
        "classnames": "^2.3.2",
        "flowbite": "^1.6.5",
        "flowbite-svelte": "^0.34.10",
        "jodit": "^3.24.9",
        "quill": "^1.3.7"
    }
}

As well as my vite.config.ts:

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';

export default defineConfig({
    plugins: [sveltekit()],
    test: {
        include: ['src/**/*.{test,spec}.{js,ts}']
    }
});

I tried using dynamic imports in the onMounted() method, to see if it was an SSR issue, like this:

<script>
    import { onMount } from 'svelte';

    onMount(async () => {
        const jodit = (await import('jodit')).default;
        jodit.Jodit.make('#editor');
    });
</script>

This made the page load again, but the imported module still wasn't working properly, only showing this error in the browser console:

Uncaught (in promise) TypeError: jodit is undefined
    instance SimpleTextBox.svelte:6
    run index.mjs:20
    mount_component index.mjs:2058
    flush index.mjs:1280
    init index.mjs:2154
    Root root.svelte:688
    createProxiedComponent svelte-hooks.js:341
    ProxyComponent proxy.js:242
    Proxy<Root> proxy.js:349
    initialize client.js:281
    _hydrate client.js:1765
    start start.js:22
    <anonymous> (index):5242
    promise callback* (index):5241

What I find even more confusing is, after I changed it back from the dynamic import to the previous version, when saving the file, the hot-reload renders the page correctly with the editor from the module:

enter image description here

This suggests to me that the code should work, as it finds the import and correctly executes. But when I manually reload the page or restart the app, I am back to the previous error. Can someone please explain to me what is going on here and how I can permanently resolve the issue? Thank you!

Sabec answered 5/5, 2023 at 9:54 Comment(0)
S
4

This might be related to ssr and the unavailability of some DOM methods and operations during Server-Side Rendering. By default, SvelteKit uses SSR for all pages and then hydrates them on the DOM after sending over the plain HTML. If your code or a package you're using needs to access DOM APIs, you might run into such issues during the SSR phase of this cycle. This might also explain why you were able to see the code running fine after a hot reload, just a theory. Try turning off ssr for that page and use csr only, it might fix your problem:

create a +page.js file in the same directory as your +page.svelte file and add the following two lines:

export const ssr = false;
export const csr = true;

References:

Seedy answered 14/7, 2023 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.