From 9dcf21578cb7e415e9670cd076182ee3c9b67a6b Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:33:57 +0100 Subject: Immediately reject modules if the compilation already failed --- src/index.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index cc779f7..b151d82 100644 --- a/src/index.js +++ b/src/index.js @@ -40,6 +40,7 @@ var CACHE_VAR = { errors: [], compilationStarted: false, compilationFinished: false, + compilationFailed: false, installed: false, srcOption: [] }; @@ -147,6 +148,7 @@ module.exports = function purescriptLoader(source, map) { errors: [], compilationStarted: false, compilationFinished: false, + compilationFailed: false, installed: CACHE_VAR.installed, srcOption: [] }; @@ -258,6 +260,8 @@ module.exports = function purescriptLoader(source, map) { ) ) .catch(error => { + CACHE_VAR.compilationFailed = true; + CACHE_VAR.deferred[0].reject(error); CACHE_VAR.deferred.slice(1).forEach(psModule => { @@ -265,8 +269,9 @@ module.exports = function purescriptLoader(source, map) { }) }) ; - } - else { + } else if (CACHE_VAR.compilationFailed) { + CACHE_VAR.deferred.pop().reject(new Error('purs-loader failed')); + } else { // The compilation has started. We must wait until it is // done in order to ensure the module map contains all of // the unknown modules. @@ -318,6 +323,8 @@ module.exports = function purescriptLoader(source, map) { ) ) .catch(error => { + CACHE_VAR.compilationFailed = true; + CACHE_VAR.deferred[0].reject(error); CACHE_VAR.deferred.slice(1).forEach(psModule => { @@ -325,8 +332,9 @@ module.exports = function purescriptLoader(source, map) { }) }) ; - } - else { + } else if (CACHE_VAR.compilationFailed) { + CACHE_VAR.deferred.pop().reject(new Error('purs-loader failed')); + } else { // The complation has started. Nothing to do but wait until it is // done before loading all of the modules. } -- cgit v1.2.3 From f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:37:46 +0100 Subject: Watch failed modules and their dependencies on compilation error --- src/index.js | 37 ++++++++++++++++++++++++++++++++++--- src/utils.js | 23 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/utils.js diff --git a/src/index.js b/src/index.js index b151d82..fce6394 100644 --- a/src/index.js +++ b/src/index.js @@ -26,6 +26,8 @@ const sourceMaps = require('./source-maps'); const dargs = require('./dargs'); +const utils = require('./utils'); + const spawn = require('cross-spawn').sync const eol = require('os').EOL @@ -186,9 +188,38 @@ module.exports = function purescriptLoader(source, map) { CACHE_VAR.warnings.push(warning); } }, - emitError: error => { - if (error.length) { - CACHE_VAR.errors.push(error); + emitError: pscMessage => { + if (pscMessage.length) { + const matchErrorsSeparator = /\n(?=Error)/; + const errors = pscMessage.split(matchErrorsSeparator); + for (const error of errors) { + const matchErrLocation = /at (.+\.purs) line (\d+), column (\d+) - line (\d+), column (\d+)/; + const [, filename] = matchErrLocation.exec(error) || []; + if (!filename) continue; + + const baseModulePath = path.join(this.rootContext, filename); + this.addDependency(baseModulePath); + + const matchErrModuleName = /in module ((?:\w+\.)*\w+)/; + const [, baseModuleName] = matchErrModuleName.exec(error) || []; + if (!baseModuleName) continue; + + const matchMissingModuleName = /Module ((?:\w+\.)*\w+) was not found/; + const matchMissingImportFromModuleName = /Cannot import value \w+ from module ((?:\w+\.)*\w+)/; + for (const re of [matchMissingModuleName, matchMissingImportFromModuleName]) { + const [, targetModuleName] = re.exec(error) || []; + if (targetModuleName) { + const resolved = utils.resolvePursModule({ + baseModulePath, + baseModuleName, + targetModuleName + }); + this.addDependency(resolved); + } + } + } + + CACHE_VAR.errors.push(pscMessage); } } } diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..0ab00eb --- /dev/null +++ b/src/utils.js @@ -0,0 +1,23 @@ +const path = require('path'); + +const repeat = (value, times) => + times <= 0 ? [] : [value, ...repeat(value, times - 1)]; +const diffPursModuleNames = (from, target, parts) => { + if (!from.length) return parts.concat(target); + if (!target.length) return parts.concat(repeat('..', from.length)); + const [head_from, ...tail_from] = from; + const [head_target, ...tail_target] = target; + return head_from === head_target + ? diffPursModuleNames(tail_from, tail_target, parts) + : parts.concat(repeat('..', from.length), target); +}; +exports.resolvePursModule = ({ baseModulePath, baseModuleName, targetModuleName }) => { + const parts = diffPursModuleNames( + baseModuleName.split('.'), + targetModuleName.split('.'), + []); + return parts.length + ? path.resolve(baseModulePath, + `${path.join(...parts)}.purs`) + : baseModulePath; +}; -- cgit v1.2.3 From d8567b87b91abac0a428874cf5fdebb1b0d90ef0 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:39:56 +0100 Subject: Allow previous loaders to extract dependencies to watch from errors --- src/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/index.js b/src/index.js index fce6394..ec9af5f 100644 --- a/src/index.js +++ b/src/index.js @@ -217,6 +217,14 @@ module.exports = function purescriptLoader(source, map) { this.addDependency(resolved); } } + + if (typeof this.extractPursDependenciesFromError === 'function') { + const dependencies = this.extractPursDependenciesFromError(error) || []; + + for (const dep of dependencies) { + this.addDependency(dep); + } + } } CACHE_VAR.errors.push(pscMessage); -- cgit v1.2.3 From 7d28a10594c370194b8c23dfa95e533b2b6067b2 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:50:55 +0100 Subject: Annotate errors to prevent redundant parsing by other loaders --- src/index.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index ec9af5f..0b4ecf8 100644 --- a/src/index.js +++ b/src/index.js @@ -190,6 +190,8 @@ module.exports = function purescriptLoader(source, map) { }, emitError: pscMessage => { if (pscMessage.length) { + const modules = []; + const matchErrorsSeparator = /\n(?=Error)/; const errors = pscMessage.split(matchErrorsSeparator); for (const error of errors) { @@ -218,6 +220,11 @@ module.exports = function purescriptLoader(source, map) { } } + const desc = { + name: baseModuleName, + filename: baseModulePath + }; + if (typeof this.extractPursDependenciesFromError === 'function') { const dependencies = this.extractPursDependenciesFromError(error) || []; @@ -225,9 +232,11 @@ module.exports = function purescriptLoader(source, map) { this.addDependency(dep); } } + + modules.push(desc); } - CACHE_VAR.errors.push(pscMessage); + CACHE_VAR.errors.push(Object.assign(new Error(pscMessage), { modules })); } } } -- cgit v1.2.3 From 1142175778cdc21add2d4b494a02c53050856aa5 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:52:09 +0100 Subject: Allow previous loaders to further describe errors --- src/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 0b4ecf8..01ad5a6 100644 --- a/src/index.js +++ b/src/index.js @@ -225,12 +225,14 @@ module.exports = function purescriptLoader(source, map) { filename: baseModulePath }; - if (typeof this.extractPursDependenciesFromError === 'function') { - const dependencies = this.extractPursDependenciesFromError(error) || []; + if (typeof this.describePscError === 'function') { + const { dependencies = [], details } = this.describePscError(error, desc); for (const dep of dependencies) { this.addDependency(dep); } + + Object.assign(desc, details); } modules.push(desc); -- cgit v1.2.3 From e3de0f7156c579e5db05e6cb895df3884e8b9cdd Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:53:45 +0100 Subject: Tag errors with a specific constructor to simplify their detection --- src/index.js | 2 +- src/utils.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 01ad5a6..8a2e468 100644 --- a/src/index.js +++ b/src/index.js @@ -238,7 +238,7 @@ module.exports = function purescriptLoader(source, map) { modules.push(desc); } - CACHE_VAR.errors.push(Object.assign(new Error(pscMessage), { modules })); + CACHE_VAR.errors.push(new utils.PscError(pscMessage, modules)); } } } diff --git a/src/utils.js b/src/utils.js index 0ab00eb..671b580 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,16 @@ const path = require('path'); +exports.PscError = class PscError extends Error { + constructor(message, modules) { + super(message); + this.modules = modules; + } + + static get name() { + return 'PscError'; + } +}; + const repeat = (value, times) => times <= 0 ? [] : [value, ...repeat(value, times - 1)]; const diffPursModuleNames = (from, target, parts) => { -- cgit v1.2.3 From 65d0bcab6687d015198a4e4b56747cc29ad2fdd1 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:57:08 +0100 Subject: Allow utils to be required with `purs-loader/utils` --- utils.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 utils.js diff --git a/utils.js b/utils.js new file mode 100644 index 0000000..cec6101 --- /dev/null +++ b/utils.js @@ -0,0 +1 @@ +module.exports = require('./lib/utils'); -- cgit v1.2.3 From a30f8b466b7746ec4f29ce68452af4c238f2d8b2 Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 12:06:03 +0100 Subject: Version 3.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b5b1ba..7383175 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "purs-loader", - "version": "3.2.0", + "version": "3.3.0", "description": "A webpack loader for PureScript.", "main": "lib/index.js", "files": [ -- cgit v1.2.3