diff --git a/src/modules.mjs b/src/modules.mjs index d05f1bb9b8dce..a13236f846beb 100644 --- a/src/modules.mjs +++ b/src/modules.mjs @@ -223,6 +223,22 @@ function getTempDir() { return tempDir; } +function preprocessFiles(filenames) { + const results = {}; + for (const filename of filenames) { + debugLog(`pre-processing JS library: ${filename}`); + pushCurrentFile(filename); + try { + results[filename] = processMacros(preprocess(filename), filename); + } catch (e) { + error(`error preprocessing JS library "${filename}":`); + throw e; + } finally { + popCurrentFile(); + } + } + return results; +} export const LibraryManager = { library: {}, @@ -251,6 +267,13 @@ export const LibraryManager = { // Save the list for has() queries later. this.libraries = calculateLibraries(); + const preprocessed = preprocessFiles(this.libraries); + for (const [filename, contents] of Object.entries(preprocessed)) { + this.executeJSLibraryFile(filename, contents); + } + }, + + executeJSLibraryFile(filename, contents) { const userLibraryProxy = new Proxy(this.library, { set(target, prop, value) { target[prop] = value; @@ -261,52 +284,47 @@ export const LibraryManager = { }, }); - for (let filename of this.libraries) { - const isUserLibrary = !isBeneath(filename, systemLibdir); + const isUserLibrary = !isBeneath(filename, systemLibdir); + if (isUserLibrary) { + debugLog(`executing user JS library: ${filename}`); + } else { + debugLog(`exectuing system JS library: ${filename}`); + } - if (isUserLibrary) { - debugLog('processing user library: ' + filename); - } else { - debugLog('processing system library: ' + filename); - } - let origLibrary = undefined; - let processed = undefined; - // When we parse user libraries also set `__user` attribute - // on each element so that we can distinguish them later. - if (isUserLibrary) { - origLibrary = this.library; - this.library = userLibraryProxy; - } - pushCurrentFile(filename); - let preprocessedName = filename.replace(/\.\w+$/, '.preprocessed$&') + let origLibrary; + // When we parse user libraries also set `__user` attribute + // on each element so that we can distinguish them later. + if (isUserLibrary) { + origLibrary = this.library; + this.library = userLibraryProxy; + } + pushCurrentFile(filename); + let preprocessedName = filename.replace(/\.\w+$/, '.preprocessed$&') + if (VERBOSE) { + preprocessedName = path.join(getTempDir(), path.basename(filename)); + } + + try { + runInMacroContext(contents, {filename: preprocessedName}) + } catch (e) { + error(`failure to execute JS library "${filename}":`); if (VERBOSE) { - preprocessedName = path.join(getTempDir(), path.basename(filename)); - } - try { - processed = processMacros(preprocess(filename), filename); - runInMacroContext(processed, {filename: preprocessedName}) - } catch (e) { - error(`failure to execute JS library "${filename}":`); - if (processed) { - if (VERBOSE) { - fs.writeFileSync(preprocessedName, processed); - error(`preprocessed JS saved to ${preprocessedName}`) - } else { - error('use -sVERBOSE to save preprocessed JS'); - } - } - throw e; - } finally { - popCurrentFile(); - if (origLibrary) { - this.library = origLibrary; - } + fs.writeFileSync(preprocessedName, contents); + error(`preprocessed JS saved to ${preprocessedName}`) + } else { + error('use -sVERBOSE to save preprocessed JS'); } - if (VERBOSE) { - fs.rmSync(getTempDir(), { recursive: true, force: true }); + throw e; + } finally { + popCurrentFile(); + if (origLibrary) { + this.library = origLibrary; } } - }, + if (VERBOSE) { + fs.rmSync(getTempDir(), { recursive: true, force: true }); + } + } }; // options is optional input object containing mergeInto params