Skip to content

Commit

Permalink
Improve performance by not building schema AST over and over (#2073)
Browse files Browse the repository at this point in the history
* Improve performance by not building schema AST over and over

* Rebuild schema AST when a plugin changes the schema
  • Loading branch information
mvestergaard authored and dotansimha committed Jul 3, 2019
1 parent b70d122 commit 3af668a
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 11 deletions.
12 changes: 8 additions & 4 deletions packages/graphql-codegen-cli/src/codegen.ts
Expand Up @@ -5,7 +5,7 @@ import { normalizeOutputParam, normalizeInstanceOrArray, normalizeConfig } from
import { prettify } from './utils/prettier';
import { Renderer } from './utils/listr-renderer';
import { loadSchema, loadDocuments } from './load';
import { GraphQLError, DocumentNode } from 'graphql';
import { GraphQLError, DocumentNode, buildASTSchema } from 'graphql';
import { getPluginByName } from './plugins';
import { getPresetByName } from './presets';
import { debugLog } from './utils/debugging';
Expand All @@ -16,7 +16,7 @@ export async function executeCodegen(config: Types.Config): Promise<Types.FileOu
function wrapTask(task: () => void | Promise<void>, source?: string) {
return async () => {
try {
await task();
await Promise.resolve(task());
} catch (error) {
if (source && !(error instanceof GraphQLError)) {
error.source = source;
Expand Down Expand Up @@ -221,6 +221,7 @@ export async function executeCodegen(config: Types.Config): Promise<Types.FileOu
presetConfig: outputConfig.presetConfig || {},
plugins: normalizedPluginsArray,
schema: outputSchema,
schemaAst: buildASTSchema(outputSchema),
documents: outputDocuments,
config: mergedConfig,
pluginMap,
Expand All @@ -231,20 +232,23 @@ export async function executeCodegen(config: Types.Config): Promise<Types.FileOu
filename,
plugins: normalizedPluginsArray,
schema: outputSchema,
schemaAst: buildASTSchema(outputSchema),
documents: outputDocuments,
config: mergedConfig,
pluginMap,
},
];
}

for (const outputArgs of outputs) {
const process = async (outputArgs: Types.GenerateOptions) => {
const output = await codegen(outputArgs);
result.push({
filename: outputArgs.filename,
content: await prettify(outputArgs.filename, output),
});
}
};

await Promise.all(outputs.map(process));
}, filename),
},
],
Expand Down
15 changes: 13 additions & 2 deletions packages/graphql-codegen-core/src/codegen.ts
@@ -1,5 +1,5 @@
import { Types, isComplexPluginOutput } from '@graphql-codegen/plugin-helpers';
import { DocumentNode, visit } from 'graphql';
import { DocumentNode, visit, buildASTSchema } from 'graphql';
import { mergeSchemas } from './merge-schemas';
import { executePlugin } from './execute-plugin';
import { DetailedError } from './errors';
Expand All @@ -16,10 +16,20 @@ export async function codegen(options: Types.GenerateOptions): Promise<string> {
const pluginPackages = Object.keys(options.pluginMap).map(key => options.pluginMap[key]);

// merged schema with parts added by plugins
let schemaChanged = false;
const schema = pluginPackages.reduce((schema, plugin) => {
return !plugin.addToSchema ? schema : mergeSchemas([schema, plugin.addToSchema]);
if (!plugin.addToSchema) {
return schema;
}

schemaChanged = true;
return mergeSchemas([schema, plugin.addToSchema]);
}, options.schema);

if (schemaChanged) {
options.schemaAst = buildASTSchema(schema);
}

const prepend: Set<string> = new Set<string>();
const append: Set<string> = new Set<string>();

Expand All @@ -39,6 +49,7 @@ export async function codegen(options: Types.GenerateOptions): Promise<string> {
...(pluginConfig as object),
},
schema,
schemaAst: options.schemaAst,
documents: options.documents,
outputFilename: options.filename,
allPlugins: options.plugins,
Expand Down
13 changes: 8 additions & 5 deletions packages/graphql-codegen-core/src/execute-plugin.ts
Expand Up @@ -7,6 +7,7 @@ export interface ExecutePluginOptions {
name: string;
config: Types.PluginConfig;
schema: DocumentNode;
schemaAst?: GraphQLSchema;
documents: Types.DocumentFile[];
outputFilename: string;
allPlugins: Types.ConfiguredPlugin[];
Expand All @@ -30,7 +31,7 @@ export async function executePlugin(options: ExecutePluginOptions, plugin: Codeg
);
}

const outputSchema: GraphQLSchema = buildASTSchema(options.schema);
const outputSchema: GraphQLSchema = options.schemaAst || buildASTSchema(options.schema);
const documents = options.documents || [];

if (outputSchema && documents.length > 0) {
Expand All @@ -51,8 +52,10 @@ export async function executePlugin(options: ExecutePluginOptions, plugin: Codeg
}
}

return plugin.plugin(outputSchema, documents, options.config, {
outputFile: options.outputFilename,
allPlugins: options.allPlugins,
});
return await Promise.resolve(
plugin.plugin(outputSchema, documents, options.config, {
outputFile: options.outputFilename,
allPlugins: options.allPlugins,
})
);
}
1 change: 1 addition & 0 deletions packages/presets/near-operation-file/src/index.ts
Expand Up @@ -162,6 +162,7 @@ export const preset: Types.OutputPreset<NearOperationFileConfig> = {
pluginMap,
config,
schema: options.schema,
schemaAst: options.schemaAst,
documents: [documentFile],
};
})
Expand Down
2 changes: 2 additions & 0 deletions packages/utils/plugins-helpers/src/types.ts
Expand Up @@ -6,6 +6,7 @@ export namespace Types {
filename: string;
plugins: Types.ConfiguredPlugin[];
schema: DocumentNode;
schemaAst?: GraphQLSchema;
documents: Types.DocumentFile[];
config: { [key: string]: any };
pluginMap: {
Expand Down Expand Up @@ -64,6 +65,7 @@ export namespace Types {
baseOutputDir: string;
plugins: Types.ConfiguredPlugin[];
schema: DocumentNode;
schemaAst?: GraphQLSchema;
documents: Types.DocumentFile[];
config: { [key: string]: any };
pluginMap: {
Expand Down

0 comments on commit 3af668a

Please sign in to comment.