Open stolinski opened 3 years ago
Hey Scott, I've seen this a couple times but in my case it's only happening when called from <script context='module'>
. Is this what you're seeing?
Ignore this, I don't know if I missed it or something changed, I am seeing this everywhere now.
I'm trying to track this down. I did find https://github.com/sveltejs/sapper/issues/592 which might be relevant but I'm not entirely sure.
Clarification on the many uses of "context" between svelte and svelte kit: https://github.com/sveltejs/kit/issues/984
I think an important thing I recognized from these two is that svelte's getContext
/ setContext
will never work with Svelte Kit's load
function cause it's called in the module context. This SHOULD still work in the normal <script>
context though. Why it doesn't is possibly a bug or maybe a part of how SK works.
Update: Scott, I just realize I assumed you are using svelte kit, are you? If not, my bad for hijacking your issue here.
This is vite
not deduping svelte
correctly and using two instances of svelte thus losing track of the current component and context.
One workaround is to alias svelte-apollo
to trick vite into thinking it's part of our code and not a node_module to force it to use our already installed svelte dependency.
Here's the config path in svelte.config.js
const config = {
kit: {
vite: {
resolve: {
alias: {
'svelte-apollo': '/node_modules/svelte-apollo/dist/svelte-apollo.es.js'
},
},
}
}
};
Another trick to make it work well with sveltekit is to create a wrapper component around the layout slot then instantiate the client inside the wrapper component.
Putting this into the vite
config should work too:
optimizeDeps: {
include: [
"@apollo/client/core",
"@apollo/client/cache",
"@apollo/client/link/ws",
"@apollo/client/link/context",
"@apollo/client/link/error",
"@apollo/client/utilities",
],
exclude: ["@apollo/client", "svelte-apollo"],
},
Getting stuck here as well. The workaround from @unlocomqx allowed use of setClient
, but now using mutation
throws the same error.
When I gave up trying to use this library everything started working. My understanding is this lib was designed to be used in svelte components and is incompatible with and possibly even redundant to using the load api. I haven't explored. In my layout component I placed my client into the load API context and accessed it from there on all other pages.
@cschmatzler Yeah the current design only allows making a query or mutation during component initialisation because it's coupled with svelte context (which only allows reading/writing during component initialisation)
The solution is to use lazy queries according to the lib author which is still unimplemented so this is currently definitely unusable https://github.com/timhall/svelte-apollo/issues/53#issuecomment-729357088
FWIW I've written a guide for Sapper integration some time ago, which should still work in SvelteKit. Haven't got the time to do a refresh on it. Note: It uses the Apollo client directly.
I think it's better to just encapsulate the module functions in the client directly I made an attempt here https://github.com/unlocomqx/svelte-apollo/blob/patch-client/src/client.ts
I can now create the client in a separate file and export it, then import it wherever needed
client.query(...);
client.mutate(...);
Much better than dealing with the context because it's very limiting
I get this error. Hope someone has a solution for that:
> node_modules/@apollo/client/react/hooks/useReactiveVar.js:1:36: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
1 │ import { useEffect, useState } from 'react';
╵ ~~~~~~~
> node_modules/@apollo/client/react/context/ApolloProvider.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
2 │ import * as React from 'react';
╵ ~~~~~~~
> node_modules/@apollo/client/react/hooks/useApolloClient.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
2 │ import * as React from 'react';
╵ ~~~~~~~
> node_modules/@apollo/client/react/context/ApolloConsumer.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
2 │ import * as React from 'react';
╵ ~~~~~~~
> node_modules/@apollo/client/react/context/ApolloContext.js:1:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
1 │ import * as React from 'react';
╵ ~~~~~~~
> node_modules/@apollo/client/react/hooks/useSubscription.js:3:68: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
3 │ import { useContext, useState, useRef, useEffect, useReducer } from 'react';
╵ ~~~~~~~
> node_modules/@apollo/client/react/hooks/useMutation.js:2:56: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
2 │ import { useContext, useState, useRef, useEffect } from 'react';
╵ ~~~~~~~
> node_modules/@apollo/client/react/hooks/utils/useBaseQuery.js:3:58: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
3 │ import { useContext, useEffect, useReducer, useRef } from 'react';
╵ ~~~~~~~
error: Could not resolve "react" (mark it as external to exclude it from the bundle)
2 │ import { useEffect, useRef } from "react";
╵ ~~~~~~~
> node_modules/@apollo/client/react/hooks/utils/useDeepMemo.js:1:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
1 │ import { useRef } from 'react';
╵ ~~~~~~~
> Build failed with 10 errors:
node_modules/@apollo/client/react/context/ApolloConsumer.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/context/ApolloContext.js:1:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/context/ApolloProvider.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/hooks/useApolloClient.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/hooks/useMutation.js:2:56: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
...
Error: Build failed with 10 errors:
node_modules/@apollo/client/react/context/ApolloConsumer.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/context/ApolloContext.js:1:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/context/ApolloProvider.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/hooks/useApolloClient.js:2:23: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
node_modules/@apollo/client/react/hooks/useMutation.js:2:56: error: Could not resolve "react" (mark it as external to exclude it from the bundle)
...
at failureErrorWithLog (D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:1478:15)
at D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:1136:28
at runOnEndCallbacks (D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:926:63)
at buildResponseToResult (D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:1134:7)
at D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:1243:14
at D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:614:9
at handleIncomingPacket (D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:711:9)
at Socket.readFromStdout (D:\dev\web\tests\crm\node_modules\esbuild\lib\main.js:581:7)
at Socket.emit (events.js:400:28)
at Socket.emit (domain.js:470:12)
{
"name": "~TODO~",
"version": "0.0.1",
"scripts": {
"dev": "svelte-kit dev",
"build": "svelte-kit build",
"preview": "svelte-kit preview",
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
},
"devDependencies": {
"@sveltejs/kit": "next",
"@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-svelte3": "^3.2.0",
"prettier": "~2.2.1",
"prettier-plugin-svelte": "^2.2.0",
"svelte": "^3.34.0",
"svelte-check": "^2.0.0",
"svelte-preprocess": "^4.0.0",
"tslib": "^2.0.0",
"typescript": "^4.0.0"
},
"type": "module",
"dependencies": {
"@apollo/client": "^3.4.11",
"graphql": "^15.5.3",
"svelte-apollo": "^0.4.0"
}
}
@vladimirdrayling Try adding @apollo/client
to optimizeDeps.exclude
and avoid importing @apollo/client
. Import from @apollo/client/core
instead.
Btw the error originally reported has been fixed in vite-plugin-svelte
now. The library should work ootb, except for the @apollo/client
part (reason). So I'd say this can be closed.
This is not entirely related to the svelte-apollo
package but for those of you that are having trouble setting this up with @apollo/client
, I might have a solution.
Credit goes to Reddit user: u/NoahVersace
, link to post. It's a fix for Prismic but the same principles apply to @apollo/client
.
Here's how I got it working for Apollo: I'm using the svelte static adapter and this works with Apollo on build and dev
// apolloClient.js
import Apollo, * as ApolloScope from '@apollo/client/core/core.cjs.js';
const HttpLink = Apollo?.HttpLink || ApolloScope?.HttpLink;
const ApolloClient = Apollo?.ApolloClient || ApolloScope?.ApolloClient;
const InMemoryCache = Apollo?.InMemoryCache || ApolloScope?.InMemoryCache;
const link = new HttpLink({
uri: `YOUR_GRAPHQL_ENDPOINT`
});
const cache = new InMemoryCache();
const apolloClient = new ApolloClient({
link,
cache
});
export default apolloClient;
From here on you may use the client as you will.
For instance, I would like to wrap it around my app so I'm calling it at __layout.svelte
:
// __layout.svelte
<script context="module">
import apolloClient from '$lib/apolloClient';
/**
* @type {import('@sveltejs/kit').Load}
*/
export async function load({ stuff }) {
const client = apolloClient;
return {
stuff: {
...stuff,
client
}
};
}
</script>
<slot />
You don't need the svelte-apollo
package in order for this to work.
Lastly, you may query data in components/pages like so:
// someDataComponent.js
<script context="module">
export async function load({ stuf }) {
return {
props: {
someData: await stuff.client.query({ query: SOME_DATA_QUERY })
}
};
}
</script>
<script>
import { SOME_DATA_QUERY } from '$lib/data-queries';
export let someData
</script>
<section>
<h1>{someData.heading}</h1>
<p>{someData.paragraph}</p>
</section>
That's it!
Hope this helps!
Another workaround not mentioned here is to add export map to @apollo/client package directly:
For me it was
"exports":{
".": {
"node":"./main.cjs", "default":"./index.js"
},
"./cache": {
"node":"./cache/cache.cjs","default":"./cache/index.js"
},
"./core": {
"node":"./core/core.cjs","default":"./core/index.js"
},
"./link/schema": {
"node":"./link/schema/schema.cjs","default":"./link/schema/index.js"
},
"./link/context": {
"node":"./link/context/context.cjs","default":"./link/context/index.js"
},
"./link/http": {
"node":"./link/http/http.cjs","default":"./link/http/index.js"
},
"./link/ws": {
"node":"./link/ws/ws.cjs","default":"./link/ws/index.js"
}
}
Make sure to delete all previous "solutions" and workaround as they would conflict. Track progress on issue here: https://github.com/apollographql/apollo-client/issues/8218
UPDATE: I also found out that rollup bundling crashes with
> [vite]: Rollup failed to resolve import "react" from "node_modules/.pnpm/@apollo+client@3.6.6_vc5lvukfq44ubwvv43scizgjye/node_modules/@apollo/client/react/context/ApolloConsumer.js".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
if you don't have compilerOptions.preserveValueImports
set to false
in your tsconfig
@tmrp Hmm, did u exclude anything? I tried your answer but I'm still getting "Could not resolve 'react' (mark it as external to exclude it from the bundle)" with following:
import Apollo, * as ApolloScope from '@apollo/client/core/core.cjs';
const HttpLink = Apollo?.HttpLink || ApolloScope?.HttpLink;
const ApolloClient = Apollo?.ApolloClient || ApolloScope?.ApolloClient;
const InMemoryCache = Apollo?.InMemoryCache || ApolloScope?.InMemoryCache;
const link = new HttpLink({
uri: process.env.VITE_GRAPHQL_ENDPOINT
});
const cache = new InMemoryCache();
const apolloClient = new ApolloClient({
link,
cache
});
export default apolloClient;
update: tried vite.optimizeDeps solution. 'react' problem was gone but got a new one with
@tobiasgranlof updates to Svelte (presumably Vite) have prevented the method I mentioned from working.
I started a new SvelteKit project and got a similar error. It took me a while to rack my brain around it, but I got it working now.
To get it to work now you have to slightly restructure apolloClient.js
like so:
import { HttpLink, InMemoryCache, ApolloClient } from '@apollo/client/core';
import { environmentVariables } from './environment-variables';
const link = new HttpLink({
uri: environmentVariables.starWarsApi
});
const cache = new InMemoryCache();
const apolloClient = new ApolloClient({
link,
cache
});
export default apolloClient;
And you would have to add the following to your svelte.config.js
file:
kit: {
...
vite: {
ssr: {
noExternal: ['@apollo/client']
}
}
}
I made a working demo project you may checkout here
I hope this helps!
Your example works but I guess because its plain js. Im using typescript and with the same configuration I do get the "react" problem when building. Even with same vite configuration as in your example. I tried both @apollo/client version 3.4.16 and latest. Same error.
this is my apollo-client.ts:
import { HttpLink, InMemoryCache, ApolloClient } from '@apollo/client/core';
import { environmentVariables } from '$lib/environment-variables';
const link = new HttpLink({
uri: environmentVariables.graphqlApi.toString()
});
const cache = new InMemoryCache();
const apolloClient = new ApolloClient({
link,
cache
});
export default apolloClient;
@tobiasgranlof, I think you made a mistake while trying to type check the environment variable here:
const link = new HttpLink({
// you would want to give uri a string type here and not transform it to a string (because it's already a string)
uri: environmentVariables.graphqlApi.toString()
// replace the above with
uri: environmentVariables.graphqlApi as string
});
To be safe, I changed my svelte.config.js
to:
import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: preprocess(),
kit: {
adapter: adapter(),
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
vite: {
optimizeDeps: {
exclude: ['@apollo/client']
},
ssr: {
noExternal: ['@apollo/client']
}
}
}
};
export default config;
I made a TypeScript version, and you may check out the repo here here
I hope this helps!
Cheers!
Yea, that worked. Not a fan of this setup but if it works, it works 😊 The only thing that is unclear, even tho we pass a cache to the apollo client is that it cant be reached server side.
const cacheResponse = apolloClient.readQuery({ query: getCarsQuery });
This code is exposed to another .ts file and this will always be null server side, since cache table only is available client side.
update: Tested with the client directly in the index.svelte file, my be server still gets request even with data in the cache. Tested with your ts example as well. Its calling the api constantly without checking the cache. Which means the cache is unecessary and useless to have.
it looks like the library was updated 10 days ago (and there is a new release), it now includes an example with sveltekit. however just testing, I get the following error.
Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/Users/raphael/dev/nyt/node_modules/.pnpm/svelte-apo
llo@0.5.0_0797cffbf2a19052134926e8d6fad18a/node_modules/@apollo/client/core' is not supported resolving ES
modules imported from /Users/raphael/dev/nyt/node_modules/.pnpm/svelte-apollo@0.5.0_0797cffbf2a1905213492
6e8d6fad18a/node_modules/svelte-apollo/dist/svelte-apollo.js
Did you mean to import @apollo+client@3.5.9_graphql@16.3.0/node_modules/@apollo/client/core/core.cjs?
at new NodeError (internal/errors.js:322:7)
at finalizeResolution (internal/modules/esm/resolve.js:314:17)
at moduleResolve (internal/modules/esm/resolve.js:776:10)
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:887:11)
at Loader.resolve (internal/modules/esm/loader.js:89:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:76:40)
at link (internal/modules/esm/module_job.js:75:36)
in case anyone else has seen and experienced this.
@happysalada I got that as well (also reported here: https://github.com/timhall/svelte-apollo/issues/119)
Adding this to my svelte.config.js
worked:
optimizeDeps: {
exclude: ['@apollo/client', 'svelte-apollo'],
},
ssr: {
noExternal: ['@apollo/client', 'svelte-apollo'],
},
under kit.vite
ref: https://github.com/timhall/svelte-apollo/issues/97#issuecomment-939058992
@tmrp Thanks, it worked!
In our layout.svelte Produces [HMR][Svelte] Unrecoverable error in <layout>: next update will trigger a full reload logError @ proxy.js:15 Proxy<__layout> @ proxy.js:372 create_fragment @ root.svelte? [sm]:36 init @ index.mjs?v=e94d9004:1500 Root @ root.svelte? [sm]:16 createProxiedComponent @ svelte-hooks.js:245 ProxyComponent @ proxy.js:241 Proxy @ proxy.js:341
_init @ start.js:646
start @ start.js:530
async function (async)
start @ start.js:483
start @ start.js:1096
(anonymous) @ (index):39
Removing setClient(client) fixes error, breaks apollo (obviously). Any thoughts?