fix(@embark/watcher): endless loop when artifacts are put in src

The problem was that putting the artifacts in src caused them to be watched
and thus creating an infinite loop, because a change in src triggers the build of the artifacts
This was fixed by ignoring the artifacts by chokidar, wherever they are
This commit is contained in:
Jonathan Rainville 2020-01-03 13:37:42 -05:00
parent 89dceabc2b
commit c8f86e55f0
1 changed files with 36 additions and 45 deletions

View File

@ -7,13 +7,11 @@ const DAPP_PIPELINE_CONFIG_FILE = 'pipeline.js';
const DAPP_WEBPACK_CONFIG_FILE = 'webpack.config.js'; const DAPP_WEBPACK_CONFIG_FILE = 'webpack.config.js';
const DAPP_BABEL_LOADER_OVERRIDES_CONFIG_FILE = 'babel-loader-overrides.js'; const DAPP_BABEL_LOADER_OVERRIDES_CONFIG_FILE = 'babel-loader-overrides.js';
// TODO: this should be receiving the config object not re-reading the
// embark.json file
// TODO: rename file events to comply with naming convention // TODO: rename file events to comply with naming convention
class Watcher { class Watcher {
constructor(embark) { constructor(embark) {
this.embarkConfig = embark.config.embarkConfig;
this.logger = embark.logger; this.logger = embark.logger;
this.events = embark.events; this.events = embark.events;
this.fs = embark.fs; this.fs = embark.fs;
@ -26,29 +24,24 @@ class Watcher {
// TODO: it needs to be more agnostic, the files to watch should be registered through the plugin api // TODO: it needs to be more agnostic, the files to watch should be registered through the plugin api
start(cb) { start(cb) {
let self = this; this.watchAssets(this.embarkConfig, () => {
// TODO: should come from the config object instead of reading the file this.logger.trace('ready to watch asset changes');
// directly
let embarkConfig = this.fs.readJSONSync("embark.json");
this.watchAssets(embarkConfig, function () {
self.logger.trace('ready to watch asset changes');
}); });
this.watchContracts(embarkConfig, function () { this.watchContracts(this.embarkConfig, () => {
self.logger.trace('ready to watch contract changes'); this.logger.trace('ready to watch contract changes');
}); });
this.watchContractConfig(embarkConfig, function () { this.watchContractConfig(this.embarkConfig, () => {
self.logger.trace('ready to watch contract config changes'); this.logger.trace('ready to watch contract config changes');
}); });
this.watchPipelineConfig(embarkConfig, function () { this.watchPipelineConfig(this.embarkConfig, () => {
self.logger.trace('ready to watch pipeline config changes'); this.logger.trace('ready to watch pipeline config changes');
}); });
this.watchWebserverConfig(embarkConfig, function () { this.watchWebserverConfig(this.embarkConfig, () => {
self.logger.trace('ready to watch webserver config changes'); this.logger.trace('ready to watch webserver config changes');
}); });
this.logger.info(__("ready to watch file changes")); this.logger.info(__("ready to watch file changes"));
@ -69,7 +62,6 @@ class Watcher {
} }
watchAssets(embarkConfig, callback) { watchAssets(embarkConfig, callback) {
let self = this;
let appConfig = embarkConfig.app; let appConfig = embarkConfig.app;
let filesToWatch = []; let filesToWatch = [];
@ -92,34 +84,32 @@ class Watcher {
this.watchFiles( this.watchFiles(
filesToWatch, filesToWatch,
function (eventName, path) { (eventName, path) => {
self.logger.info(`${eventName}: ${path}`); this.logger.info(`${eventName}: ${path}`);
self.events.emit('file-' + eventName, 'asset', path); this.events.emit('file-' + eventName, 'asset', path);
self.events.emit('file-event', {fileType: 'asset', path}); this.events.emit('file-event', {fileType: 'asset', path});
}, },
function () { () => {
callback(); callback();
} }
); );
} }
watchContracts(embarkConfig, callback) { watchContracts(embarkConfig, callback) {
let self = this;
this.watchFiles( this.watchFiles(
[embarkConfig.contracts], [embarkConfig.contracts],
function (eventName, path) { (eventName, path) => {
self.logger.info(`${eventName}: ${path}`); this.logger.info(`${eventName}: ${path}`);
self.events.emit('file-' + eventName, 'contract', path); this.events.emit('file-' + eventName, 'contract', path);
self.events.emit('file-event', {fileType: 'contract', path}); this.events.emit('file-event', {fileType: 'contract', path});
}, },
function () { () => {
callback(); callback();
} }
); );
} }
watchWebserverConfig(embarkConfig, callback) { watchWebserverConfig(embarkConfig, callback) {
let self = this;
let webserverConfig; let webserverConfig;
if (typeof embarkConfig.config === 'object') { if (typeof embarkConfig.config === 'object') {
if (!embarkConfig.config.webserver) { if (!embarkConfig.config.webserver) {
@ -134,18 +124,17 @@ class Watcher {
webserverConfig = [`${contractsFolder}**/webserver.json`, `${contractsFolder}**/webserver.js`]; webserverConfig = [`${contractsFolder}**/webserver.json`, `${contractsFolder}**/webserver.js`];
} }
this.watchFiles(webserverConfig, this.watchFiles(webserverConfig,
function (eventName, path) { (eventName, path) => {
self.logger.info(`${eventName}: ${path}`); this.logger.info(`${eventName}: ${path}`);
self.events.emit('webserver:config:change', 'config', path); this.events.emit('webserver:config:change', 'config', path);
}, },
function () { () => {
callback(); callback();
} }
); );
} }
watchContractConfig(embarkConfig, callback) { watchContractConfig(embarkConfig, callback) {
let self = this;
let contractConfig; let contractConfig;
if (typeof embarkConfig.config === 'object' || embarkConfig.config.contracts) { if (typeof embarkConfig.config === 'object' || embarkConfig.config.contracts) {
contractConfig = embarkConfig.config.contracts; contractConfig = embarkConfig.config.contracts;
@ -157,12 +146,12 @@ class Watcher {
contractConfig = [`${contractsFolder}**/contracts.json`, `${contractsFolder}**/contracts.js`]; contractConfig = [`${contractsFolder}**/contracts.json`, `${contractsFolder}**/contracts.js`];
} }
this.watchFiles(contractConfig, this.watchFiles(contractConfig,
function (eventName, path) { (eventName, path) => {
self.logger.info(`${eventName}: ${path}`); this.logger.info(`${eventName}: ${path}`);
self.events.emit('file-' + eventName, 'config', path); this.events.emit('file-' + eventName, 'config', path);
self.events.emit('file-event', {fileType: 'config', path}); this.events.emit('file-event', {fileType: 'config', path});
}, },
function () { () => {
callback(); callback();
} }
); );
@ -191,11 +180,13 @@ class Watcher {
this.logger.trace('watchFiles'); this.logger.trace('watchFiles');
this.logger.trace(files); this.logger.trace(files);
let configWatcher = chokidar.watch(files, {
// FIXME this should be handled by the nim-compiler plugin somehow // FIXME this should be handled by the nim-compiler plugin somehow
// panicoverride.nim is a file added by nimplay when compiling but then removed // panicoverride.nim is a file added by nimplay when compiling but then removed
// If we don't ignore that file, we start an inifite loop of compilation // If we don't ignore that file, we start an inifite loop of compilation
ignored: /[\/\\]\.|tmp_|panicoverride\.nim/, persistent: true, ignoreInitial: true, followSymlinks: true const ignored = new RegExp(`[\\/\\\\]\\.|tmp_|panicoverride\.nim|${path.basename(this.embarkConfig.generationDir)}`);
let configWatcher = chokidar.watch(files, {
ignored, persistent: true, ignoreInitial: true, followSymlinks: true
}); });
this.fileWatchers.push(configWatcher); this.fileWatchers.push(configWatcher);