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 devDependencies.

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:

external: Object.keys(pkg.dependencies).concat(require('module').builtinModules),

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')

And this works while still allowing @urql/svelte to import it after purging of the dev dependencies.

Not perfect, but a workaround that works.


Join my mailing list