How to fix "Function called outside component initialization" with Svelte
Recently, a sapper-based project went over the limit for the size of the built image sent to the cloud platform we were using. To reduce it I knew the easiest first step would be to make sure only runtime dependencies were in
dependencies in our
package.json by moving everything else to
Svelte is a devDependency by default in the sapper template, but when I purged dependencies using
yarn workspaces focus --all --production,
@urql/svelte threw an error:
Error: Cannot find module 'svelte/store' Require stack: - ./node_modules/@urql/svelte/dist/urql-svelte.js - ./__sapper__/build/server/server-782caa63.js - ./__sapper__/build/server/server.js - ./__sapper__/build/index.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
But when I moved
svelte to a dependency I got an error saying
Function called outside component initialization. This is documented on the now-defunct sapper issue tracker in issue #592 with the suggested fix being to put
svelte back as a
devDependency. So I was stuck between two different errors.
I discovered a workaround, though. All I had to do was open up and change
rollup.config.js. The default export has a key for the server, and inside server there is a key for external modules. These are the modules that should be imported from node_modules. By default the template contains this code:
In short, this finds all the non-dev dependencies and tells rollup they are external. By changing it to filter out svelte, we can let rollup continue to import the locally built svelte runtime.
external: Object.keys(pkg.dependencies) .filter((packageName) => packageName !== 'svelte') .concat(require('module').builtinModules),
And this works while still allowing
@urql/svelte to import it after purging of the dev dependencies.
Not perfect, but a workaround that works.