Skip to content

Commit

Permalink
feat: Support disabling codegen in certain modes
Browse files Browse the repository at this point in the history
Adds a plugin config that provides support for disabling codegen under
different modes
  • Loading branch information
danielwaltz committed Feb 1, 2022
1 parent 92690a0 commit 9c546a7
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 29 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Experimental zero-config vite plugin that uses the vite file watcher to run [gra

Installation instructions found [here](https://www.graphql-code-generator.com/docs/getting-started/installation). Optional if already set up in project.

## Install
## Install Plugin

```bash
# npm
Expand All @@ -16,7 +16,7 @@ npm i -D vite-plugin-graphql-codegen
yarn add -D vite-plugin-graphql-codegen
```

## Initialize
## Initialize Plugin

```js
# vite.config.ts
Expand All @@ -31,4 +31,19 @@ export default defineConfig({
});
```

## Options

Providing options is not required as sensible defaults are in place, but there may be times where it's helpful to disable codegen under certain circumstances, like when running builds in CI.

```js
codegen({
/* Should codegen run when the dev server starts. Defaults to true. */
runOnStart: true,
/* Should codegen run on build. Will prevent build if codegen fails. Defaults to true. */
runOnBuild: true,
/* Should codegen run when files get added or change. Defaults to true. */
enableWatcher: true
})
```

Project bootstrapped with [TSDX](https://github.com/palmerhq/tsdx).
9 changes: 9 additions & 0 deletions src/helpers/isCodegenConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CodegenContext } from '@graphql-codegen/cli';

export function isCodegenConfig(
filePath: string,
context: CodegenContext
): boolean {
const configPath = context.filepath;
return configPath === filePath;
}
21 changes: 0 additions & 21 deletions src/helpers.ts → src/helpers/isGraphQLDocument.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fs from 'fs';
import { CodegenContext } from '@graphql-codegen/cli';
import { normalizeInstanceOrArray } from '@graphql-codegen/plugin-helpers';

Expand All @@ -22,23 +21,3 @@ export async function isGraphQLDocument(

return paths.some(documentPath => documentPath === filePath);
}

export function isCodegenConfig(
filePath: string,
context: CodegenContext
): boolean {
const configPath = context.filepath;
return configPath === filePath;
}

export function restartVite(fileName: string) {
if (!fileName) return;

const time = new Date();

try {
fs.utimesSync(fileName, time, time);
} catch (error) {
fs.closeSync(fs.openSync(fileName, 'w'));
}
}
13 changes: 13 additions & 0 deletions src/helpers/restartVite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import fs from 'fs';

export function restartVite(fileName: string) {
if (!fileName) return;

const time = new Date();

try {
fs.utimesSync(fileName, time, time);
} catch (error) {
fs.closeSync(fs.openSync(fileName, 'w'));
}
}
12 changes: 12 additions & 0 deletions src/helpers/viteModes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ConfigEnv } from 'vite';

export type ViteMode = ConfigEnv['command'];

const modes = {
serve: 'serve',
build: 'build',
} as { [K in ViteMode]: K };

export const isServeMode = (mode: ViteMode) => mode === modes.serve;

export const isBuildMode = (mode: ViteMode) => mode === modes.build;
53 changes: 47 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
import fs from 'fs';
import { Plugin } from 'vite';
import { CodegenContext, generate, loadContext } from '@graphql-codegen/cli';
import { isCodegenConfig, isGraphQLDocument, restartVite } from './helpers';
import { isCodegenConfig } from './helpers/isCodegenConfig';
import { isGraphQLDocument } from './helpers/isGraphQLDocument';
import { restartVite } from './helpers/restartVite';
import { ViteMode, isServeMode, isBuildMode } from './helpers/viteModes';

export interface Options {
/**
* Enable codegen in serve mode.
* @defaultValue `true`
*/
runOnStart?: boolean;
/**
* Enable codegen in build mode.
* @defaultValue `true`
*/
runOnBuild?: boolean;
/**
* Enable codegen integration with vite file watcher.
* @defaultValue `true`
*/
enableWatcher?: boolean;
}

const VITE_CONFIG_FILE_NAMES = ['vite.config.ts', 'vite.config.js'] as const;

export default function VitePluginGraphQLCodegen(): Plugin {
export default function VitePluginGraphQLCodegen(options?: Options): Plugin {
let codegenContext: CodegenContext;
let viteMode: ViteMode;
let viteConfigFileName: typeof VITE_CONFIG_FILE_NAMES[number];

const {
runOnStart = true,
runOnBuild = true,
enableWatcher = true, //
} = options ?? {};

return {
name: 'graphql-codegen',
async config(config) {
async config(config, env) {
codegenContext = await loadContext(config.root);

// Vite handles file watching
codegenContext.updateConfig({ watch: false });

viteMode = env.command;
},
configResolved() {
for (const fileName of VITE_CONFIG_FILE_NAMES) {
Expand All @@ -26,10 +56,19 @@ export default function VitePluginGraphQLCodegen(): Plugin {
}
},
async buildStart() {
const isServe = isServeMode(viteMode);
const isBuild = isBuildMode(viteMode);

if (isServe && !runOnStart) return;
if (isBuild && !runOnBuild) return;

try {
await generate(codegenContext);
} catch (error) {
// GraphQL Codegen handles printing errors
// Prevent build if codegen fails
if (isBuild) throw error;

// GraphQL Codegen handles logging useful errors
}
},
configureServer(server) {
Expand All @@ -41,18 +80,20 @@ export default function VitePluginGraphQLCodegen(): Plugin {
return;
}

if (!enableWatcher) return;

try {
const isDocument = await isGraphQLDocument(filePath, codegenContext);

if (!isDocument) return;
} catch {
// GraphQL Codegen handles printing errors
// GraphQL Codegen handles logging useful errors
}

try {
await generate(codegenContext);
} catch (error) {
// GraphQL Codegen handles printing errors
// GraphQL Codegen handles logging useful errors
}
};

Expand Down

0 comments on commit 9c546a7

Please sign in to comment.