diff --git a/src/Bundler.js b/src/Bundler.js index ae7dcbbdaa2..3348aff725c 100644 --- a/src/Bundler.js +++ b/src/Bundler.js @@ -9,7 +9,7 @@ const FSCache = require('./FSCache'); const HMRServer = require('./HMRServer'); const Server = require('./Server'); const {EventEmitter} = require('events'); -const Logger = require('./Logger'); +const logger = require('./Logger'); const PackagerRegistry = require('./packagers'); const localRequire = require('./utils/localRequire'); const config = require('./utils/config'); @@ -31,7 +31,6 @@ class Bundler extends EventEmitter { this.parser = new Parser(this.options); this.packagers = new PackagerRegistry(); this.cache = this.options.cache ? new FSCache(this.options) : null; - this.logger = new Logger(this.options); this.delegate = options.delegate || {}; this.bundleLoaders = {}; @@ -55,6 +54,8 @@ class Bundler extends EventEmitter { this.errored = false; this.buildQueue = new PromiseQueue(this.processAsset.bind(this)); this.rebuildTimeout = null; + + logger.setOptions(this.options); } normalizeOptions(options) { @@ -136,7 +137,7 @@ class Bundler extends EventEmitter { } } } catch (err) { - this.logger.warn(err); + logger.warn(err); } } @@ -155,8 +156,8 @@ class Bundler extends EventEmitter { this.pending = true; this.errored = false; - this.logger.clear(); - this.logger.status(emoji.progress, 'Building...'); + logger.clear(); + logger.status(emoji.progress, 'Building...'); try { // Start worker farm, watcher, etc. if needed @@ -196,13 +197,13 @@ class Bundler extends EventEmitter { buildTime < 1000 ? `${buildTime}ms` : `${(buildTime / 1000).toFixed(2)}s`; - this.logger.status(emoji.success, `Built in ${time}.`, 'green'); + logger.status(emoji.success, `Built in ${time}.`, 'green'); this.emit('bundled', bundle); return bundle; } catch (err) { this.errored = true; - this.logger.error(err); + logger.error(err); if (this.hmr) { this.hmr.emitError(err); } @@ -359,7 +360,7 @@ class Bundler extends EventEmitter { } if (!this.errored) { - this.logger.status(emoji.progress, `Building ${asset.basename}...`); + logger.status(emoji.progress, `Building ${asset.basename}...`); } // Mark the asset processed so we don't load it twice @@ -533,8 +534,8 @@ class Bundler extends EventEmitter { return; } - this.logger.clear(); - this.logger.status(emoji.progress, `Building ${Path.basename(path)}...`); + logger.clear(); + logger.status(emoji.progress, `Building ${Path.basename(path)}...`); // Add the asset to the rebuild queue, and reset the timeout. for (let asset of assets) { diff --git a/src/FSCache.js b/src/FSCache.js index e5fb89682f3..01a5821973c 100644 --- a/src/FSCache.js +++ b/src/FSCache.js @@ -3,6 +3,7 @@ const path = require('path'); const md5 = require('./utils/md5'); const objectHash = require('./utils/objectHash'); const pkg = require('../package.json'); +const logger = require('./Logger'); // These keys can affect the output, so if they differ, the cache should not match const OPTION_KEYS = ['publicURL', 'minify', 'hmr']; @@ -46,7 +47,7 @@ class FSCache { await fs.writeFile(this.getCacheFile(filename), JSON.stringify(data)); this.invalidated.delete(filename); } catch (err) { - console.error('Error writing to cache', err); + logger.error('Error writing to cache', err); } } diff --git a/src/HMRServer.js b/src/HMRServer.js index 516374c1a72..274da3eee29 100644 --- a/src/HMRServer.js +++ b/src/HMRServer.js @@ -1,5 +1,6 @@ const WebSocket = require('ws'); const prettyError = require('./utils/prettyError'); +const logger = require('./Logger'); class HMRServer { async start(port) { @@ -76,8 +77,7 @@ class HMRServer { // This gets triggered on page refresh, ignore this return; } - // TODO: Use logger to print errors - console.log(prettyError(err)); + logger.log(err); } broadcast(msg) { diff --git a/src/Logger.js b/src/Logger.js index 5c3a23dfcb2..e5d43025fb5 100644 --- a/src/Logger.js +++ b/src/Logger.js @@ -5,12 +5,19 @@ const emoji = require('./utils/emoji'); class Logger { constructor(options) { - this.logLevel = typeof options.logLevel === 'number' ? options.logLevel : 3; - this.color = - typeof options.color === 'boolean' ? options.color : chalk.supportsColor; - this.chalk = new chalk.constructor({enabled: this.color}); this.lines = 0; this.statusLine = null; + this.setOptions(options); + } + + setOptions(options) { + this.logLevel = + options && typeof options.logLevel === 'number' ? options.logLevel : 3; + this.color = + options && typeof options.color === 'boolean' + ? options.color + : chalk.supportsColor; + this.chalk = new chalk.constructor({enabled: this.color}); } write(message, persistent = false) { @@ -42,7 +49,7 @@ class Logger { return; } - this.write(this.chalk.yellow(`${emoji.warning} ${message}`)); + this.write(this.chalk.yellow(`${emoji.warning} ${message}`)); } error(err) { @@ -108,6 +115,28 @@ class Logger { this.lines++; } } + + handleMessage(options) { + this[options.method](...options.args); + } } -module.exports = Logger; +// If we are in a worker, make a proxy class which will +// send the logger calls to the main process via IPC. +// These are handled in WorkerFarm and directed to handleMessage above. +if (process.send) { + class LoggerProxy {} + for (let method of Object.getOwnPropertyNames(Logger.prototype)) { + LoggerProxy.prototype[method] = (...args) => { + process.send({ + type: 'logger', + method, + args + }); + }; + } + + module.exports = new LoggerProxy(); +} else { + module.exports = new Logger(); +} diff --git a/src/Server.js b/src/Server.js index ccf595e908b..bc3cf065e24 100644 --- a/src/Server.js +++ b/src/Server.js @@ -4,6 +4,7 @@ const serveStatic = require('serve-static'); const getPort = require('get-port'); const serverErrors = require('./utils/customErrors').serverErrors; const generateCertificate = require('./utils/generateCertificate'); +const logger = require('./Logger'); serveStatic.mime.define({ 'application/wasm': ['wasm'] @@ -71,20 +72,20 @@ async function serve(bundler, port, useHTTPS = false) { return new Promise((resolve, reject) => { server.on('error', err => { - bundler.logger.error(new Error(serverErrors(err, server.address().port))); + logger.error(new Error(serverErrors(err, server.address().port))); reject(err); }); server.once('listening', () => { let addon = server.address().port !== port - ? `- ${bundler.logger.chalk.yellow( + ? `- ${logger.chalk.yellow( `configured port ${port} could not be used.` )}` : ''; - bundler.logger.persistent( - `Server running at ${bundler.logger.chalk.cyan( + logger.persistent( + `Server running at ${logger.chalk.cyan( `${useHTTPS ? 'https' : 'http'}://localhost:${server.address().port}` )} ${addon}` ); diff --git a/src/WorkerFarm.js b/src/WorkerFarm.js index bc3e9860645..6977733c2b4 100644 --- a/src/WorkerFarm.js +++ b/src/WorkerFarm.js @@ -2,6 +2,7 @@ const {EventEmitter} = require('events'); const os = require('os'); const Farm = require('worker-farm/lib/farm'); const promisify = require('./utils/promisify'); +const logger = require('./Logger'); let shared = null; @@ -60,6 +61,8 @@ class WorkerFarm extends Farm { if (data.event) { this.emit(data.event, ...data.args); + } else if (data.type === 'logger') { + logger.handleMessage(data); } else { super.receive(data); } diff --git a/src/transforms/uglify.js b/src/transforms/uglify.js index 19de75edd75..aad885148b2 100644 --- a/src/transforms/uglify.js +++ b/src/transforms/uglify.js @@ -1,4 +1,5 @@ const {minify} = require('uglify-es'); +const logger = require('../Logger'); module.exports = async function(asset) { await asset.parseIfNeeded(); @@ -26,8 +27,7 @@ module.exports = async function(asset) { // Log all warnings if (result.warnings) { result.warnings.forEach(warning => { - // TODO: warn this using the logger - console.log(warning); + logger.warn('[uglify] ' + warning); }); } diff --git a/src/utils/generateCertificate.js b/src/utils/generateCertificate.js index 8b6565d36cd..4bf9304a3cc 100644 --- a/src/utils/generateCertificate.js +++ b/src/utils/generateCertificate.js @@ -2,6 +2,7 @@ const forge = require('node-forge'); const fs = require('fs'); const mkdirp = require('mkdirp'); const path = require('path'); +const logger = require('../Logger'); function generateCertificate(options = {}) { const privateKeyPath = path.join(options.cacheDir, 'private.pem'); @@ -19,7 +20,7 @@ function generateCertificate(options = {}) { } } - console.log('Generating SSL Certificate...'); + logger.log('Generating SSL Certificate...'); const pki = forge.pki; const keys = pki.rsa.generateKeyPair(2048);