From 9c546a799664df7877e980b3daf8353d8498fd9a Mon Sep 17 00:00:00 2001 From: Daniel Waltz Date: Mon, 31 Jan 2022 23:10:44 -0500 Subject: [PATCH] feat: Support disabling codegen in certain modes Adds a plugin config that provides support for disabling codegen under different modes --- README.md | 19 ++++++- src/helpers/isCodegenConfig.ts | 9 ++++ .../isGraphQLDocument.ts} | 21 -------- src/helpers/restartVite.ts | 13 +++++ src/helpers/viteModes.ts | 12 +++++ src/index.ts | 53 ++++++++++++++++--- 6 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 src/helpers/isCodegenConfig.ts rename src/{helpers.ts => helpers/isGraphQLDocument.ts} (61%) create mode 100644 src/helpers/restartVite.ts create mode 100644 src/helpers/viteModes.ts diff --git a/README.md b/README.md index e96025d..12a250a 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 @@ -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). diff --git a/src/helpers/isCodegenConfig.ts b/src/helpers/isCodegenConfig.ts new file mode 100644 index 0000000..415bdd5 --- /dev/null +++ b/src/helpers/isCodegenConfig.ts @@ -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; +} diff --git a/src/helpers.ts b/src/helpers/isGraphQLDocument.ts similarity index 61% rename from src/helpers.ts rename to src/helpers/isGraphQLDocument.ts index 578b696..fbacade 100644 --- a/src/helpers.ts +++ b/src/helpers/isGraphQLDocument.ts @@ -1,4 +1,3 @@ -import fs from 'fs'; import { CodegenContext } from '@graphql-codegen/cli'; import { normalizeInstanceOrArray } from '@graphql-codegen/plugin-helpers'; @@ -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')); - } -} diff --git a/src/helpers/restartVite.ts b/src/helpers/restartVite.ts new file mode 100644 index 0000000..7832396 --- /dev/null +++ b/src/helpers/restartVite.ts @@ -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')); + } +} diff --git a/src/helpers/viteModes.ts b/src/helpers/viteModes.ts new file mode 100644 index 0000000..cc9ca16 --- /dev/null +++ b/src/helpers/viteModes.ts @@ -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; diff --git a/src/index.ts b/src/index.ts index f70b10a..200846f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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) { @@ -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) { @@ -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 } };