Skip to content
Snippets Groups Projects

Task update2024

Merged Johannes Kreiner requested to merge task_update2024 into master
Compare and Show latest version
3 files
+ 135
219
Compare changes
  • Side-by-side
  • Inline
Files
3
+ 81
34
import Task from '../task.js';
import gaze from 'gaze';
import { watch } from 'chokidar';
import chalk from 'chalk';
import path from 'node:path';
import settings from '../settings.js';
import * as globby from 'globby';
/**
* The watch-task observes changes in source files and triggers compilation
*/
export default class Watch extends Task {
constructor() {
super();
this._isProcessing = false;
this._debounceTimeout = null;
this._debounceDelay = 1;
}
/**
* Runner function
*
@@ -25,58 +33,76 @@ export default class Watch extends Task {
* Watch for CSS-related files
*/
async _watchCss() {
let globs = [];
// Determine which extensions to watch
const extensions =
(this._config.watchExtensions || []).length > 0
? this._config.watchExtensions
: this._config.extensions;
// get a glob for each extension that shall be watched
((this._config.watchExtensions || []).length > 0
? this._config.watchExtensions
: this._config.extensions
).forEach((_extension) => {
// Create glob patterns for each extension
let globs = [];
extensions.forEach((_extension) => {
globs.push(
this._getGlobFor(_extension, `${this._config.directories.sass}/**/*.scss`),
this._getGlobFor(_extension, `${this._config.directories.svg}/**/*.svg`),
);
});
// assemble information about which files need to be watched
const ignoredFiles = ['!**/*_svg.scss'];
// Negative patterns to exclude certain files
const ignoredPatterns = ['!**/*_svg.scss'];
gaze([...globs, ...ignoredFiles], (error, watcher) => {
if (error) {
this._handleError(error.stack);
}
watcher.on('changed', this._onCssChange.bind(this));
watcher.on('added', this._onNewFile.bind(this));
// Use globby to resolve the final list of files
const filesToWatch = await globby.globby([...globs, ...ignoredPatterns]);
// Set up chokidar watcher
const watcher = watch(filesToWatch, {
ignoreInitial: true, // Only watch changes after initial scan
});
watcher.on('error', (error) => {
this._handleError(error.stack);
});
watcher.on('change', this._onCssChange.bind(this));
watcher.on('add', this._onNewFile.bind(this));
}
/**
* Watch for JS-related files
*/
async _watchJs() {
let globs = [];
// Determine which extensions to watch
const extensions =
(this._config.watchExtensions || []).length > 0
? this._config.watchExtensions
: this._config.extensions;
// get a glob for each extension that shall be watched
((this._config.watchExtensions || []).length > 0
? this._config.watchExtensions
: this._config.extensions
).forEach((_extension) => {
let globs = [];
extensions.forEach((_extension) => {
globs.push(
this._getGlobFor(_extension, `${this._config.directories.javascriptSrc}/**/*.js`),
this._getGlobFor(_extension, `${this._config.directories.javascriptSrc}/**/*.ts`),
);
});
// assemble information about which files need to be watched
const ignoredFiles = ['!**/*.min.js', ...this._config.js.excludeFromQa];
// Negative patterns or exclude patterns
const ignoredPatterns = ['!**/*.min.js', ...this._config.js.excludeFromQa];
gaze([...globs, ...ignoredFiles], (error, watcher) => {
if (error) {
this._logger.error(error.stack);
}
watcher.on('changed', this._onJsChange.bind(this));
watcher.on('added', this._onNewFile.bind(this));
// Use globby to resolve the final list of files
const filesToWatch = await globby.globby([...globs, ...ignoredPatterns]);
// Set up chokidar watcher
const watcher = watch(filesToWatch, {
ignoreInitial: true,
});
watcher.on('error', (error) => {
this._logger.error(error.stack);
});
// Map events similarly for JS
watcher.on('change', this._onJsChange.bind(this));
watcher.on('add', this._onNewFile.bind(this));
}
/**
@@ -89,6 +115,27 @@ export default class Watch extends Task {
return path.join(this._config.directories.basePath, _extension, _path);
}
/**
* Debounced trigger function with lock mechanism
* @param {Function} triggerFunction The function to trigger (either _triggerCss or _triggerJs)
* @returns {Promise<void>}
*/
async _debouncedTrigger(triggerFunction) {
if (this._isProcessing) {
return;
}
clearTimeout(this._debounceTimeout);
this._debounceTimeout = setTimeout(async () => {
try {
this._isProcessing = true;
await triggerFunction.call(this);
} finally {
this._isProcessing = false;
}
}, this._debounceDelay);
}
/**
* Trigger CSS-compilation
*/
@@ -108,24 +155,24 @@ export default class Watch extends Task {
}
/**
* This function will execute on file changes
* This function will execute on CSS file changes
*
* @param {String} _fileName The path to the file that changed
*/
_onCssChange(_fileName) {
this._setCurrentExtensionName(_fileName);
this._logger.info(`Change in ${chalk.white(path.basename(_fileName))}`);
this._triggerCss();
this._debouncedTrigger(this._triggerCss);
}
/**
* This function will execute on file changes
* This function will execute on JS file changes
*
* @param {String} _fileName The path to the file that changed
*/
_onJsChange(_fileName) {
this._logger.info(`Change in ${chalk.white(path.basename(_fileName))}`);
this._triggerJs();
this._debouncedTrigger(this._triggerJs);
}
/**
@@ -147,7 +194,7 @@ export default class Watch extends Task {
if (this._config.extensions[0] === '') {
return;
}
// the file path will contain backslashes instead of slashes on windows. we need to normalize this.
// normalize windows backslashes
let file = _file.replaceAll('\\', '/');
settings.setExtension(file.split(this._config.directories.basePath)[1].split('/')[0]);
}
Loading