Skip to content

Commit

Permalink
Some more performance improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown committed Aug 10, 2020
1 parent 957841d commit 503d9c3
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 144 deletions.
6 changes: 6 additions & 0 deletions .changeset/green-days-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@ts-gql/compiler": patch
"@ts-gql/config": patch
---

Optimise lazy requires
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"jest": "^25.4.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"typescript": "^3.8.3"
"typescript": "^3.9.7"
},
"scripts": {
"postinstall": "preconstruct dev",
Expand Down
7 changes: 4 additions & 3 deletions packages/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@
"@graphql-codegen/plugin-helpers": "^1.13.3",
"@graphql-codegen/typescript": "^1.13.3",
"@graphql-codegen/typescript-operations": "^1.13.3",
"@nodelib/fs.walk": "^1.2.4",
"@ts-gql/config": "^0.7.0",
"@types/babel__code-frame": "^7.0.1",
"@types/fs-extra": "^8.1.0",
"@types/graceful-fs": "^4.1.3",
"@types/invariant": "^2.2.32",
"chokidar": "^3.4.0",
"fast-glob": "^3.2.4",
"find-pkg-json-field-up": "^1.0.1",
"fs-extra": "^9.0.0",
"globby": "^11.0.0",
"graceful-fs": "^4.2.4",
"invariant": "^2.2.4",
"slash": "^3.0.0",
"strip-ansi": "^6.0.0"
Expand Down
6 changes: 3 additions & 3 deletions packages/compiler/src/extract-documents.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Node } from "@babel/types";
import { parse as babelParse } from "@babel/parser";
import type { Node } from "@babel/types";
import { lazyRequire } from "lazy-require.macro";
import { CompilerError, FullSourceLocation } from "./types";

