Skip to content

Commit

Permalink
Performance improvements (#6737)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown authored Oct 7, 2021
1 parent 73544fd commit 930b712
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 119 deletions.
5 changes: 5 additions & 0 deletions .changeset/dry-mayflies-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-next/keystone': patch
---

Improved dev startup performance
5 changes: 5 additions & 0 deletions .changeset/fuzzy-swans-give.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-next/keystone': patch
---

Keystone will now consistently not respect a custom Babel config if it exists rather than the previous behaviour of respecting it in some commands but not for compilations from `keystone-next build` that are run with `keystone-next start`
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@preconstruct/cli": "2.1.4",
"@preconstruct/eslint-plugin-format-js-tag": "^0.1.0",
"@testing-library/jest-dom": "^5.14.1",
"@types/babel__core": "^7.1.16",
"@types/jest": "^27.0.2",
"@types/node-fetch": "^2.5.12",
"@typescript-eslint/eslint-plugin": "^4.33.0",
Expand Down
2 changes: 0 additions & 2 deletions packages/keystone/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"dependencies": {
"@apollo/client": "^3.4.16",
"@babel/core": "^7.15.5",
"@babel/plugin-transform-modules-commonjs": "^7.15.4",
"@babel/runtime": "^7.15.4",
"@emotion/hash": "^0.8.0",
"@emotion/weak-memoize": "^0.2.5",
Expand All @@ -54,7 +53,6 @@
"@prisma/sdk": "3.2.0",
"@sindresorhus/slugify": "^1.1.2",
"@types/apollo-upload-client": "14.1.0",
"@types/babel__core": "^7.1.16",
"@types/bcryptjs": "^2.4.2",
"@types/cookie": "^0.4.1",
"@types/express": "^4.17.13",
Expand Down
23 changes: 15 additions & 8 deletions packages/keystone/src/admin-ui/system/generateAdminUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import Path from 'path';
import fs from 'fs-extra';

import fastGlob from 'fast-glob';
import prettier from 'prettier';
import resolve from 'resolve';
import { GraphQLSchema } from 'graphql';
import type { KeystoneConfig, AdminMetaRootVal, AdminFileToWrite } from '../../types';
import { writeAdminFiles } from '../templates';
import { serializePathForImport } from '../utils/serializePathForImport';

export const formatSource = (src: string, parser: 'babel' | 'babel-ts' = 'babel') =>
prettier.format(src, { parser, trailingComma: 'es5', singleQuote: true });

function getDoesAdminConfigExist() {
try {
const configPath = Path.join(process.cwd(), 'admin', 'config');
Expand All @@ -25,7 +21,7 @@ function getDoesAdminConfigExist() {
}
}

async function writeAdminFile(file: AdminFileToWrite, projectAdminPath: string) {
export async function writeAdminFile(file: AdminFileToWrite, projectAdminPath: string) {
const outputFilename = Path.join(projectAdminPath, file.outputPath);
if (file.mode === 'copy') {
if (!Path.isAbsolute(file.inputPath)) {
Expand All @@ -38,7 +34,7 @@ async function writeAdminFile(file: AdminFileToWrite, projectAdminPath: string)
await fs.copyFile(file.inputPath, outputFilename);
}
if (file.mode === 'write') {
await fs.outputFile(outputFilename, formatSource(file.src));
await fs.outputFile(outputFilename, file.src);
}
return Path.normalize(outputFilename);
}
Expand All @@ -49,8 +45,19 @@ export const generateAdminUI = async (
adminMeta: AdminMetaRootVal,
projectAdminPath: string
) => {
// Nuke any existing files in our target directory
await fs.remove(projectAdminPath);
const dir = await fs.readdir(projectAdminPath).catch(err => {
if (err.code === 'ENOENT') {
return [];
}
throw err;
});

await Promise.all(
dir.map(x => {
if (x === '.next') return;
return fs.remove(Path.join(projectAdminPath, x));
})
);
const publicDirectory = Path.join(projectAdminPath, 'public');

if (config.images || config.files) {
Expand Down
22 changes: 4 additions & 18 deletions packages/keystone/src/lib/config/requireSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import * as babel from '@babel/core';
import sourceMapSupport from 'source-map-support';

const EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx'];
const babelPlugins = [require.resolve('@babel/plugin-transform-modules-commonjs')];

const hook = () => {
let compiling = false;
Expand Down Expand Up @@ -37,26 +36,13 @@ const hook = () => {
}
try {
compiling = true;
const partialConfig = babel.loadPartialConfig({
plugins: babelPlugins,
const output = babel.transformSync(code, {
filename,
presets: [require.resolve('next/babel')],
configFile: false,
babelrc: false,
sourceMaps: 'both',
rootMode: 'upward-optional',
})!;
let options = partialConfig.options;
if (!partialConfig.hasFilesystemConfig()) {
options = {
...options,
// note that we're explicitly removing the plugin(@babel/plugin-transform-modules-commonjs)
// we added above because for some reason, it interacts poorly with next/babel
// and results in stray ESM imports of React when they should be CJS
// note that we're never going to be removing a consumer's Babel config since
// that would make hasFilesystemConfig() return true
plugins: [],
presets: [require.resolve('next/babel')],
};
}
const output = babel.transformSync(code, options)!;
sourceMaps[filename] = output.map;
return output.code!;
} finally {
Expand Down
7 changes: 1 addition & 6 deletions packages/keystone/src/lib/schema-type-printer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
FieldDefinitionNode,
InputValueDefinitionNode,
} from 'graphql';
import prettier from 'prettier';
import { getGqlNames } from '../types';
import { InitialisedList } from './core/types-for-lists';

Expand Down Expand Up @@ -175,9 +174,5 @@ export type KeystoneContext = Omit<GenericKeystoneContext, 'db' | 'query' | 'pri
prisma: import('.prisma/client').PrismaClient;
};
`;
return prettier.format(prelude + printedTypes + allListsStr + postlude, {
parser: 'babel-ts',
trailingComma: 'es5',
singleQuote: true,
});
return prelude + printedTypes + allListsStr + postlude;
}
20 changes: 1 addition & 19 deletions packages/keystone/src/scripts/build/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,7 @@ import { requireSource } from '../../lib/config/requireSource';
import { generateNodeModulesArtifacts, validateCommittedArtifacts } from '../../artifacts';
import { getAdminPath, getConfigPath } from '../utils';
import { serializePathForImport } from '../../admin-ui/utils/serializePathForImport';
import { formatSource } from '../../admin-ui/system/generateAdminUI';

// FIXME: Duplicated from admin-ui package. Need to decide on a common home.
async function writeAdminFile(file: AdminFileToWrite, projectAdminPath: string) {
const outputFilename = Path.join(projectAdminPath, file.outputPath);
if (file.mode === 'copy') {
if (!Path.isAbsolute(file.inputPath)) {
throw new Error(
`An inputPath of "${file.inputPath}" was provided to copy but inputPaths must be absolute`
);
}
await fs.ensureDir(Path.dirname(outputFilename));
// TODO: should we use copyFile or copy?
await fs.copyFile(file.inputPath, outputFilename);
}
if (file.mode === 'write') {
await fs.outputFile(outputFilename, formatSource(file.src));
}
}
import { writeAdminFile } from '../../admin-ui/system/generateAdminUI';

const reexportKeystoneConfig = async (cwd: string, isDisabled?: boolean) => {
const projectAdminPath = getAdminPath(cwd);
Expand Down
14 changes: 9 additions & 5 deletions packages/keystone/src/scripts/run/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,31 @@ export const dev = async (cwd: string, shouldDropDatabase: boolean) => {
// Generate the Artifacts
console.log('✨ Generating GraphQL and Prisma schemas');
const prismaSchema = (await generateCommittedArtifacts(graphQLSchema, config, cwd)).prisma;
await generateNodeModulesArtifacts(graphQLSchema, config, cwd);
let keystonePromise = generateNodeModulesArtifacts(graphQLSchema, config, cwd).then(() => {
const prismaClient = requirePrismaClient(cwd);
return getKeystone(prismaClient);
});

let migrationPromise: Promise<void>;

// Set up the Database
if (config.db.useMigrations) {
await devMigrations(
migrationPromise = devMigrations(
config.db.url,
prismaSchema,
getSchemaPaths(cwd).prisma,
shouldDropDatabase
);
} else {
await pushPrismaSchemaToDatabase(
migrationPromise = pushPrismaSchemaToDatabase(
config.db.url,
prismaSchema,
getSchemaPaths(cwd).prisma,
shouldDropDatabase
);
}

const prismaClient = requirePrismaClient(cwd);
const keystone = getKeystone(prismaClient);
const [keystone] = await Promise.all([keystonePromise, migrationPromise]);
const { createContext } = keystone;

// Connect to the Database
Expand Down
Loading

0 comments on commit 930b712

Please sign in to comment.