From 0b7bdc2b9379e027e9ebae186bc65663a8828215 Mon Sep 17 00:00:00 2001 From: Ken Chau Date: Thu, 1 Oct 2020 10:54:35 -0700 Subject: [PATCH 1/2] adds some safe-guard against stalling with node-sass in sassTask --- packages/just-scripts/src/tasks/sassTask.ts | 51 +++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/packages/just-scripts/src/tasks/sassTask.ts b/packages/just-scripts/src/tasks/sassTask.ts index 9a57e8d2..6a2b1c46 100644 --- a/packages/just-scripts/src/tasks/sassTask.ts +++ b/packages/just-scripts/src/tasks/sassTask.ts @@ -10,6 +10,8 @@ export interface SassTaskOptions { postcssPlugins?: any[]; } +let processHandlerSet = false; + export function sassTask(options: SassTaskOptions): TaskFunction; /** @deprecated Use object param version */ export function sassTask(createSourceModule: (fileName: string, css: string) => string, postcssPlugins?: any[]): TaskFunction; @@ -17,6 +19,9 @@ export function sassTask( optionsOrCreateSourceModule: SassTaskOptions | ((fileName: string, css: string) => string), postcssPlugins?: any[] ): TaskFunction { + // node-sass causes strange behavior when it fails. It sometimes hangs the whole process + setUncaughtExceptionHandler(); + let createSourceModule: (fileName: string, css: string) => string; if (typeof optionsOrCreateSourceModule === 'function') { createSourceModule = optionsOrCreateSourceModule; @@ -35,7 +40,7 @@ export function sassTask( if (!nodeSass || !postcss || !autoprefixer) { logger.warn('One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect'); - done(); + cleanUpAndDone(done); return; } @@ -84,9 +89,9 @@ export function sassTask( } ); - parallelLimit(tasks, 5, done); + parallelLimit(tasks, 5, err => cleanUpAndDone(done, err)); } else { - done(); + cleanUpAndDone(done); } }; } @@ -107,3 +112,43 @@ function patchSassUrl(url: string, _prev: string, _done: any) { return { file: newUrl }; } + +/** + * sets up an uncaughtException handler for node-sass + */ +function setUncaughtExceptionHandler() { + if (!processHandlerSet) { + processHandlerSet = true; + process.on('uncaughtException', uncaughtExceptionHandler); + } +} + +/** + * unsets the uncaughtException handler for node-sass + */ +function unsetUncaughtExceptionHandler() { + if (processHandlerSet) { + processHandlerSet = false; + process.off('uncaughtException', uncaughtExceptionHandler); + } +} + +/** + * The uncaughtExceptionHandler is a work around for node-sass hanging + * See: https://github.com/sass/node-sass/issues/1048 + * @param e + */ +function uncaughtExceptionHandler(e: Error) { + console.error(e.stack); + process.kill(process.pid, 'SIGINT'); +} + +/** + * In order for us to clean up the exception handler, we attach the clean up to the "done" callback + * @param done + * @param e + */ +function cleanUpAndDone(done: (e?: Error) => void, e?: Error) { + unsetUncaughtExceptionHandler(); + return done(e); +} From d04ffe78e6eaef6993d518639ebc288b89fd98ec Mon Sep 17 00:00:00 2001 From: Ken Chau Date: Thu, 1 Oct 2020 10:54:45 -0700 Subject: [PATCH 2/2] Change files --- change/just-scripts-2020-10-01-10-54-45-node-sass.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 change/just-scripts-2020-10-01-10-54-45-node-sass.json diff --git a/change/just-scripts-2020-10-01-10-54-45-node-sass.json b/change/just-scripts-2020-10-01-10-54-45-node-sass.json new file mode 100644 index 00000000..81860445 --- /dev/null +++ b/change/just-scripts-2020-10-01-10-54-45-node-sass.json @@ -0,0 +1,8 @@ +{ + "type": "patch", + "comment": "adds some safe-guard against stalling with node-sass in sassTask", + "packageName": "just-scripts", + "email": "kchau@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-10-01T17:54:45.328Z" +}