type BabelVisitors = {
Expand Down Expand Up @@ -43,7 +43,7 @@ export function extractGraphQLDocumentsContentsFromFile(
}[] = [];
if (/gql\s*`/.test(content)) {
try {
let ast = babelParse(content, {
let ast = lazyRequire<typeof import("@babel/parser")>().parse(content, {
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
allowSuperOutsideMethod: true,
Expand Down
6 changes: 3 additions & 3 deletions packages/compiler/src/fs-operations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from "fs-extra";
import * as fs from "./fs";

export type FsOperation =
| {
Expand All @@ -13,7 +13,7 @@ export type FsOperation =

export async function applyFsOperation(operation: FsOperation) {
if (operation.type === "remove") {
return fs.remove(operation.filename);
return fs.unlink(operation.filename);
}
return fs.outputFile(operation.filename, operation.content);
return fs.writeFile(operation.filename, operation.content);
}
8 changes: 8 additions & 0 deletions packages/compiler/src/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import gracefulFS from "graceful-fs";
import { promisify } from "util";

export const writeFile = promisify(gracefulFS.writeFile);
export const readFile = promisify(gracefulFS.readFile);
export const mkdir = promisify(gracefulFS.mkdir);
export const readdir = promisify(gracefulFS.readdir);
export const unlink = promisify(gracefulFS.unlink);
4 changes: 2 additions & 2 deletions packages/compiler/src/get-documents.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from "fs-extra";
import * as fs from "./fs";
import type { DocumentNode } from "graphql";
import { GraphQLError } from "graphql/error/GraphQLError";
import { parse } from "graphql/language/parser";
Expand Down Expand Up @@ -65,7 +65,7 @@ function writeDocumentExtractionCache(
2
);
let signed = integrity.sign(stringified);
return fs.outputFile(cacheFilename, signed);
return fs.writeFile(cacheFilename, signed);
}

export async function getDocuments(files: string[], cacheFilename: string) {
Expand Down
117 changes: 61 additions & 56 deletions packages/compiler/src/get-generated-types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import fs from "fs-extra";
import * as fs from "./fs";
import nodePath from "path";
import type { FragmentDefinitionNode } from "graphql";
import { GraphQLError } from "graphql/error/GraphQLError";
import { visit } from "graphql/language/visitor";
import { lazyRequire } from "lazy-require.macro";
import slash from "slash";
import globby from "globby";
import { walk as _walk, Settings } from "@nodelib/fs.walk";
import { cachedGenerateSchemaTypes } from "./schema-types";
import {
cachedGenerateOperationTypes,
cachedGenerateErrorModuleFsOperation,
} from "./operation-types";
import { FsOperation } from "./fs-operations";
import { Config } from "@ts-gql/config";
import { promisify } from "util";
import { CompilerError, TSGQLDocument } from "./types";
import { cachedGenerateIntrospectionResult } from "./introspection-result";
import { locFromSourceAndGraphQLError, hashString } from "./utils";
Expand All @@ -32,6 +33,8 @@ function memoize<V>(fn: (arg: string) => V): (arg: string) => V {
};
}

const walk = promisify(_walk);

function getPrintCompilerError() {
let readFile = memoize((filename: string) => fs.readFile(filename, "utf8"));
return async (error: CompilerError) => {
Expand All @@ -52,6 +55,20 @@ function getPrintCompilerError() {
};
}

type Dependencies = string | Dependencies[];

let tsExtensionRegex = /\.tsx?$/;

let dtsExtensionRegex = /\.d\.ts$/;

const walkSettings = new Settings({
deepFilter: (entry) =>
!entry.path.includes("node_modules") &&
entry.path !== `__generated__${nodePath.sep}ts-gql`,
entryFilter: (entry) =>
tsExtensionRegex.test(entry.name) && !dtsExtensionRegex.test(entry.name),
});

export const getGeneratedTypes = async (config: Config) => {
let generatedDirectory = nodePath.join(
config.directory,
Expand All @@ -60,13 +77,11 @@ export const getGeneratedTypes = async (config: Config) => {
);

const files = (
await globby(["**/*.{ts,tsx}"], {
cwd: config.directory,
absolute: true,
expandDirectories: false,
ignore: ["**/node_modules/**", "__generated__/ts-gql/*", "**/*.d.ts"],
})
).map((x) => slash(x));
await Promise.all([
walk(config.directory, walkSettings),
fs.mkdir(generatedDirectory, { recursive: true }),
])
)[0].map((x) => slash(x.path));

let { errors, documents } = await getDocuments(
files,
Expand Down Expand Up @@ -156,47 +171,15 @@ export const getGeneratedTypes = async (config: Config) => {
if (operation) {
fsOperations.push(operation);
}

let dependencies = Object.keys(uniqueDocumentsByName).reduce((obj, item) => {
obj[item] = [];
return obj;
}, {} as Record<string, string[]>);

for (let key in uniqueDocumentsByName) {
let { node } = uniqueDocumentsByName[key];
visit(node, {
FragmentSpread(node) {
let name = node.name.value;
if (
!uniqueDocumentsByName[name] ||
uniqueDocumentsByName[name].node.kind === "OperationDefinition"
) {
errors.push({
message: `Fragment ${name} not found`,
filename: uniqueDocumentsByName[key].filename,
loc: locFromSourceAndGraphQLError(
uniqueDocumentsByName[key].loc,
new GraphQLError("Fragment", [node])
),
});
} else {
dependencies[key].push(name);
}
},
});
}

const dependencies = getDependencies(uniqueDocumentsByName, errors);
const documentValidationCache = await readDocumentValidationCache(config);
const newDocumentValidationCache: DocumentValidationCache = {};
await Promise.all(
Object.keys(uniqueDocumentsByName).map(async (key) => {
const documentInfo = uniqueDocumentsByName[key];
let nodes = [
documentInfo.node,
...getFlatDependenciesForItem(dependencies, key).map(
(x) => uniqueDocumentsByName[x].node as FragmentDefinitionNode
),
];
let nodes = [...new Set(dependencies[key].flat(Infinity))].map(
(x) => uniqueDocumentsByName[x].node as FragmentDefinitionNode
);

let document = {
kind: "Document",
Expand Down Expand Up @@ -252,15 +235,37 @@ export const getGeneratedTypes = async (config: Config) => {
};
};

function getFlatDependenciesForItem(
deps: Record<string, string[]>,
item: string
): string[] {
return [
...new Set<string>(
deps[item].concat(
...deps[item].map((item) => getFlatDependenciesForItem(deps, item))
)
),
];
function getDependencies(
uniqueDocumentsByName: Record<string, TSGQLDocument>,
errors: CompilerError[]
) {
let dependencies: Record<string, Dependencies[]> = {};
Object.keys(uniqueDocumentsByName).forEach((item) => {
dependencies[item] = [item];
});

for (let key in uniqueDocumentsByName) {
let { node } = uniqueDocumentsByName[key];
visit(node, {
FragmentSpread(node) {
let name = node.name.value;
if (
!uniqueDocumentsByName[name] ||
uniqueDocumentsByName[name].node.kind === "OperationDefinition"
) {
errors.push({
message: `Fragment ${name} not found`,
filename: uniqueDocumentsByName[key].filename,
loc: locFromSourceAndGraphQLError(
uniqueDocumentsByName[key].loc,
new GraphQLError("Fragment", [node])
),
});
} else {
dependencies[key].push(dependencies[name]);
}
},
});
}
return dependencies;
}
2 changes: 1 addition & 1 deletion packages/compiler/src/introspection-result.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from "fs-extra";
import * as fs from "./fs";
import type { GraphQLSchema } from "graphql";
import { parseTsGqlMeta } from "./utils";
import { FsOperation } from "./fs-operations";
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/operation-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from "fs-extra";
import * as fs from "./fs";
import type { DocumentNode } from "graphql";
import { codegen } from "./codegen-core";
import { hashString, parseTsGqlMeta } from "./utils";
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/schema-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from "fs-extra";
import * as fs from "./fs";
import path from "path";
import { codegen } from "./codegen-core";
import { hashString, parseTsGqlMeta } from "./utils";
Expand Down
4 changes: 2 additions & 2 deletions packages/compiler/src/validate-documents.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ValidationRule, DocumentNode } from "graphql";
import { GraphQLError } from "graphql/error/GraphQLError";
import nodePath from "path";
import * as fs from "fs-extra";
import * as fs from "./fs";
import { Config } from "@ts-gql/config";
import { lazyRequire } from "lazy-require.macro";
import { locFromSourceAndGraphQLError, integrity } from "./utils";
Expand Down Expand Up @@ -89,7 +89,7 @@ export function writeDocumentValidationCache(
2
);
let signed = integrity.sign(stringified);
return fs.outputFile(cacheFilename, signed);
return fs.writeFile(cacheFilename, signed);
}

let rules: { operation: ValidationRule[]; fragment: ValidationRule[] };
Expand Down
5 changes: 2 additions & 3 deletions packages/compiler/src/watch.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as fs from "fs-extra";
import { getRawConfig } from "@ts-gql/config";
import * as fs from "./fs";
import { getRawConfig, parseSchema } from "@ts-gql/config";
import { createWatcher } from "./watcher";
import { getGeneratedTypes } from "./get-generated-types";
import { parseSchema } from "@ts-gql/config";
import { applyFsOperation } from "./fs-operations";
import { lazyRequire } from "lazy-require.macro";

Expand Down
Loading

0 comments on commit 503d9c3

Please sign in to comment.