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

"Function called outside component initialization" when using URQL with SvelteKit production server (dev server works fine) #2397

Closed
Nickersoft opened this issue Sep 10, 2021 · 6 comments · Fixed by sveltejs/vite-plugin-svelte#166 or #2402

Comments

@Nickersoft
Copy link

Nickersoft commented Sep 10, 2021

Describe the bug

I'm experiencing an interesting bug in which using URQL on the client-side throws a "Function called outside component initialization" error... however, it only happens after building a production build with the Node adapter. If I run my code using the dev environment my site loads fine. I'm curious about the difference between how the two servers are run that could hint as to what is happening here.

I started a discussion over on urql-graphql/urql#1938, but as I'm not sure if the issue lies with SK or URQL, I figured I'd cover both bases. A little bit more context can be found in the linked ticket, but overall, this is the issue I'm facing.

Reproduction

I managed to reproduce the issue in https://github.com/Nickersoft/urql-repro. Just be sure to run yarn first.

  • To check the dev server: yarn dev
  • To check the production build: yarn build && yarn preview

Logs

Error: Function called outside component initialization
    at get_current_component (file:///Users/tnickerson/base/urql-repro/node_modules/svelte/internal/index.mjs:938:15)
    at setContext (file:///Users/tnickerson/base/urql-repro/node_modules/svelte/internal/index.mjs:968:5)
    at setClient (file:///Users/tnickerson/base/urql-repro/node_modules/@urql/svelte/dist/urql-svelte.mjs:155:3)
    at file:///Users/tnickerson/base/urql-repro/.svelte-kit/output/server/app.js:1532:3
    at Object.$$render (file:///Users/tnickerson/base/urql-repro/.svelte-kit/output/server/app.js:1327:18)
    at Object.default (file:///Users/tnickerson/base/urql-repro/.svelte-kit/output/server/app.js:1385:117)
    at file:///Users/tnickerson/base/urql-repro/.svelte-kit/output/server/app.js:1494:42
    at Object.$$render (file:///Users/tnickerson/base/urql-repro/.svelte-kit/output/server/app.js:1327:18)
    at file:///Users/tnickerson/base/urql-repro/.svelte-kit/output/server/app.js:1384:78
    at $$render (file:///Users/tnickerson/base/urql-repro/.svelte-kit/output/server/app.js:1327:18)

System Info

System:
    OS: macOS 11.5.2
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 2.20 GB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.17.4 - /var/folders/yh/cv0rc4pd0px2xktclp4yt49h0000gq/T/fnm_multishells/44377_1631239888327/bin/node
    Yarn: 3.0.2 - ~/.yarn/bin/yarn
    npm: 6.14.14 - /var/folders/yh/cv0rc4pd0px2xktclp4yt49h0000gq/T/fnm_multishells/44377_1631239888327/bin/npm
  Browsers:
    Brave Browser: 93.1.29.77
    Chrome: 93.0.4577.63
    Firefox: 89.0.2
    Safari: 14.1.2
  npmPackages:
    @sveltejs/adapter-node: next => 1.0.0-next.45 
    @sveltejs/kit: next => 1.0.0-next.162 
    svelte: ^3.42.4 => 3.42.4

Severity

blocking all usage of SvelteKit

Additional Information

I'm aware that this topic has been discussed at length in both communities (using URQL with SvelteKit), but in this particular case I'm not attempting to run any code on the server, and am following all of the advice found in various discussions surrounding the use of URQL.

@benmccann
Copy link
Member

I'm not attempting to run any code on the server

I'm not familiar with urql, but that may be your problem. You are running code on the server. If I set ssr: false then it works

@Nickersoft
Copy link
Author

Nickersoft commented Sep 10, 2021

@benmccann Thanks for the quick response! Without globally disabling SSR, is there any way around this until URQL supports SSR out-of-the-box?

@benmccann
Copy link
Member

You can disable SSR on a per-page basis. Is there any information about why SSR does not work with urql? I wonder if it might be a Vite bug such as vitejs/vite#4306

@Nickersoft
Copy link
Author

Yeah, so there's been quite a large discussion about it here. The general consensus seems to be that initClient / setClient (used to initialize the GraphQL client) calls setContext under the hood, which errors when called on the server.

The urql docs suggest that adding optimizeDeps: { exclude: ['@urql/svelte'] } to your Svelte config should fix this error, but myself and others have tried and it hasn't made a difference, so perhaps it is a Vite issue.

@bluwy
Copy link
Member

bluwy commented Sep 11, 2021

Dug into this today, the issue is that we add svelte to ssr.noExternal in vite-plugin-svelte during build here. Per the comment, it's needed so we can resolve svelte as svelte/ssr. But this breaks for @urql/svelte since it, in turn, imports svelte, but @urql/svelte itself is externalized so we never got to resolve it's imported svelte to svelte/ssr, causing two Svelte instances running hence the error.

You can observe the behaviour by building the repro repo, and open .svelte-kit/output/server/app.js. Notice we bundled setContext, and we also import @urql/svelte, which it's setClient function isn't using our bundled setContext.


Workaround

  1. Set config.kit.vite.ssr.noExternal to ['@urql/svelte']. vite-plugin-svelte could automate this by checking deps with svelte as peer dep.
  2. Or set config.kit.vite.ssr.external to ['svelte']. You won't get the benefits of resolve svelte to a different module in SSR mode svelte#6372 though

Honestly, I don't think svelte/ssr was the right path all along, but the work has been done. cc @dominikg

@dominikg
Copy link
Member

svelte/ssr helps to avoid boilerplate code in onMount for SSR with client only dependencies. The fix on vite-plugin-svelte is the way to go 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants