diff --git a/README.md b/README.md index 5e23874914..8908c605f5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![GraphQLConf 2024 Banner: September 10-12, San Francisco. Hosted by the GraphQL Foundation](https://github.com/user-attachments/assets/2d048502-e5b2-4e9d-a02a-50b841824de6)](https://graphql.org/conf/2024/?utm_source=github&utm_medium=graphql_js&utm_campaign=readme) + # GraphQL.js The JavaScript reference implementation for GraphQL, a query language for APIs created by Facebook. diff --git a/cspell.yml b/cspell.yml index 6ae58bbd3f..422c9d50e1 100644 --- a/cspell.yml +++ b/cspell.yml @@ -20,6 +20,13 @@ overrides: words: - clsx - infima + - noopener + - Vite + - craco + - esbuild + - swcrc + - noreferrer + - xlink validateDirectives: true ignoreRegExpList: diff --git a/src/jsutils/instanceOf.ts b/src/jsutils/instanceOf.ts index c84bcb2afc..562aee3e2f 100644 --- a/src/jsutils/instanceOf.ts +++ b/src/jsutils/instanceOf.ts @@ -1,5 +1,11 @@ import { inspect } from './inspect.js'; +/* c8 ignore next 3 */ +const isProduction = + globalThis.process != null && + // eslint-disable-next-line no-undef + process.env.NODE_ENV === 'production'; + /** * A replacement for instanceof which includes an error warning when multi-realm * constructors are detected. @@ -9,7 +15,7 @@ import { inspect } from './inspect.js'; export const instanceOf: (value: unknown, constructor: Constructor) => boolean = /* c8 ignore next 6 */ // FIXME: https://github.com/graphql/graphql-js/issues/2317 - globalThis.process != null && globalThis.process.env.NODE_ENV === 'production' + isProduction ? function instanceOf(value: unknown, constructor: Constructor): boolean { return value instanceof constructor; } diff --git a/src/language/ast.ts b/src/language/ast.ts index 22a7cc253c..4aa2b811b8 100644 --- a/src/language/ast.ts +++ b/src/language/ast.ts @@ -343,11 +343,12 @@ export interface OperationDefinitionNode { readonly selectionSet: SelectionSetNode; } -export enum OperationTypeNode { +enum OperationTypeNode { QUERY = 'query', MUTATION = 'mutation', SUBSCRIPTION = 'subscription', } +export { OperationTypeNode }; export interface VariableDefinitionNode { readonly kind: Kind.VARIABLE_DEFINITION; diff --git a/src/language/directiveLocation.ts b/src/language/directiveLocation.ts index b10214d47f..0a7bae7990 100644 --- a/src/language/directiveLocation.ts +++ b/src/language/directiveLocation.ts @@ -1,7 +1,7 @@ /** * The set of allowed directive location values. */ -export enum DirectiveLocation { +enum DirectiveLocation { /** Request Definitions */ QUERY = 'QUERY', MUTATION = 'MUTATION', @@ -24,3 +24,5 @@ export enum DirectiveLocation { INPUT_OBJECT = 'INPUT_OBJECT', INPUT_FIELD_DEFINITION = 'INPUT_FIELD_DEFINITION', } + +export { DirectiveLocation } diff --git a/src/language/kinds.ts b/src/language/kinds.ts index d606c12cbe..5c314432af 100644 --- a/src/language/kinds.ts +++ b/src/language/kinds.ts @@ -1,7 +1,7 @@ /** * The set of allowed kind values for AST nodes. */ -export enum Kind { +enum Kind { /** Name */ NAME = 'Name', @@ -72,3 +72,5 @@ export enum Kind { ENUM_TYPE_EXTENSION = 'EnumTypeExtension', INPUT_OBJECT_TYPE_EXTENSION = 'InputObjectTypeExtension', } + +export { Kind }; diff --git a/src/language/tokenKind.ts b/src/language/tokenKind.ts index 1bba933d50..1bc471c079 100644 --- a/src/language/tokenKind.ts +++ b/src/language/tokenKind.ts @@ -2,7 +2,7 @@ * An exported enum describing the different kinds of tokens that the * lexer emits. */ -export enum TokenKind { +enum TokenKind { SOF = '', EOF = '', BANG = '!', @@ -27,3 +27,5 @@ export enum TokenKind { BLOCK_STRING = 'BlockString', COMMENT = 'Comment', } + +export { TokenKind } diff --git a/src/type/introspection.ts b/src/type/introspection.ts index 5f3c9c1fa5..2330b2485a 100644 --- a/src/type/introspection.ts +++ b/src/type/introspection.ts @@ -443,7 +443,7 @@ export const __EnumValue: GraphQLObjectType = new GraphQLObjectType({ } as GraphQLFieldConfigMap), }); -export enum TypeKind { +enum TypeKind { SCALAR = 'SCALAR', OBJECT = 'OBJECT', INTERFACE = 'INTERFACE', @@ -453,6 +453,7 @@ export enum TypeKind { LIST = 'LIST', NON_NULL = 'NON_NULL', } +export { TypeKind }; export const __TypeKind: GraphQLEnumType = new GraphQLEnumType({ name: '__TypeKind', diff --git a/src/utilities/findBreakingChanges.ts b/src/utilities/findBreakingChanges.ts index 793d29bc83..78bbada1c7 100644 --- a/src/utilities/findBreakingChanges.ts +++ b/src/utilities/findBreakingChanges.ts @@ -34,7 +34,7 @@ import type { GraphQLSchema } from '../type/schema.js'; import { astFromValue } from './astFromValue.js'; import { sortValueNode } from './sortValueNode.js'; -export enum BreakingChangeType { +enum BreakingChangeType { TYPE_REMOVED = 'TYPE_REMOVED', TYPE_CHANGED_KIND = 'TYPE_CHANGED_KIND', TYPE_REMOVED_FROM_UNION = 'TYPE_REMOVED_FROM_UNION', @@ -52,8 +52,9 @@ export enum BreakingChangeType { DIRECTIVE_REPEATABLE_REMOVED = 'DIRECTIVE_REPEATABLE_REMOVED', DIRECTIVE_LOCATION_REMOVED = 'DIRECTIVE_LOCATION_REMOVED', } +export { BreakingChangeType }; -export enum DangerousChangeType { +enum DangerousChangeType { VALUE_ADDED_TO_ENUM = 'VALUE_ADDED_TO_ENUM', TYPE_ADDED_TO_UNION = 'TYPE_ADDED_TO_UNION', OPTIONAL_INPUT_FIELD_ADDED = 'OPTIONAL_INPUT_FIELD_ADDED', @@ -61,6 +62,7 @@ export enum DangerousChangeType { IMPLEMENTED_INTERFACE_ADDED = 'IMPLEMENTED_INTERFACE_ADDED', ARG_DEFAULT_VALUE_CHANGE = 'ARG_DEFAULT_VALUE_CHANGE', } +export { DangerousChangeType }; export interface BreakingChange { type: BreakingChangeType; diff --git a/website/docs/tutorials/going-to-production.md b/website/docs/tutorials/going-to-production.md new file mode 100644 index 0000000000..fcc4a9ca37 --- /dev/null +++ b/website/docs/tutorials/going-to-production.md @@ -0,0 +1,127 @@ +--- +title: Going to production +category: FAQ +--- + +GraphQL.JS contains a few development checks which in production will cause slower performance and +an increase in bundle-size. Every bundler goes about these changes different, in here we'll list +out the most popular ones. + +## Bundler-specific configuration + +Here are some bundler-specific suggestions for configuring your bundler to remove `globalThis.process` and `process.env.NODE_ENV` on build time. + +### Vite + +```js +export default defineConfig({ + // ... + define: { + 'globalThis.process': JSON.stringify(true), + 'process.env.NODE_ENV': JSON.stringify('production'), + }, +}); +``` + +### Next.js + +```js +// ... +/** @type {import('next').NextConfig} */ +const nextConfig = { + webpack(config, { webpack }) { + config.plugins.push( + new webpack.DefinePlugin({ + 'globalThis.process': JSON.stringify(true), + 'process.env.NODE_ENV': JSON.stringify('production'), + }), + ); + return config; + }, +}; + +module.exports = nextConfig; +``` + +### create-react-app + +With `create-react-app`, you need to use a third-party package like [`craco`](https://craco.js.org/) to modify the bundler configuration. + +```js +const webpack = require('webpack'); +module.exports = { + webpack: { + plugins: [ + new webpack.DefinePlugin({ + 'globalThis.process': JSON.stringify(true), + 'process.env.NODE_ENV': JSON.stringify('production'), + }), + ], + }, +}; +``` + +### esbuild + +```json +{ + "define": { + "globalThis.process": true, + "process.env.NODE_ENV": "production" + } +} +``` + +### Webpack + +```js +config.plugins.push( + new webpack.DefinePlugin({ + 'globalThis.process': JSON.stringify(true), + 'process.env.NODE_ENV': JSON.stringify('production'), + }), +); +``` + +### Rollup + +```js +export default [ + { + // ... input, output, etc. + plugins: [ + minify({ + mangle: { + toplevel: true, + }, + compress: { + toplevel: true, + global_defs: { + '@globalThis.process': JSON.stringify(true), + '@process.env.NODE_ENV': JSON.stringify('production'), + }, + }, + }), + ], + }, +]; +``` + +### SWC + +```json title=".swcrc" +{ + "jsc": { + "transform": { + "optimizer": { + "globals": { + "vars": { + "globalThis.process": true, + "process.env.NODE_ENV": "production" + } + } + } + } + } +} +``` diff --git a/website/sidebars.cjs b/website/sidebars.cjs index 5201b4fd95..9857a5f754 100644 --- a/website/sidebars.cjs +++ b/website/sidebars.cjs @@ -15,6 +15,11 @@ module.exports = { label: 'Advanced', items: ['tutorials/constructing-types'], }, + { + type: 'category', + label: 'FAQ', + items: ['tutorials/going-to-production'], + }, 'tutorials/express-graphql', 'tutorials/defer-stream', ],