Skip to content

Commit b977602

Browse files
authoredSep 4, 2024··
fix: keep graphql import as require in cjs (#2258)
1 parent 0bc6b3f commit b977602

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import fs from 'fs/promises'
2+
import type { Plugin } from 'esbuild'
3+
4+
/**
5+
* A plugin to replace `require('graphql')` statements with `await import('graphql')`
6+
* only for ESM bundles. This makes the GraphQL module to be imported lazily
7+
* while maintaining the CommonJS compatibility.
8+
* @see https://github.com/mswjs/msw/issues/2254
9+
*/
10+
export function graphqlImportPlugin(): Plugin {
11+
return {
12+
name: 'graphql-import-plugin',
13+
setup(build) {
14+
if (build.initialOptions.format !== 'esm') {
15+
return
16+
}
17+
18+
build.onLoad({ filter: /\.ts$/ }, async (args) => {
19+
const contents = await fs.readFile(args.path, 'utf-8')
20+
const match = /require\(['"]graphql['"]\)/g.exec(contents)
21+
22+
if (match) {
23+
return {
24+
loader: 'ts',
25+
contents:
26+
contents.slice(0, match.index - 1) +
27+
`await import('graphql').catch((error) => {console.error('[MSW] Failed to parse a GraphQL query: cannot import the "graphql" module. Please make sure you install it if you wish to intercept GraphQL requests. See the original import error below.'); throw error})` +
28+
contents.slice(match.index + match[0].length),
29+
}
30+
}
31+
})
32+
},
33+
}
34+
}

‎src/core/utils/internal/parseGraphQLRequest.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ export function parseDocumentNode(node: DocumentNode): ParsedGraphQLQuery {
4040
}
4141

4242
async function parseQuery(query: string): Promise<ParsedGraphQLQuery | Error> {
43-
const { parse } = await import('graphql').catch((error) => {
44-
devUtils.error(
45-
'Failed to parse a GraphQL query: cannot import the "graphql" module. Please make sure you install it if you wish to intercept GraphQL requests. See the original import error below.',
46-
)
47-
throw error
48-
})
43+
/**
44+
* @note Use `require` to get the "graphql" module here.
45+
* It has to be scoped to this function because this module leaks to the
46+
* root export. It has to be `require` because tools like Jest have trouble
47+
* handling dynamic imports. It gets replaced with a dynamic import on build time.
48+
*/
49+
// eslint-disable-next-line @typescript-eslint/no-require-imports
50+
const { parse } = require('graphql')
4951

5052
try {
5153
const ast = parse(query)

‎tsup.config.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from './config/plugins/esbuild/copyWorkerPlugin'
88
import { resolveCoreImportsPlugin } from './config/plugins/esbuild/resolveCoreImportsPlugin'
99
import { forceEsmExtensionsPlugin } from './config/plugins/esbuild/forceEsmExtensionsPlugin'
10+
import { graphqlImportPlugin } from './config/plugins/esbuild/graphQLImportPlugin'
1011
import packageJson from './package.json'
1112

1213
// Externalize the in-house dependencies so that the user
@@ -33,7 +34,7 @@ const coreConfig: Options = {
3334
sourcemap: true,
3435
dts: true,
3536
tsconfig: path.resolve(__dirname, 'src/tsconfig.core.build.json'),
36-
esbuildPlugins: [forceEsmExtensionsPlugin()],
37+
esbuildPlugins: [graphqlImportPlugin(), forceEsmExtensionsPlugin()],
3738
}
3839

3940
const nodeConfig: Options = {

0 commit comments

Comments
 (0)
Please sign in to comment.