Skip to content

Commit 9e4f796

Browse files
authored
use development condition and enableDevMode() instead of NODE_ENV (#4464)
Motivation: This PR makes our build product cross-platform by dropping all Node.js specific code. In development mode, GraphQL.JS can provide an additional runtime check appropriate for development-time errors: the erroneous inclusion of multiple GraphQL.JS modules. Unlike earlier versions of GraphQL.JS, by default, development mode is disabled. This is to best ensure that production builds do not incur the performance and bundle size penalties associated with the additional checks. Also, unlike earlier versions, development mode is not configured by use of environment variables, which are accessed in disparate ways on the various platforms. In particular, the `NODE_ENV` environment variable now has no effect on triggering development mode. Rather, development mode is either enabled: 1. by setting a 'development' condition, which is possible only on platforms that support `package.json` conditional exports and custom conditions, or 2. by calling `enableDevMode()` within user code. Conditional exports with custom conditions are supported by: Node.js, Deno, Bun, Webpack 5, Rspack, Rollup (via the `node-resolve` plugin), esbuild, Vite, and Rsbuild. create-react-app and Next.js support conditional exports when using Webpack 5 as their bundler. Conditional exports with custom conditions are not supported by Webpack 4, Rollup (without the `node-resolve` plugin), older versions of Deno or transpilers such as swc. create-react-app and Next.js do not support conditional exports with custom conditions when using Webpack 4 as their bundler, nor does Next.js yet support conditional exports with custom conditions when using Turbopack (see vercel/next.js#78912). Testing frameworks such as Mocha, Jest, and Vitest support conditional exports with custom conditions, Integration tests within the repository demonstrate how to enable development mode using the `development` condition on various platforms that support this, as well as enabling development mode by calling `enableDevMode()` within user code. We encourage enabling development mode in a development environment. This facilitates the additional check to ensure that only a single GraphQL.JS module is used. Additional development-time checks may also be added in the future.
1 parent 1bb1417 commit 9e4f796

File tree

38 files changed

+525
-221
lines changed

38 files changed

+525
-221
lines changed

cspell.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ words:
6868
- deno
6969
- denoland
7070
- hashbang
71-
- Rspack
71+
- vitest
7272
- Rollup
73+
- Rspack
74+
- Rsbuild
75+
- Turbopack
7376

7477
# Website tech
7578
- Nextra

integrationTests/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The `conditions` subdirectory contains tests that verify the conditional exports
2020

2121
### Verifying Development Mode Tests
2222

23-
Each subdirectory represents a different environment/bundler demonstrating enabling development mode by setting the environment variable `NODE_ENV` to `development`.
23+
Each subdirectory represents a different platform/bundler demonstrating enabling development mode by enabling the `development` condition or by calling `enableDevMode()`.
2424

2525
### Verifying Production Mode Tests
2626

integrationTests/dev-bun/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"description": "graphql-js development mode should work with Bun",
33
"private": true,
44
"scripts": {
5-
"test": "docker run --rm --volume \"$PWD\":/usr/src/app -w /usr/src/app oven/bun:\"$BUN_VERSION\"-slim bun test.js"
5+
"test": "docker run --rm --volume \"$PWD\":/usr/src/app -w /usr/src/app oven/bun:\"$BUN_VERSION\"-slim bun --conditions=development test.js"
66
},
77
"dependencies": {
88
"graphql": "file:../graphql.tgz"

integrationTests/dev-deno/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"description": "graphql-js development mode should work with Deno",
33
"private": true,
44
"scripts": {
5-
"test": "docker run --rm --volume \"$PWD\":/usr/src/app -w /usr/src/app denoland/deno:alpine-\"$DENO_VERSION\" deno run --allow-env=NODE_ENV test.js"
5+
"test": "docker run --rm --volume \"$PWD\":/usr/src/app -w /usr/src/app denoland/deno:alpine-\"$DENO_VERSION\" deno run --conditions=development test.js"
66
},
77
"dependencies": {
88
"graphql": "file:../graphql.tgz"

integrationTests/dev-deno/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class GraphQLObjectType {
99
try {
1010
isObjectType(new GraphQLObjectType());
1111
throw new Error(
12-
'Expected isObjectType to throw an error in Deno implicit dev mode.',
12+
'Expected isObjectType to throw an error in Deno development mode.',
1313
);
1414
} catch (error) {
1515
if (!error.message.includes('from another module or realm')) {

integrationTests/dev-esbuild/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"private": true,
44
"type": "module",
55
"scripts": {
6-
"build": "esbuild index.js --bundle --outfile=dist/bundle.js --format=esm",
6+
"build": "esbuild index.js --bundle --outfile=dist/bundle.js --format=esm --conditions=development",
77
"test": "npm run build && node dist/bundle.js"
88
},
99
"dependencies": {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"description": "graphql-js explicit development mode should work",
3+
"private": true,
4+
"type": "module",
5+
"scripts": {
6+
"test": "node test.js"
7+
},
8+
"dependencies": {
9+
"graphql": "file:../graphql.tgz"
10+
}
11+
}

integrationTests/dev-explicit/test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { enableDevMode, isObjectType } from 'graphql';
2+
3+
enableDevMode();
4+
5+
class GraphQLObjectType {
6+
get [Symbol.toStringTag]() {
7+
return 'GraphQLObjectType';
8+
}
9+
}
10+
11+
try {
12+
isObjectType(new GraphQLObjectType());
13+
throw new Error(
14+
'Expected isObjectType to throw an error in Node.js development mode.',
15+
);
16+
} catch (error) {
17+
if (!error.message.includes('from another module or realm')) {
18+
throw error;
19+
}
20+
}

integrationTests/dev-jest/index.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class FakeGraphQLObjectType {
99
}
1010
}
1111

12-
describe('Jest with SWC development mode tests', () => {
12+
describe('Jest development mode tests', () => {
1313
test('isObjectType should throw in development mode for instances from another realm/module', () => {
1414
expect(() => isObjectType(new FakeGraphQLObjectType())).toThrowError(
1515
/from another module or realm/,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const jestConfig = {
2+
testEnvironmentOptions: {
3+
customExportConditions: ['development'],
4+
},
5+
};
6+
7+
// eslint-disable-next-line no-restricted-exports, import/no-default-export
8+
export default jestConfig;

0 commit comments

Comments
 (0)