mefechoel/svelte-navigator

TypeError: append_styles is not a function

asode opened this issue · 8 comments

asode commented

Describe the bug

When using renderWithRouter with jest + TypeScript the following error occurs:

TypeError: append_styles is not a function

  at Object.init (node_modules/svelte/internal/index.js:1791:22)
  at new Router (node_modules/svelte-navigator/dist/svelte-navigator.umd.js:1243:16)
  at create_fragment (src/testHelp/WrapRouter.svelte:335:11)
  at init (node_modules/svelte/internal/index.js:1809:37)
  at new WrapRouter (src/testHelp/WrapRouter.svelte:452:3)
  at render (node_modules/@testing-library/svelte/dist/pure.js:81:21)
  at renderWithRouter (src/testHelp/renderWithRouter.ts:22:9)
  at Object.<anonymous> (src/components/Layout.test.ts:5:19)
  at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
  at runJest (node_modules/@jest/core/build/runJest.js:387:19)
  at _run10000 (node_modules/@jest/core/build/cli/index.js:408:7)
  at runCLI (node_modules/@jest/core/build/cli/index.js:261:3)

To Reproduce

Here's a repo to reproduce the error.
Here's the error reproduced in GitHub Actions

Expected behavior

No error and succesfully rendering the component with the wrapped router.

Same thing is happening to me after I tried bundling with esbuild.

index.mjs:1788 Uncaught TypeError: append_styles is not a function
    at init (index.mjs:1788)
    at new Router (svelte-navigator.module.mjs:1191)
    at create_fragment6 (App.svelte:26)
    at init (index.mjs:1806)
    at new App (App.svelte:11)
    at main.js:3
    at main.js:7

However, it was working properly when building with Vite

asode commented

Thank you @rodryquintero for the input. Did you use the wrapRouter example and did you write it in TS? Did you write your tests using TS which had to be transformed with ts-jest? Just wondering what works and what doesn't. :)

Hi, @asode

the append_styles was a breaking change of internal API since svelte 3.40.0

see HERE for details

have you tried to downgrade the svelte version to 3.39.0?

Hi,
I had the same issue and I found a workaround without downgrading Svelte. All you have to do is compile the source code of the package within the jest tests.

First, we need a custom jest resolver and an exception to tell jest to transform the svelte-navigator source code.

My package.json

"jest": {
    ...
    "resolver": "<rootDir>/jestResolver.cjs",
    "transformIgnorePatterns": [
      "<rootDir>/node_modules/(?!svelte-navigator)"
    ],
    "transform": {
      "^.+\\.svelte$": [
        "svelte-jester",
        {
          "preprocess": true
        }
      ],
      "^.+\\.ts$": "ts-jest",
      "^.+\\.js$": "babel-jest"
    },
    "moduleFileExtensions": [
      "js",
      "ts",
      "svelte"
    ],
   ...
  }

jestResolver.cjs

module.exports = (request, options) => {
    if (request === 'svelte-navigator') {
        request = 'svelte-navigator/src';
    }

    return options.defaultResolver(request, options);
};

babel.config.json

{
  "presets": ["@babel/preset-env"]
}

If you haven't installed babel and babel jest, run the following
npm i -D @babel/preset-env babel-jest

I hope this can be useful :)

Another workaround I've found is to import the component sources directly so that they're compiled using the latest version of svelte i.e.

import {Router} from "svelte-navigator";

becomes:

import Router from "svelte-navigator/src/Router.svelte";

How did you fix it? I don't think downgrade svelte to run tests is a proper solution, also it makes another issues in the app itself