Инициализировать URQL для Svelte асинхронным способом (мне нужно разделить schema.json на отдельный кусок)
Я использую Svelte и URQL.
Я использую здесь стройный пример из папки ваших пакетов, за исключением того, что я создаю
format: 'esm'
в моем
rollup.config.js
.
Мой накопительный пакет уже разделяет мой последний пакет на части, когда я использую
import('./Component.svelte')
в моем коде.
Что мне трудно сделать, так это асинхронно инициализировать urql, например:
import { initClient, dedupExchange, fetchExchange } from '@urql/svelte'
import { cacheExchange } from "@urql/exchange-graphcache";
const exchanges = [
cacheExchange({
resolvers: { /*... my resolvers*/ },
schema // I need this async, something like: await import('./schema').then(result => result.default)
}),
fetchExchange
]
export function initURQL () {
initClient({
url: 'http://localhost/graphql',
exchanges
})
}
Если я использую что-то вроде:
export async function initURQL () {
const schema = await import('./schema.json').default
const exchanges = [
cacheExchange({
resolvers: {},
schema
}),
fetchExchange
]
initClient({
url: 'http://localhost/graphql',
exchanges
})
}`
и позвонить из
App.svelte
с участием
;(async () => await initURQL())()
это дает мне ошибку:
Uncaught (in promise) Error: Function called outside component initialization
Как я могу это исправить?
1 ответ
Я не использую URQL, но тоже столкнулся с этой ошибкой.
К сожалению, позвонить нельзя
getContext
или же
setContext
(который является то, что
initClient
в
urql/packages/svelte-urql/src/context.ts
звонки) асинхронно.
https://svelte.dev/docs#setContext:
Как и функции жизненного цикла, это должно вызываться во время инициализации компонента.
https://github.com/timhall/svelte-apollo/issues/9#issuecomment-646184888 отвечает на очень похожий вопрос и, надеюсь, указывает на подходящий обходной путь для вас:
это происходит с getClient и setClient, потому что это тонкий контекст, который доступен только при инициализации (построении) компонента и не может быть в обработчике событий. см. ответ на проблему регистрации пользователя Svelte с установкой значения хранилища. Скорее всего, происходит то, что вы вызываете его в асинхронном событии su как on:click, onMount, onDestroy, когда оно недоступно. Решением для этого является сохранение вашего клиента как магазина в контексте согласно https://svelte.dev/tutorial/context-api.
В целом это должно выглядеть примерно так:
setClient(writable(apolloClient)); let client getClient().subscribe((_client) => client = _client);