Skip to content

Commit 927e5a5

Browse files
authored
enable conditional exports (#4448)
bun, module, module-sync => ESM deno, node and require => CJS default => ESM. node (in versions that do not support module-sync) point sto CJS even when using import so as to avoid the dual-package hazard. deno also points to cjs, even though it supports require(esm), see denoland/deno#29970 the require condition points to CJS just because our default is otherwise now ESM.
1 parent cae3547 commit 927e5a5

File tree

14 files changed

+181
-21
lines changed

14 files changed

+181
-21
lines changed

cspell.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ words:
6666

6767
# TODO: contribute upstream
6868
- deno
69+
- denoland
6970
- hashbang
7071
- Rspack
7172
- Rollup

integrationTests/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Each subdirectory represents a different environment/bundler:
1414
- `ts` - tests for supported Typescript versions
1515
- `webpack` - tests for Webpack
1616

17+
### Verifying Conditional Exports
18+
19+
The `conditions` subdirectory contains tests that verify the conditional exports of GraphQL.js. These tests ensure that the correct files are imported based on the environment being used.
20+
1721
### Verifying Development Mode Tests
1822

1923
Each subdirectory represents a different environment/bundler demonstrating enabling development mode by setting the environment variable `NODE_ENV` to `development`.

integrationTests/conditions/check.mjs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import assert from 'node:assert';
2+
3+
import { GraphQLObjectType as ESMGraphQLObjectType } from 'graphql';
4+
5+
import { CJSGraphQLObjectType, cjsPath } from './cjs-importer.cjs';
6+
7+
const moduleSync = process.env.MODULE_SYNC === 'true';
8+
const expectedExtension = moduleSync ? '.mjs' : '.js';
9+
assert.ok(
10+
cjsPath.endsWith(expectedExtension),
11+
`require('graphql') should resolve to a file with extension "${expectedExtension}", but got "${cjsPath}".`,
12+
);
13+
14+
const isSameModule = ESMGraphQLObjectType === CJSGraphQLObjectType;
15+
assert.strictEqual(
16+
isSameModule,
17+
true,
18+
'ESM and CJS imports should be the same module instances.',
19+
);
20+
21+
console.log('Module identity and path checks passed.');
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
const { GraphQLObjectType } = require('graphql');
4+
5+
const cjsPath = require.resolve('graphql');
6+
7+
// eslint-disable-next-line import/no-commonjs
8+
module.exports = {
9+
CJSGraphQLObjectType: GraphQLObjectType,
10+
cjsPath,
11+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"description": "graphql-js should be loaded correctly on different versions of Node.js, Deno and Bun",
3+
"private": true,
4+
"scripts": {
5+
"test": "node test.js"
6+
},
7+
"dependencies": {
8+
"graphql": "file:../graphql.tgz"
9+
}
10+
}

integrationTests/conditions/test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import childProcess from 'node:child_process';
2+
3+
const nodeTests = [
4+
// Old node versions, require => CJS
5+
{ version: '20.18.0', moduleSync: false },
6+
{ version: '22.11.0', moduleSync: false },
7+
// New node versions, module-sync => ESM
8+
{ version: '20.19.0', moduleSync: true },
9+
{ version: '22.12.0', moduleSync: true },
10+
{ version: '24.0.0', moduleSync: true },
11+
];
12+
13+
for (const { version, moduleSync } of nodeTests) {
14+
console.log(`Testing on node@${version} (moduleSync: ${moduleSync}) ...`);
15+
childProcess.execSync(
16+
`docker run --rm --volume "$PWD":/usr/src/app -w /usr/src/app --env MODULE_SYNC=${moduleSync} node:${version}-slim node ./check.mjs`,
17+
{ stdio: 'inherit' },
18+
);
19+
}
20+
21+
console.log('Testing on bun (moduleSync: true) ...');
22+
childProcess.execSync(
23+
`docker run --rm --volume "$PWD":/usr/src/app -w /usr/src/app --env MODULE_SYNC=true oven/bun:alpine bun ./check.mjs`,
24+
{ stdio: 'inherit' },
25+
);
26+
27+
console.log('Testing on deno (moduleSync: false) ...');
28+
childProcess.execSync(
29+
`docker run --rm --volume "$PWD":/usr/src/app -w /usr/src/app --env MODULE_SYNC=false denoland/deno:alpine-2.4.1 deno run --allow-read --allow-env ./check.mjs`,
30+
{ stdio: 'inherit' },
31+
);

integrationTests/ts/esm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const queryType: GraphQLObjectType = new GraphQLObjectType({
1818
default: { value: 'World' },
1919
},
2020
},
21-
resolve(_root, args: { who: string }) {
21+
resolve(_root: unknown, args: { who: string }) {
2222
return 'Hello ' + args.who;
2323
},
2424
},

integrationTests/ts/extensions-test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ interface SomeExtension {
55
meaningOfLife: 42;
66
}
77

8+
// Import added to support deno, which does not scan node_modules automatically.
9+
import 'graphql';
810
declare module 'graphql' {
911
interface GraphQLObjectTypeExtensions<_TSource, _TContext> {
1012
someObjectExtension?: SomeExtension;
@@ -32,7 +34,8 @@ const queryType: GraphQLObjectType = new GraphQLObjectType({
3234
},
3335
},
3436
},
35-
resolve: (_root, args) => 'Hello ' + (args.who || 'World'),
37+
resolve: (_root: unknown, args: { who: string }) =>
38+
'Hello ' + (args.who || 'World'),
3639
extensions: {
3740
someFieldExtension: { meaningOfLife: 42 },
3841
},

integrationTests/ts/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"dependencies": {
99
"graphql": "file:../graphql.tgz",
1010
"graphql-esm": "file:../graphql-esm.tgz",
11+
"@types/node": "~24.0.10",
1112
"typescript-4.9": "npm:[email protected]",
1213
"typescript-5.0": "npm:[email protected]",
1314
"typescript-5.1": "npm:[email protected]",

integrationTests/ts/test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ const tsVersions = Object.keys(dependencies)
99
.sort((a, b) => b.localeCompare(a));
1010

1111
for (const version of tsVersions) {
12-
console.log(`Testing on ${version} ...`);
12+
console.log(`Testing on node ${version} ...`);
1313
childProcess.execSync(tscPath(version), { stdio: 'inherit' });
1414
}
1515

16+
console.log('Testing on deno ...');
17+
childProcess.execSync(
18+
`docker run --rm --volume "$PWD":/usr/src/app -w /usr/src/app denoland/deno:alpine-2.4.1 deno check`,
19+
{ stdio: 'inherit' },
20+
);
21+
1622
function tscPath(version) {
1723
return path.join('node_modules', version, 'bin', 'tsc');
1824
}

0 commit comments

Comments
 (0)