diff --git a/packages/core/config/webpack.common.js b/packages/core/config/webpack.common.js
index e5476c69d47b..9ce17b462a30 100644
--- a/packages/core/config/webpack.common.js
+++ b/packages/core/config/webpack.common.js
@@ -228,7 +228,7 @@ module.exports = (webpackEnv) => {
*/
app:
redwoodPaths.web.index ||
- require.resolve('@redwoodjs/web/dist/entry/index.js'),
+ require.resolve('@redwoodjs/web/webpackEntry'),
},
resolve: {
extensions: ['.wasm', '.mjs', '.js', '.jsx', '.ts', '.tsx', '.json'],
diff --git a/packages/internal/src/generate/typeDefinitions.ts b/packages/internal/src/generate/typeDefinitions.ts
index 05224ea25a29..a77f8d1a6992 100644
--- a/packages/internal/src/generate/typeDefinitions.ts
+++ b/packages/internal/src/generate/typeDefinitions.ts
@@ -62,6 +62,7 @@ export const generateTypeDefs = async () => {
...generateTypeDefScenarios(),
...generateTypeDefTestMocks(),
...generateStubStorybookTypes(),
+ ...generateViteClientTypesDirective(),
...gqlApiTypeDefFiles,
...gqlWebTypeDefFiles,
],
@@ -378,6 +379,22 @@ export const generateTypeDefGlobImports = () => {
export const generateTypeDefGlobalContext = () => {
return writeTypeDefIncludeFile('api-globalContext.d.ts.template')
}
+/**
+ * Typescript does not preserve triple slash directives when outputting js or d.ts files.
+ * This is a work around so that *.svg, *.png, etc. imports have types.
+ */
+export const generateViteClientTypesDirective = () => {
+ const viteClientDirective = `/// `
+ const redwoodProjectPaths = getPaths()
+
+ const viteClientDirectivePath = path.join(
+ redwoodProjectPaths.generated.types.includes,
+ 'web-vite-client.d.ts',
+ )
+ fs.writeFileSync(viteClientDirectivePath, viteClientDirective)
+
+ return [viteClientDirectivePath]
+}
function generateStubStorybookTypes() {
const stubStorybookTypesFileContent = `\
diff --git a/packages/prerender/src/graphql/graphql.ts b/packages/prerender/src/graphql/graphql.ts
index 6350b81b3ffe..985efb2fafe0 100644
--- a/packages/prerender/src/graphql/graphql.ts
+++ b/packages/prerender/src/graphql/graphql.ts
@@ -5,7 +5,7 @@ import { print } from 'graphql'
import { getConfig, getPaths } from '@redwoodjs/project-config'
// @MARK: have to do this, otherwise rwjs/web is loaded before shims
-import { getOperationName } from '@redwoodjs/web/dist/graphql'
+import { getOperationName } from '@redwoodjs/web/dist/graphql.js'
import { GqlHandlerImportError } from '../errors'
diff --git a/packages/testing/config/jest/web/jest-preset.js b/packages/testing/config/jest/web/jest-preset.js
index b2ad05105777..e2ffc5d58349 100644
--- a/packages/testing/config/jest/web/jest-preset.js
+++ b/packages/testing/config/jest/web/jest-preset.js
@@ -54,7 +54,7 @@ module.exports = {
NODE_MODULES_PATH,
'@redwoodjs/testing/dist/web/MockRouter.js',
),
- '^@redwoodjs/web$': path.join(NODE_MODULES_PATH, '@redwoodjs/web'),
+ '^@redwoodjs/web$': path.join(NODE_MODULES_PATH, '@redwoodjs/web/dist/cjs'),
// This allows us to mock `createAuthentication` which is used by auth
// clients, which in turn lets us mock `useAuth` in tests
diff --git a/packages/testing/config/storybook/main.js b/packages/testing/config/storybook/main.js
index a03ba6be846c..83d6b013b015 100644
--- a/packages/testing/config/storybook/main.js
+++ b/packages/testing/config/storybook/main.js
@@ -55,6 +55,14 @@ const baseConfig = {
sbConfig.resolve.alias['@redwoodjs/auth$'] = require.resolve(
'@redwoodjs/testing/dist/web/mockAuth.js',
)
+
+ // Force loading the ESM version of ApolloProvider in Storybook
+ // I'm unsure why storybook-webpack does not work with the CJS version
+ // All other cases are fine with the CJS import.
+ sbConfig.resolve.alias['@redwoodjs/web/apollo$'] = require.resolve(
+ '@redwoodjs/web/forceEsmApollo',
+ )
+
sbConfig.resolve.alias['~__REDWOOD__USER_ROUTES_FOR_MOCK'] =
redwoodProjectPaths.web.routes
sbConfig.resolve.alias['~__REDWOOD__USER_WEB_SRC'] =
diff --git a/packages/vite/package.json b/packages/vite/package.json
index 9f7d0e5f0d9d..53d8fa9d503f 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -94,6 +94,7 @@
"react-server-dom-webpack": "19.0.0-beta-04b058868c-20240508",
"vite": "5.3.1",
"vite-plugin-cjs-interop": "2.1.1",
+ "vite-plugin-node-polyfills": "^0.22.0",
"yargs-parser": "21.1.1"
},
"devDependencies": {
diff --git a/packages/vite/src/devFeServer.ts b/packages/vite/src/devFeServer.ts
index a142135588fe..30644f3e9f8e 100644
--- a/packages/vite/src/devFeServer.ts
+++ b/packages/vite/src/devFeServer.ts
@@ -67,7 +67,13 @@ async function createServer() {
configFile: rwPaths.web.viteConfig,
plugins: [
cjsInterop({
- dependencies: ['@redwoodjs/**'],
+ dependencies: [
+ // Skip ESM modules: rwjs/auth, rwjs/web
+ '@redwoodjs/forms',
+ '@redwoodjs/prerender/*',
+ '@redwoodjs/router',
+ '@redwoodjs/auth-*',
+ ],
}),
rscEnabled && rscRoutesAutoLoader(),
],
diff --git a/packages/vite/src/index.ts b/packages/vite/src/index.ts
index de1663be514a..2d128913826e 100644
--- a/packages/vite/src/index.ts
+++ b/packages/vite/src/index.ts
@@ -4,6 +4,7 @@ import path from 'path'
import react from '@vitejs/plugin-react'
import type { PluginOption } from 'vite'
import { normalizePath } from 'vite'
+import { nodePolyfills } from 'vite-plugin-node-polyfills'
import { getWebSideDefaultBabelConfig } from '@redwoodjs/babel-config'
import { getConfig, getPaths } from '@redwoodjs/project-config'
@@ -156,5 +157,16 @@ export default function redwoodPluginVite(): PluginOption[] {
}),
},
}),
+ // Only include the Buffer polyfill for non-rsc dev, for DevFatalErrorPage
+ // Including the polyfill plugin in any form in RSC breaks
+ !rscEnabled && {
+ ...nodePolyfills({
+ include: ['buffer'],
+ globals: {
+ Buffer: true,
+ },
+ }),
+ apply: 'serve',
+ },
]
}
diff --git a/packages/vite/src/rsc/rscBuildForSsr.ts b/packages/vite/src/rsc/rscBuildForSsr.ts
index 1f97b9aebcea..7506955100a0 100644
--- a/packages/vite/src/rsc/rscBuildForSsr.ts
+++ b/packages/vite/src/rsc/rscBuildForSsr.ts
@@ -61,7 +61,16 @@ export async function rscBuildForSsr({
],
},
plugins: [
- cjsInterop({ dependencies: ['@redwoodjs/**'] }),
+ cjsInterop({
+ dependencies: [
+ // Skip ESM modules: rwjs/auth, rwjs/web
+ '@redwoodjs/forms',
+ '@redwoodjs/prerender/*',
+ '@redwoodjs/router',
+ '@redwoodjs/router/*',
+ '@redwoodjs/auth-*',
+ ],
+ }),
rscRoutesAutoLoader(),
rscSsrRouterImport(),
],
@@ -84,10 +93,11 @@ export async function rscBuildForSsr({
// for the client-only components. They get loaded once the page is
// rendered
...clientEntryFiles,
+ // These import redirections are so that we don't bundle multiple versions of react
__rwjs__react: 'react',
__rwjs__location: '@redwoodjs/router/dist/location',
__rwjs__server_auth_provider: '@redwoodjs/auth/ServerAuthProvider',
- __rwjs__server_inject: '@redwoodjs/web/dist/components/ServerInject',
+ __rwjs__server_inject: '@redwoodjs/web/serverInject',
'__rwjs__rsdw-client': 'react-server-dom-webpack/client.edge',
// TODO (RSC): add __rwjs__ prefix to the entry below
'rd-server': 'react-dom/server.edge',
diff --git a/packages/vite/src/streaming/buildForStreamingServer.ts b/packages/vite/src/streaming/buildForStreamingServer.ts
index 38a8d1539990..56f644037c10 100644
--- a/packages/vite/src/streaming/buildForStreamingServer.ts
+++ b/packages/vite/src/streaming/buildForStreamingServer.ts
@@ -19,7 +19,13 @@ export async function buildForStreamingServer({
configFile: rwPaths.web.viteConfig,
plugins: [
cjsInterop({
- dependencies: ['@redwoodjs/**'],
+ dependencies: [
+ // Skip ESM modules: rwjs/auth, rwjs/web
+ '@redwoodjs/forms',
+ '@redwoodjs/prerender/*',
+ '@redwoodjs/router',
+ '@redwoodjs/auth-*',
+ ],
}),
],
build: {
diff --git a/packages/vite/src/streaming/streamHelpers.ts b/packages/vite/src/streaming/streamHelpers.ts
index 27002f0c9446..68b18f8ad141 100644
--- a/packages/vite/src/streaming/streamHelpers.ts
+++ b/packages/vite/src/streaming/streamHelpers.ts
@@ -102,13 +102,16 @@ export async function reactRenderToStreamResponse(
const { createElement }: React = rscEnabled
? await importModule('__rwjs__react')
: await import('react')
+
const {
createInjector,
ServerHtmlProvider,
ServerInjectedHtml,
}: ServerInjectType = rscEnabled
? await importModule('__rwjs__server_inject')
- : await import('@redwoodjs/web/dist/components/ServerInject.js')
+ : // @ts-expect-error this is defined in packages/web/package.json exports.
+ // This package just doesn't have moduleResolution configured
+ await import('@redwoodjs/web/serverInject')
const { renderToString }: RDServerType = rscEnabled
? await importModule('rd-server')
: await import('react-dom/server')
@@ -322,7 +325,8 @@ export async function importModule(
} else if (mod === '__rwjs__server_auth_provider') {
return await import(ServerAuthProviderPath)
} else if (mod === '__rwjs__server_inject') {
- return (await import(ServerInjectPath)).default
+ // Don't need default because rwjs/web is now ESM
+ return await import(ServerInjectPath)
}
throw new Error('Unknown module ' + mod)
diff --git a/packages/web/apollo/index.js b/packages/web/apollo/index.js
index 4cd7b24834fc..4f02affbabbb 100644
--- a/packages/web/apollo/index.js
+++ b/packages/web/apollo/index.js
@@ -1,2 +1,2 @@
/* eslint-env es6, commonjs */
-module.exports = require('../dist/apollo')
+module.exports = require('../dist/cjs/apollo/index.js')
diff --git a/packages/web/build.mts b/packages/web/build.mts
index 942e976fa81b..ad8cc749bae7 100644
--- a/packages/web/build.mts
+++ b/packages/web/build.mts
@@ -1,37 +1,41 @@
-// import { writeFileSync } from 'node:fs'
-
import {
build,
defaultBuildOptions,
defaultIgnorePatterns,
} from '@redwoodjs/framework-tools'
+import { writeFileSync } from 'node:fs'
// CJS build
+/**
+ * Notes:
+ * - we don't build the webpack entry point in CJS, because it produces a double wrapped module
+ * instead we use the ESM version (see ./webpackEntry in package.json). The double wrapping happens
+ * when you set type: module in package.json, and occurs on the App & Routes import from the project.
+ * - we build bins in CJS, until projects fully switch to ESM (or we produce .mts files) this is probably
+ * the better option
+ */
await build({
entryPointOptions: {
- ignore: [...defaultIgnorePatterns],
+ ignore: [...defaultIgnorePatterns, 'src/__typetests__/**', 'src/entry/**'],
},
buildOptions: {
...defaultBuildOptions,
- // ⭐ No special tsconfig here
- // outdir: 'dist/cjs', DONT DO THIS JUST YET
- outdir: 'dist',
+ // ⭐ No special build tsconfig in this package
+ outdir: 'dist/cjs',
packages: 'external',
},
})
-/** THIS IS IN PART 2 ~ making this a dual module
-Will enable in follow up PR
-
-ESM build
+// ESM build
await build({
entryPointOptions: {
- ignore: [...defaultIgnorePatterns, 'src/entry/**'],
+ // @NOTE: building the cjs bins only...
+ // I haven't tried esm bins yet...
+ ignore: [...defaultIgnorePatterns, 'src/bins/**', 'src/__typetests__/**'],
},
buildOptions: {
...defaultBuildOptions,
- // ⭐ No special tsconfig here
- // tsconfig: 'tsconfig.build.json',
+ // ⭐ No special build tsconfig in this package
format: 'esm',
packages: 'external',
},
@@ -44,5 +48,3 @@ writeFileSync('dist/cjs/package.json', JSON.stringify({ type: 'commonjs' }))
// Place a package.json file with `type: module` in the dist/esm folder so that
// all .js files are treated as ES Module files.
writeFileSync('dist/package.json', JSON.stringify({ type: 'module' }))
-
-*/
diff --git a/packages/web/package.json b/packages/web/package.json
index 4924e2502de5..a65b2e5168b1 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -1,6 +1,7 @@
{
"name": "@redwoodjs/web",
"version": "7.0.0",
+ "type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com/redwoodjs/redwood.git",
@@ -10,14 +11,66 @@
"main": "./dist/index.js",
"types": "dist/index.d.ts",
"bin": {
- "cross-env": "./dist/bins/cross-env.js",
- "msw": "./dist/bins/msw.js",
- "redwood": "./dist/bins/redwood.js",
- "rw": "./dist/bins/redwood.js",
- "rwfw": "./dist/bins/rwfw.js",
- "storybook": "./dist/bins/storybook.js",
- "tsc": "./dist/bins/tsc.js",
- "webpack": "./dist/bins/webpack.js"
+ "cross-env": "./dist/cjs/bins/cross-env.js",
+ "msw": "./dist/cjs/bins/msw.js",
+ "redwood": "./dist/cjs/bins/redwood.js",
+ "rw": "./dist/cjs/bins/redwood.js",
+ "rwfw": "./dist/cjs/bins/rwfw.js",
+ "storybook": "./dist/cjs/bins/storybook.js",
+ "tsc": "./dist/cjs/bins/tsc.js",
+ "webpack": "./dist/cjs/bins/webpack.js"
+ },
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/index.d.ts",
+ "default": "./dist/index.js"
+ },
+ "require": {
+ "types": "./dist/cjs/index.d.ts",
+ "default": "./dist/cjs/index.js"
+ }
+ },
+ "./serverInject": {
+ "require": "./dist/cjs/components/ServerInject.js",
+ "import": "./dist/components/ServerInject.js",
+ "types": "./dist/components/ServerInject.d.ts",
+ "default": "./dist/components/ServerInject.js"
+ },
+ "./dist/components/*": {
+ "require": "./dist/cjs/components/*.js",
+ "import": "./dist/components/*.js"
+ },
+ "./dist/apollo/suspense": {
+ "require": "./dist/cjs/apollo/suspense.js",
+ "import": "./dist/apollo/suspense.js"
+ },
+ "./dist/apollo/sseLink": {
+ "require": "./dist/cjs/apollo/sseLink.js",
+ "import": "./dist/apollo/sseLink.js"
+ },
+ "./dist/graphql.js": {
+ "require": "./dist/cjs/graphql.js",
+ "import": "./dist/graphql.js"
+ },
+ "./webpackEntry": {
+ "default": "./dist/entry/index.js"
+ },
+ "./toast": {
+ "require": "./dist/cjs/toast/index.js",
+ "import": "./dist/toast/index.js",
+ "types": "./dist/toast/index.d.ts"
+ },
+ "./apollo": {
+ "require": "./dist/cjs/apollo/index.js",
+ "import": "./dist/apollo/index.js",
+ "types": "./dist/apollo/index.d.ts",
+ "default": "./dist/cjs/apollo/index.js"
+ },
+ "./forceEsmApollo": {
+ "require": "./dist/apollo/index.js",
+ "import": "./dist/apollo/index.js"
+ }
},
"files": [
"dist",
@@ -28,7 +81,7 @@
"scripts": {
"build": "tsx ./build.mts && yarn build:types",
"build:pack": "yarn pack -o redwoodjs-web.tgz",
- "build:types": "tsc --build --verbose tsconfig.json",
+ "build:types": "tsc --build --verbose ./tsconfig.json ./tsconfig.types-cjs.json",
"build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"",
"prepublishOnly": "NODE_ENV=production yarn build",
"test": "vitest run",
diff --git a/packages/web/src/__typetests__/cellProps.test.tsx b/packages/web/src/__typetests__/cellProps.test.tsx
index 6797e42bbcf6..1ff1ecf35ff7 100644
--- a/packages/web/src/__typetests__/cellProps.test.tsx
+++ b/packages/web/src/__typetests__/cellProps.test.tsx
@@ -1,7 +1,7 @@
// These are normally auto-imported by babel
import React from 'react'
-import gql from 'graphql-tag'
+import { gql } from 'graphql-tag'
import { describe, expect, test } from 'tstyche'
import type { CellProps, CellSuccessProps } from '@redwoodjs/web'
diff --git a/packages/web/src/apollo/fragmentRegistry.ts b/packages/web/src/apollo/fragmentRegistry.ts
index ba26c2b387d5..40867e2c8aa4 100644
--- a/packages/web/src/apollo/fragmentRegistry.ts
+++ b/packages/web/src/apollo/fragmentRegistry.ts
@@ -1,8 +1,10 @@
import * as apolloClient from '@apollo/client'
import type { UseFragmentResult } from '@apollo/client'
-import type { FragmentRegistryAPI } from '@apollo/client/cache'
-import { createFragmentRegistry } from '@apollo/client/cache'
-import { getFragmentDefinitions } from '@apollo/client/utilities'
+// @ts-expect-error Force import cjs module
+import { createFragmentRegistry } from '@apollo/client/cache/cache.cjs'
+import type { FragmentRegistryAPI } from '@apollo/client/cache/index.js'
+// @ts-expect-error Force import cjs module
+import { getFragmentDefinitions } from '@apollo/client/utilities/utilities.cjs'
import type { DocumentNode } from 'graphql'
export type FragmentIdentifier = string | number
diff --git a/packages/web/src/apollo/index.tsx b/packages/web/src/apollo/index.tsx
index 341b24875537..7942fa25994e 100644
--- a/packages/web/src/apollo/index.tsx
+++ b/packages/web/src/apollo/index.tsx
@@ -4,33 +4,42 @@ import type {
ApolloClientOptions,
setLogVerbosity,
ApolloCache,
+ InMemoryCacheConfig,
+ HttpOptions,
+ DocumentNode,
} from '@apollo/client'
-import * as apolloClient from '@apollo/client'
-import { setContext } from '@apollo/client/link/context'
-import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries'
-import { getMainDefinition } from '@apollo/client/utilities'
-import { fetch as crossFetch } from '@whatwg-node/fetch'
-import { print } from 'graphql/language/printer'
-
-// Note: Importing directly from `apollo/client` doesn't work properly in Storybook.
-const {
+import {
ApolloProvider,
ApolloClient,
ApolloLink,
- HttpLink,
InMemoryCache,
+ split,
+} from '@apollo/client'
+// @ts-expect-error Force import cjs module
+import { setLogVerbosity as apolloSetLogVerbosity } from '@apollo/client/core/core.cjs'
+// @ts-expect-error Force import cjs module
+import { setContext } from '@apollo/client/link/context/context.cjs'
+// @ts-expect-error Force import cjs module
+import { HttpLink } from '@apollo/client/link/http/http.cjs'
+// @ts-expect-error Force import cjs module
+import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries/persisted-queries.cjs'
+import {
useQuery,
useMutation,
useSubscription,
useBackgroundQuery,
useReadQuery,
useSuspenseQuery,
- setLogVerbosity: apolloSetLogVerbosity,
-} = apolloClient
+ // @ts-expect-error Force import cjs module
+} from '@apollo/client/react/hooks/hooks.cjs'
+// @ts-expect-error Force import cjs module
+import { getMainDefinition } from '@apollo/client/utilities/utilities.cjs'
+import { fetch as crossFetch } from '@whatwg-node/fetch'
+import { print } from 'graphql/language/printer.js'
import type { UseAuth } from '@redwoodjs/auth'
import { useNoAuth } from '@redwoodjs/auth'
-import './typeOverride'
+import './typeOverride.js'
import {
FetchConfigProvider,
@@ -43,8 +52,10 @@ import {
registerFragment,
registerFragments,
} from './fragmentRegistry.js'
-import { SSELink } from './sseLink.js'
+import * as SSELinkExports from './sseLink.js'
import { useCache } from './useCache.js'
+// Not sure why we need to import it this way for legacy builds to work
+const { SSELink } = SSELinkExports
export type {
CacheKey,
@@ -56,7 +67,7 @@ export { useCache }
export { fragmentRegistry, registerFragment, registerFragments }
-export type ApolloClientCacheConfig = apolloClient.InMemoryCacheConfig
+export type ApolloClientCacheConfig = InMemoryCacheConfig
export type RedwoodApolloLinkName =
| 'withToken'
@@ -66,7 +77,7 @@ export type RedwoodApolloLinkName =
export type RedwoodApolloLink<
Name extends RedwoodApolloLinkName,
- Link extends apolloClient.ApolloLink = apolloClient.ApolloLink,
+ Link extends ApolloLink = ApolloLink,
> = {
name: Name
link: Link
@@ -76,15 +87,10 @@ export type RedwoodApolloLinks = [
RedwoodApolloLink<'withToken'>,
RedwoodApolloLink<'authMiddleware'>,
RedwoodApolloLink<'updateDataApolloLink'>,
- RedwoodApolloLink<
- 'httpLink',
- apolloClient.ApolloLink | apolloClient.HttpLink
- >,
+ RedwoodApolloLink<'httpLink', ApolloLink | HttpLink>,
]
-export type RedwoodApolloLinkFactory = (
- links: RedwoodApolloLinks,
-) => apolloClient.ApolloLink
+export type RedwoodApolloLinkFactory = (links: RedwoodApolloLinks) => ApolloLink
export type GraphQLClientConfigProp = Omit<
ApolloClientOptions,
@@ -108,7 +114,7 @@ export type GraphQLClientConfigProp = Omit<
* }}>
* ```
*/
- httpLinkConfig?: apolloClient.HttpOptions
+ httpLinkConfig?: HttpOptions
/**
* Extend or overwrite `RedwoodApolloProvider`'s Apollo Link.
*
@@ -132,7 +138,7 @@ export type GraphQLClientConfigProp = Omit<
* - your function should return a single link (e.g., using `ApolloLink.from`; see https://www.apollographql.com/docs/react/api/link/introduction/#additive-composition)
* - the `HttpLink` should come last (https://www.apollographql.com/docs/react/api/link/introduction/#the-terminating-link)
*/
- link?: apolloClient.ApolloLink | RedwoodApolloLinkFactory
+ link?: ApolloLink | RedwoodApolloLinkFactory
}
const ApolloProviderWithFetchConfig: React.FunctionComponent<{
@@ -231,7 +237,7 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{
// is subscription it needs to use the SSELink (server sent events link).
const httpOrSSELink =
typeof SSELink !== 'undefined'
- ? apolloClient.split(
+ ? split(
({ query }) => {
const definition = getMainDefinition(query)
@@ -240,6 +246,7 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{
definition.operation === 'subscription'
)
},
+ // @ts-expect-error Due to CJS imports
new SSELink({
url: uri,
auth: { authProviderType, tokenFn: getToken },
@@ -259,14 +266,14 @@ const ApolloProviderWithFetchConfig: React.FunctionComponent<{
*
* See https://www.apollographql.com/docs/react/api/link/persisted-queries/
*/
- interface DocumentNodeWithMeta extends apolloClient.DocumentNode {
+ interface DocumentNodeWithMeta extends DocumentNode {
__meta__?: {
hash: string
}
}
// Check if the query made includes the hash, and if so then make the request with the persisted query link
- const terminatingLink = apolloClient.split(
+ const terminatingLink = split(
({ query }) => {
const documentQuery = query as DocumentNodeWithMeta
return documentQuery?.['__meta__']?.['hash'] !== undefined
@@ -348,7 +355,7 @@ class ErrorBoundary extends React.Component {
export const RedwoodApolloProvider: React.FunctionComponent<{
graphQLClientConfig?: GraphQLClientConfigProp
- fragments?: apolloClient.DocumentNode[]
+ fragments?: DocumentNode[]
useAuth?: UseAuth
logLevel?: ReturnType
children: React.ReactNode
diff --git a/packages/web/src/apollo/links.ts b/packages/web/src/apollo/links.ts
index 6394b23df832..aace390c188e 100644
--- a/packages/web/src/apollo/links.ts
+++ b/packages/web/src/apollo/links.ts
@@ -1,7 +1,9 @@
import type { HttpOptions, Operation } from '@apollo/client'
-import { ApolloLink, HttpLink, Observable } from '@apollo/client'
-import { setContext } from '@apollo/client/link/context'
-import { print } from 'graphql/language/printer'
+import { Observable } from '@apollo/client/core/index.js'
+import { setContext } from '@apollo/client/link/context/index.js'
+import { ApolloLink } from '@apollo/client/link/core/index.js'
+import { HttpLink } from '@apollo/client/link/http/index.js'
+import { print } from 'graphql/language/printer.js'
export function createHttpLink(
uri: string,
diff --git a/packages/web/src/apollo/sseLink.ts b/packages/web/src/apollo/sseLink.ts
index 24e28d614443..307c98090a14 100644
--- a/packages/web/src/apollo/sseLink.ts
+++ b/packages/web/src/apollo/sseLink.ts
@@ -1,8 +1,11 @@
import type { HttpOptions } from '@apollo/client'
import type { Operation, FetchResult } from '@apollo/client/core'
-import { ApolloLink, Observable } from '@apollo/client/core'
+// @ts-expect-error Force import cjs module
+import { ApolloLink } from '@apollo/client/link/core/core.cjs'
+// @ts-expect-error Force import cjs module
+import { Observable } from '@apollo/client/utilities/utilities.cjs'
import { print } from 'graphql'
-import type { ClientOptions, Client } from 'graphql-sse'
+import type { ClientOptions, Client, Sink } from 'graphql-sse'
import { createClient } from 'graphql-sse'
interface SSELinkOptions extends Partial {
url: string
@@ -60,7 +63,7 @@ const mapReferrerPolicyHeader = (
/**
* GraphQL over Server-Sent Events (SSE) spec link for Apollo Client
*/
-export class SSELink extends ApolloLink {
+class SSELink extends ApolloLink {
private client: Client
constructor(options: SSELinkOptions) {
@@ -92,7 +95,7 @@ export class SSELink extends ApolloLink {
}
public request(operation: Operation): Observable {
- return new Observable((sink) => {
+ return new Observable((sink: Sink) => {
return this.client.subscribe(
{ ...operation, query: print(operation.query) },
{
@@ -104,3 +107,5 @@ export class SSELink extends ApolloLink {
})
}
}
+
+export { SSELink }
diff --git a/packages/web/src/apollo/suspense.tsx b/packages/web/src/apollo/suspense.tsx
index 873fb99acfea..b111eaff5b07 100644
--- a/packages/web/src/apollo/suspense.tsx
+++ b/packages/web/src/apollo/suspense.tsx
@@ -6,7 +6,7 @@
* Done this way, to avoid making changes breaking on main, due to the experimental-nextjs import
* Eventually we will have one ApolloProvider, not multiple.
*/
-
+'use client'
import React, { useContext } from 'react'
import type {
@@ -17,15 +17,15 @@ import type {
InMemoryCacheConfig,
setLogVerbosity,
} from '@apollo/client'
+import { setLogVerbosity as apolloSetLogVerbosity } from '@apollo/client/core/index.js'
import {
- setLogVerbosity as apolloSetLogVerbosity,
useMutation,
useSubscription,
useBackgroundQuery,
useQuery,
useReadQuery,
useSuspenseQuery,
-} from '@apollo/client'
+} from '@apollo/client/react/hooks/index.js'
import {
ApolloClient,
InMemoryCache,
@@ -36,28 +36,28 @@ import { buildManualDataTransport } from '@apollo/client-react-streaming/manual-
import type { UseAuth } from '@redwoodjs/auth'
import { useNoAuth } from '@redwoodjs/auth'
import { ServerAuthContext } from '@redwoodjs/auth/dist/AuthProvider/ServerAuthProvider.js'
-import './typeOverride'
+import './typeOverride.js'
import {
FetchConfigProvider,
useFetchConfig,
-} from '../components/FetchConfigProvider'
+} from '../components/FetchConfigProvider.js'
import { GraphQLHooksProvider } from '../components/GraphQLHooksProvider.js'
-import { ServerHtmlContext } from '../components/ServerInject'
+import { ServerHtmlContext } from '../components/ServerInject.js'
import type {
RedwoodApolloLink,
RedwoodApolloLinkFactory,
RedwoodApolloLinkName,
RedwoodApolloLinks,
-} from './links'
+} from './links.js'
import {
createAuthApolloLink,
createFinalLink,
createHttpLink,
createTokenLink,
createUpdateDataLink,
-} from './links'
+} from './links.js'
export type ApolloClientCacheConfig = InMemoryCacheConfig
diff --git a/packages/web/src/apollo/useCache.ts b/packages/web/src/apollo/useCache.ts
index 92dcb70d18c1..9f29dec1168f 100644
--- a/packages/web/src/apollo/useCache.ts
+++ b/packages/web/src/apollo/useCache.ts
@@ -1,7 +1,8 @@
import type { ApolloCache, Reference, StoreObject } from '@apollo/client'
-import { useApolloClient } from '@apollo/client'
-import type { NormalizedCacheObject } from '@apollo/client/cache/inmemory/types'
+import type { NormalizedCacheObject } from '@apollo/client/cache/inmemory/types.js'
import type { ApolloQueryResult } from '@apollo/client/core'
+// @ts-expect-error Force import cjs module
+import { useApolloClient } from '@apollo/client/react/hooks/hooks.cjs'
type useCacheType = {
cache: ApolloCache