Reputation: 16696
I have written and published a svelte library that makes the form validation library vest easy to use with svelte. I have thoroughly tested it, and it works great, also with a local path dependency. But as soon as I import the library from npm I get this error:
Function called outside component initialization
I'm pretty sure the function in question is setContext()
. The thing is... I'm sure it's not called outside component initialization, and if I just copy the source of the .ts file into my project it works again.
I assume that somehow they have access to different svelte versions, and that's what's causing the mixup. But I don't see how it's possible, because I don't have svelte as a dependency, only as a peer dependency (I also tried removing it from peerDependencies
but that didn't change anything).
Here is the repo: https://github.com/enyo/use-vest
Here is repo that can replicate the issue: https://github.com/enyo/use-vest-repro
Upvotes: 3
Views: 5263
Reputation: 1846
UPDATE: All of this is wrong
The problem is that you can't do a setContext()
outside of a Svelte component, you need to call it explicitly in the <script>
tag. The reason it works when you copy and paste it into the component is that the Svelte compiler can associate the component with the given context.
In short, you can't use setContext()
outside a .svelte
file.
Hence, a way to solve this problem is to export an actual .svelte
file (e.g. a <VestForm>
component). However, there might be another way of going about it better suited to your specific use case, but I'm not sure since I'm not familiar with Vest.
I think the version of Svelte has nothing to do with your issue.
Hope this helps.
Upvotes: 0
Reputation: 29897
After some debugging I found that error:
Function called outside component initialization
only happens on the dev server, on the client and production build the library works as expected.
This is because on the server the setContext is imported from different runtimes.
On the server the setContext
inside the Form.svelte is included from "svelte/index.js" but in "use-vest/dist/index.js" the setContext
is included from "svelte/index.mjs"
.js vs .mjs
For H.B. the call stacks:
Trace: js
at Object.<anonymous> (/Volumes/Sites/use-vest-repro/node_modules/svelte/internal/index.js:987:9)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Module._load (node:internal/modules/cjs/loader:827: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 importModuleDynamicallyWrapper (node:internal/vm/module:435:15)
Trace: mjs
at file:///Volumes/Sites/use-vest-repro/node_modules/svelte/internal/index.mjs:984:9
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 importModuleDynamicallyWrapper (node:internal/vm/module:435:15)
at async nodeImport (/Volumes/Sites/use-vest-repro/node_modules/vite/dist/node/chunks/dep-59dc6e00.js:59403:21)
at async eval (/src/lib/components/Form.svelte:7:31)
at async instantiateModule (/Volumes/Sites/use-vest-repro/node_modules/vite/dist/node/chunks/dep-59dc6e00.js:59333:9)
I'm not sure how to solve this...
Let me know if you find a solution.
Upvotes: 1