From 981e0aebc5cf2e5fc42b33226dba8c9c2f1c7351 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Wed, 2 Sep 2020 06:40:22 -0500 Subject: [PATCH] fix(watch): fix config.watchIgnoredRegex and update w/ RegExp array --- src/compiler/build/watch-build.ts | 9 ++++-- .../config/test/validate-config.spec.ts | 29 +++++++++++++++++++ src/compiler/config/validate-config.ts | 10 +++++++ src/compiler/fs-watch/fs-watch-rebuild.ts | 11 ++++++- src/declarations/stencil-public-compiler.ts | 7 ++++- 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/compiler/build/watch-build.ts b/src/compiler/build/watch-build.ts index 76fa3197bd9..1e5d1983574 100644 --- a/src/compiler/build/watch-build.ts +++ b/src/compiler/build/watch-build.ts @@ -9,6 +9,7 @@ import { hasHtmlChanges, hasScriptChanges, hasStyleChanges, + isWatchIgnorePath, scriptsAdded, scriptsDeleted, } from '../fs-watch/fs-watch-rebuild'; @@ -78,7 +79,9 @@ export const createWatchBuild = async (config: d.Config, compilerCtx: d.Compiler const watchingFiles = new Map(); const onFsChange: d.CompilerFileWatcherCallback = (p, eventKind) => { - if (tsWatchProgram) { + if (tsWatchProgram && isWatchIgnorePath(config, p)) { + config.watchIgnoredRegex; + updateCompilerCtxCache(config, compilerCtx, p, eventKind); switch (eventKind) { @@ -131,13 +134,13 @@ export const createWatchBuild = async (config: d.Config, compilerCtx: d.Compiler const request = async (data: d.CompilerRequest) => compilerRequest(config, compilerCtx, data); compilerCtx.addWatchFile = filePath => { - if (isString(filePath) && !watchingFiles.has(filePath)) { + if (isString(filePath) && !watchingFiles.has(filePath) && !isWatchIgnorePath(config, filePath)) { watchingFiles.set(filePath, config.sys.watchFile(filePath, onFsChange)); } }; compilerCtx.addWatchDir = (dirPath, recursive) => { - if (isString(dirPath) && !watchingDirs.has(dirPath)) { + if (isString(dirPath) && !watchingDirs.has(dirPath) && !isWatchIgnorePath(config, dirPath)) { watchingDirs.set(dirPath, config.sys.watchDirectory(dirPath, onDirChange, recursive)); } }; diff --git a/src/compiler/config/test/validate-config.spec.ts b/src/compiler/config/test/validate-config.spec.ts index 4791b42cb73..5277e016ec5 100644 --- a/src/compiler/config/test/validate-config.spec.ts +++ b/src/compiler/config/test/validate-config.spec.ts @@ -1,5 +1,6 @@ import type * as d from '@stencil/core/declarations'; import { mockLogger, mockStencilSystem } from '@stencil/core/testing'; +import { isWatchIgnorePath } from '../../fs-watch/fs-watch-rebuild'; import { validateConfig } from '../validate-config'; describe('validation', () => { @@ -341,4 +342,32 @@ describe('validation', () => { const { config } = validateConfig(userConfig); expect(config.taskQueue).toBe('congestionAsync'); }); + + it('empty watchIgnoredRegex, all valid', () => { + const { config } = validateConfig(userConfig); + expect(config.watchIgnoredRegex).toEqual([]); + expect(isWatchIgnorePath(config, '/some/image.gif')).toBe(false); + expect(isWatchIgnorePath(config, '/some/typescript.ts')).toBe(false); + }); + + it('should change a single watchIgnoredRegex to an array', () => { + userConfig.watchIgnoredRegex = /\.(gif|jpe?g|png)$/i; + const { config } = validateConfig(userConfig); + expect(config.watchIgnoredRegex).toHaveLength(1); + expect((config.watchIgnoredRegex as any[])[0]).toEqual(/\.(gif|jpe?g|png)$/i); + expect(isWatchIgnorePath(config, '/some/image.gif')).toBe(true); + expect(isWatchIgnorePath(config, '/some/typescript.ts')).toBe(false); + }); + + it('should clean up valid watchIgnoredRegex', () => { + userConfig.watchIgnoredRegex = [/\.(gif|jpe?g)$/i, null, 'me-regex' as any, /\.(png)$/i]; + const { config } = validateConfig(userConfig); + expect(config.watchIgnoredRegex).toHaveLength(2); + expect((config.watchIgnoredRegex as any[])[0]).toEqual(/\.(gif|jpe?g)$/i); + expect((config.watchIgnoredRegex as any[])[1]).toEqual(/\.(png)$/i); + expect(isWatchIgnorePath(config, '/some/image.gif')).toBe(true); + expect(isWatchIgnorePath(config, '/some/image.jpg')).toBe(true); + expect(isWatchIgnorePath(config, '/some/image.png')).toBe(true); + expect(isWatchIgnorePath(config, '/some/typescript.ts')).toBe(false); + }); }); diff --git a/src/compiler/config/validate-config.ts b/src/compiler/config/validate-config.ts index 9174c1078ab..d3df3700d65 100644 --- a/src/compiler/config/validate-config.ts +++ b/src/compiler/config/validate-config.ts @@ -119,6 +119,16 @@ export const validateConfig = (userConfig?: Config) => { setBooleanConfig(config, 'enableCache', 'cache', true); + if (!Array.isArray(config.watchIgnoredRegex) && config.watchIgnoredRegex != null) { + config.watchIgnoredRegex = [config.watchIgnoredRegex]; + } + config.watchIgnoredRegex = ((config.watchIgnoredRegex as RegExp[]) || []).reduce((arr, reg) => { + if (reg instanceof RegExp) { + arr.push(reg); + } + return arr; + }, [] as RegExp[]); + return { config, diagnostics, diff --git a/src/compiler/fs-watch/fs-watch-rebuild.ts b/src/compiler/fs-watch/fs-watch-rebuild.ts index 40aaf6f680e..505dcce0df5 100644 --- a/src/compiler/fs-watch/fs-watch-rebuild.ts +++ b/src/compiler/fs-watch/fs-watch-rebuild.ts @@ -1,6 +1,6 @@ import type * as d from '../../declarations'; import { basename } from 'path'; -import { unique } from '@utils'; +import { isString, unique } from '@utils'; export const filesChanged = (buildCtx: d.BuildCtx) => { // files changed include updated, added and deleted @@ -77,3 +77,12 @@ export const updateCacheFromRebuild = (compilerCtx: d.CompilerCtx, buildCtx: d.B compilerCtx.fs.clearDirCache(dirDeleted); }); }; + +export const isWatchIgnorePath = (config: d.Config, path: string) => { + if (isString(path)) { + return (config.watchIgnoredRegex as RegExp[]).some(reg => { + return reg.test(path); + }); + } + return false; +}; diff --git a/src/declarations/stencil-public-compiler.ts b/src/declarations/stencil-public-compiler.ts index 6fd0b7504af..0c3eeee17e9 100644 --- a/src/declarations/stencil-public-compiler.ts +++ b/src/declarations/stencil-public-compiler.ts @@ -214,7 +214,12 @@ export interface StencilConfig { sys?: CompilerSystem; tsconfig?: string; validateTypes?: boolean; - watchIgnoredRegex?: RegExp; + /** + * An array of RegExp patterns that are matched against all source files before adding + * to the watch list in watch mode. If the file path matches any of the patterns, when it + * is updated, it will not trigger a re-run of tests. + */ + watchIgnoredRegex?: RegExp | RegExp[]; excludeUnusedDependencies?: boolean; stencilCoreResolvedId?: string; }