UNPKG

assetgraph

Version:

An auto discovery dependency graph based optimization framework for web pages and applications

179 lines (166 loc) 5.87 kB
const chalk = require('chalk'); const _ = require('lodash'); const Path = require('path'); const urlTools = require('urltools'); const AssetGraph = require('../AssetGraph'); function indentSubsequentLines(str, level) { return str.replace(/\n/g, `\n${new Array(level + 1).join(' ')}`); } function escapeRegExpMetaChars(str) { return str.replace(/[$.^()[\]{}]/g, '\\$&'); } module.exports = ({ afterTransform, repl, stopOnWarning, console } = {}) => { console = console || global.console; let startReplRegExp; if (repl) { startReplRegExp = new RegExp( _.flatten( _.flatten([repl]).map((transformName) => transformName.split(',')) ) .map((transformName) => transformName.replace(/[.+{}[]()?^$]/g, '\\$&')) .join('|') ); } return function logEvents(assetGraph) { const assetGraphRootRelativeToCwd = Path.relative( process.cwd(), urlTools.fileUrlToFsPath(assetGraph.root) ); const assetGraphRootRelativeToCwdRegExp = new RegExp( `\\b${escapeRegExpMetaChars(assetGraphRootRelativeToCwd)}/`, 'g' ); const cwdRegExp = new RegExp( `(?:file://)?${escapeRegExpMetaChars(`${process.cwd()}/`)}`, 'g' ); const colorBySeverity = { info: 'cyan', warn: 'yellow', error: 'red' }; const symbolBySeverity = { info: 'ℹ', warn: '⚠', error: '✘' }; function outputMessage(messageOrError, severity) { severity = severity || 'info'; let message; if (Object.prototype.toString.call(messageOrError) === '[object Error]') { if (severity === 'error') { message = messageOrError.stack; } else { message = messageOrError.message || messageOrError.name || messageOrError.code; } if (messageOrError.asset) { const fileLineCol = [messageOrError.asset.urlOrDescription]; if (messageOrError.line) { fileLineCol.push(messageOrError.line); if (messageOrError.column) { fileLineCol.push(messageOrError.col); } } message = `${fileLineCol.join(':')} - ${message}`; const incomingRelations = messageOrError.asset.incomingRelations; if (incomingRelations.length > 0) { message += `\nIncluding assets:\n ${incomingRelations .map((incomingRelation) => { return incomingRelation.from.urlOrDescription; }) .join('\n ')}\n`; } } if (messageOrError.relations) { message += `\nCyclic relations:\n ${messageOrError.relations .map((incomingRelation) => incomingRelation.location) .join('\n ')}\n`; } } else { if (typeof messageOrError === 'string') { message = messageOrError; } else if (typeof messageOrError.message === 'string') { message = messageOrError.message; } else { // Give up guessing. This is probably an error on the next lines... message = messageOrError; } } const caption = ` ${ symbolBySeverity[severity] } ${severity.toUpperCase()}: `; message = message .replace(cwdRegExp, '') .replace( assetGraphRootRelativeToCwdRegExp, chalk.gray(`${assetGraphRootRelativeToCwd}/`) ); console[severity]( chalk[colorBySeverity[severity]](caption) + indentSubsequentLines(message, caption.length) ); } let firstWarningSeenDuringTransform = null; const transformStack = [logEvents]; assetGraph .on('beforeTransform', (transform) => { firstWarningSeenDuringTransform = null; transformStack.push(transform); }) .on('afterTransform', function (transform, elapsedTime) { if (firstWarningSeenDuringTransform && stopOnWarning) { console.error( `${ chalk.red(' ✘ ERROR: ') + (transform.name ? `${transform.name}: ` : '') }A warning was encountered while stopOnWarning is on, exiting with a non-zero exit code` ); process.exit(1); } if (transform !== transformStack.pop()) { throw new Error( 'logEvents: Internal error in the transformStack housekeeping' ); } if (afterTransform !== false) { console.log( `${chalk.green(' ✔ ') + (elapsedTime / 1000).toFixed(3)} secs: ${ transform.name }` ); } if (startReplRegExp && startReplRegExp.test(transform.name)) { this.transformQueue.transforms.unshift( AssetGraph.transforms.startRepl() ); } }) .on('info', (info) => { outputMessage(info, 'info'); }) .on('warn', function (err) { outputMessage(err, 'warn'); if (startReplRegExp && startReplRegExp.test('warn')) { this.transformQueue.transforms.unshift( AssetGraph.transforms.startRepl() ); } if (transformStack.length > 0) { firstWarningSeenDuringTransform = firstWarningSeenDuringTransform || err; } else if (stopOnWarning) { console.error( `${chalk.red( ' ✘ ERROR: ' )}A warning was encountered while stopOnWarning is on, exiting with a non-zero exit code` ); process.exit(1); } }) .on('error', function (err) { outputMessage(err, 'error'); if (startReplRegExp && startReplRegExp.test('error')) { this.transformQueue.transforms.unshift( AssetGraph.transforms.startRepl() ); } else { process.exit(1); } }); }; };