diff --git a/.changeset/funny-bikes-switch.md b/.changeset/funny-bikes-switch.md new file mode 100644 index 00000000000..10e68ab666a --- /dev/null +++ b/.changeset/funny-bikes-switch.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/cli': minor +--- + +Changes watch mode to not use polling by default and adds configurable override diff --git a/packages/graphql-codegen-cli/src/utils/watcher.ts b/packages/graphql-codegen-cli/src/utils/watcher.ts index c65cfc1e3aa..02b77b89369 100644 --- a/packages/graphql-codegen-cli/src/utils/watcher.ts +++ b/packages/graphql-codegen-cli/src/utils/watcher.ts @@ -24,7 +24,7 @@ function emitWatching() { export const createWatcher = ( initalContext: CodegenContext, onNext: (result: Types.FileOutput[]) => Promise -) => { +): Promise => { debugLog(`[Watcher] Starting watcher...`); let config: Types.Config & { configFilePath?: string } = initalContext.getConfig(); const files: string[] = [initalContext.filepath].filter(a => a); @@ -94,9 +94,8 @@ export const createWatcher = ( followSymlinks: true, cwd: process.cwd(), disableGlobbing: false, - usePolling: true, - interval: 100, - binaryInterval: 300, + usePolling: config.watchConfig?.usePolling, + interval: config.watchConfig?.interval, depth: 99, awaitWriteFinish: true, ignorePermissionErrors: false, @@ -141,7 +140,7 @@ export const createWatcher = ( }; // the promise never resolves to keep process running - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { executeCodegen(initalContext) .then(onNext, () => Promise.resolve()) .then(runWatcher) diff --git a/packages/utils/plugins-helpers/src/types.ts b/packages/utils/plugins-helpers/src/types.ts index 9551c09c206..1624c330778 100644 --- a/packages/utils/plugins-helpers/src/types.ts +++ b/packages/utils/plugins-helpers/src/types.ts @@ -414,6 +414,17 @@ export namespace Types { * For more details: https://graphql-code-generator.com/docs/getting-started/development-workflow#watch-mode */ watch?: boolean | string | string[]; + /** + * @description Allows overriding the behavior of watch to use stat polling over native file watching support. + * + * Config fields have the same defaults and sematics as the identically named ones for chokidar. + * + * For more details: https://graphql-code-generator.com/docs/getting-started/development-workflow#watch-mode + */ + watchConfig?: { + usePolling: boolean; + interval?: number; + }; /** * @description A flag to suppress printing errors when they occur. */ diff --git a/website/docs/getting-started/development-workflow.md b/website/docs/getting-started/development-workflow.md index f7987b1dee1..960ececfcae 100644 --- a/website/docs/getting-started/development-workflow.md +++ b/website/docs/getting-started/development-workflow.md @@ -50,6 +50,17 @@ If you wish, you can specify a custom list of files to watch, by adding a glob e Use this when you are loading your schema or documents from a single code file, that depends on other files internally, because codegen can't tell that you using those files automatically. ::: +By default, watch mode uses the system's native support to listen for file change events. This can be configured in the settings file to use a stat polling method instead in unusual cases where system support is unavailable. + +```yml +watch: true +# Passed directly through to chokidar's file watch configuration +watchConfig: + usePolling: true + interval: 1000 +``` + + ### Monorepo and Yarn Workspaces If you are using a monorepo structure, with tools such as [Yarn Workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) or [Lerna](https://github.com/lerna/lerna), we recommend to install the codegen in the root of your monorepo.