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
+ 104
46
const Task = require('../task');
const gaze = require('gaze');
const chalk = require('chalk');
const path = require('path');
const settings = require('../settings');
import Task from '../task.js';
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
*/
module.exports = class Watch extends Task {
export default class Watch extends Task {
constructor() {
super();
this._isProcessing = false;
this._debounceTimeout = null;
this._debounceDelay = 1;
}
/**
* Runner function
@@ -16,7 +23,7 @@ module.exports = class Watch extends Task {
*/
async run() {
settings.setWatcherActive(true);
return new Promise(resolve => {
return new Promise(() => {
this._watchCss();
this._watchJs();
});
@@ -26,48 +33,76 @@ module.exports = 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 ? this._config.watchExtensions : this._config.extensions).forEach(_extension => {
globs.push(this._getGlobFor(_extension, `${this._config.directories.sass}/**/*.scss`));
globs.push(this._getGlobFor(_extension, `${this._config.directories.svg}/**/*.svg`));
// 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.concat(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 ? this._config.watchExtensions : this._config.extensions).forEach(_extension => {
globs.push(this._getGlobFor(_extension, `${this._config.directories.javascriptSrc}/**/*.js`));
globs.push(this._getGlobFor(_extension, `${this._config.directories.javascriptSrc}/**/*.ts`));
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'].concat(this._config.js.excludeFromQa);
// Negative patterns or exclude patterns
const ignoredPatterns = ['!**/*.min.js', ...this._config.js.excludeFromQa];
gaze(globs.concat(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));
}
/**
@@ -80,41 +115,64 @@ module.exports = 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
*/
_triggerCss() {
let task = this._settings.tasks.css();
new task().run();
async _triggerCss() {
const cssTaskModule = await this._settings.tasks.css();
const CssTask = cssTaskModule.default;
await new CssTask().run();
}
/**
* Trigger JS-compilation
*/
_triggerJs() {
let task = this._settings.tasks.js();
new task().run();
async _triggerJs() {
const jsTaskModule = await this._settings.tasks.js();
const JsTask = jsTaskModule.default;
await new JsTask().run();
}
/**
* 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);
}
/**
@@ -136,8 +194,8 @@ module.exports = 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.
let file = _file.replace(/\\/g, '/');
// normalize windows backslashes
let file = _file.replaceAll('\\', '/');
settings.setExtension(file.split(this._config.directories.basePath)[1].split('/')[0]);
}
};
}
Loading