From f0534fc3b900735a6474207365209406cda574ad Mon Sep 17 00:00:00 2001 From: Kees Kluskens Date: Tue, 27 Feb 2018 21:24:45 +0100 Subject: [PATCH] Use webpack-log for logging webpack-dev-middleware already uses this, should not be breaking unless you rely on WDS's exact output format. --- bin/webpack-dev-server.js | 37 ++++++++++++++++++------------------- lib/Server.js | 37 ++++++++++++++++--------------------- lib/createLog.js | 19 +++++++++++++++++++ lib/optionsSchema.json | 11 +++++++++++ package.json | 1 + test/Validation.test.js | 2 +- 6 files changed, 66 insertions(+), 41 deletions(-) create mode 100644 lib/createLog.js diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index 4ef6a36167..08f473891c 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -14,6 +14,7 @@ const open = require('opn'); const portfinder = require('portfinder'); const addDevServerEntrypoints = require('../lib/util/addDevServerEntrypoints'); const createDomain = require('../lib/util/createDomain'); // eslint-disable-line +const createLog = require('../lib/createLog'); // Prefer the local installation of webpack-dev-server if (importLocal(__filename)) { @@ -370,6 +371,7 @@ function processOptions(webpackOptions) { } function startDevServer(webpackOptions, options) { + const log = createLog(options); addDevServerEntrypoints(webpackOptions, options); let compiler; @@ -377,7 +379,7 @@ function startDevServer(webpackOptions, options) { compiler = webpack(webpackOptions); } catch (e) { if (e instanceof webpack.WebpackOptionsValidationError) { - console.error(colorError(options.stats.colors, e.message)); + log.error(colorError(options.stats.colors, e.message)); process.exit(1); // eslint-disable-line } throw e; @@ -393,11 +395,11 @@ function startDevServer(webpackOptions, options) { let server; try { - server = new Server(compiler, options); + server = new Server(compiler, options, log); } catch (e) { const OptionsValidationError = require('../lib/OptionsValidationError'); if (e instanceof OptionsValidationError) { - console.error(colorError(options.stats.colors, e.message)); + log.error(colorError(options.stats.colors, e.message)); process.exit(1); // eslint-disable-line } throw e; @@ -437,7 +439,7 @@ function startDevServer(webpackOptions, options) { if (fsError) throw fsError; const uri = createDomain(options, server.listeningApp) + suffix; - reportReadiness(uri, options); + reportReadiness(uri, options, log); }); }); } else { @@ -446,31 +448,28 @@ function startDevServer(webpackOptions, options) { if (options.bonjour) broadcastZeroconf(options); const uri = createDomain(options, server.listeningApp) + suffix; - reportReadiness(uri, options); + reportReadiness(uri, options, log); }); } } -function reportReadiness(uri, options) { +function reportReadiness(uri, options, log) { const useColor = argv.color; const contentBase = Array.isArray(options.contentBase) ? options.contentBase.join(', ') : options.contentBase; - if (!options.quiet) { - let startSentence = `Project is running at ${colorInfo(useColor, uri)}`; - if (options.socket) { - startSentence = `Listening to socket at ${colorInfo(useColor, options.socket)}`; - } - - console.log((options.progress ? '\n' : '') + startSentence); + if (options.socket) { + log.info(`Listening to socket at ${colorInfo(useColor, options.socket)}`); + } else { + log.info(`Project is running at ${colorInfo(useColor, uri)}`); + } - console.log(`webpack output is served from ${colorInfo(useColor, options.publicPath)}`); + log.info(`webpack output is served from ${colorInfo(useColor, options.publicPath)}`); - if (contentBase) { console.log(`Content not from webpack is served from ${colorInfo(useColor, contentBase)}`); } + if (contentBase) { log.info(`Content not from webpack is served from ${colorInfo(useColor, contentBase)}`); } - if (options.historyApiFallback) { console.log(`404s will fallback to ${colorInfo(useColor, options.historyApiFallback.index || '/index.html')}`); } + if (options.historyApiFallback) { log.info(`404s will fallback to ${colorInfo(useColor, options.historyApiFallback.index || '/index.html')}`); } - if (options.bonjour) { console.log('Broadcasting "http" with subtype of "webpack" via ZeroConf DNS (Bonjour)'); } - } + if (options.bonjour) { log.info('Broadcasting "http" with subtype of "webpack" via ZeroConf DNS (Bonjour)'); } if (options.open) { let openOptions = {}; @@ -482,7 +481,7 @@ function reportReadiness(uri, options) { } open(uri + (options.openPage || ''), openOptions).catch(() => { - console.log(`${openMessage}. If you are running in a headless environment, please do not use the open flag.`); + log.warn(`${openMessage}. If you are running in a headless environment, please do not use the open flag.`); }); } } diff --git a/lib/Server.js b/lib/Server.js index 410be4bac6..4f42d44d9d 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -21,15 +21,16 @@ const sockjs = require('sockjs'); const spdy = require('spdy'); const webpack = require('webpack'); const webpackDevMiddleware = require('webpack-dev-middleware'); +const createLog = require('./createLog'); const OptionsValidationError = require('./OptionsValidationError'); const optionsSchema = require('./optionsSchema.json'); const clientStats = { errorDetails: false }; -const log = console.log; // eslint-disable-line no-console -function Server(compiler, options) { +function Server(compiler, options, _log) { // Default options if (!options) options = {}; + this.log = _log || createLog(options); const validationErrors = webpack.validateSchema(optionsSchema, options); if (validationErrors.length) { @@ -88,14 +89,8 @@ function Server(compiler, options) { res.send('Invalid Host header'); }); - const wdmOptions = {}; + const wdmOptions = { logLevel: this.log.options.level }; - if (options.quiet === true) { - wdmOptions.logLevel = 'silent'; - } - if (options.noInfo === true) { - wdmOptions.logLevel = 'warn'; - } // middleware for serving webpack bundle this.middleware = webpackDevMiddleware(compiler, Object.assign({}, options, wdmOptions)); @@ -286,14 +281,14 @@ function Server(compiler, options) { } }, - contentBaseFiles() { + contentBaseFiles: () => { if (Array.isArray(contentBase)) { contentBase.forEach((item) => { app.get('*', express.static(item)); }); } else if (/^(https?:)?\/\//.test(contentBase)) { - log('Using a URL as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'); - log('proxy: {\n\t"*": ""\n}'); // eslint-disable-line quotes + this.log.warn('Using a URL as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'); + this.log.warn('proxy: {\n\t"*": ""\n}'); // eslint-disable-line quotes // Redirect every request to contentBase app.get('*', (req, res) => { res.writeHead(302, { @@ -302,8 +297,8 @@ function Server(compiler, options) { res.end(); }); } else if (typeof contentBase === 'number') { - log('Using a number as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'); - log('proxy: {\n\t"*": "//localhost:"\n}'); // eslint-disable-line quotes + this.log.warn('Using a number as contentBase is deprecated and will be removed in the next major version. Please use the proxy option instead.'); + this.log.warn('proxy: {\n\t"*": "//localhost:"\n}'); // eslint-disable-line quotes // Redirect every request to the port contentBase app.get('*', (req, res) => { res.writeHead(302, { @@ -364,7 +359,7 @@ function Server(compiler, options) { setup: () => { if (typeof options.setup === 'function') { - log('The `setup` option is deprecated and will be removed in v3. Please update your config to use `before`'); + this.log.warn('The `setup` option is deprecated and will be removed in v3. Please update your config to use `before`'); options.setup(app, this); } } @@ -415,14 +410,14 @@ function Server(compiler, options) { // cert is more than 30 days old, kill it with fire if ((now - certStat.ctime) / certTtl > 30) { - log('SSL Certificate is more than 30 days old. Removing.'); + this.log.info('SSL Certificate is more than 30 days old. Removing.'); del.sync([certPath], { force: true }); certExists = false; } } if (!certExists) { - log('Generating SSL Certificate'); + this.log.info('Generating SSL Certificate'); const attrs = [{ name: 'commonName', value: 'localhost' }]; const pems = selfsigned.generate(attrs, { algorithm: 'sha256', @@ -573,16 +568,16 @@ Server.prototype.checkHost = function (headers) { // delegate listen call and init sockjs Server.prototype.listen = function (port, hostname, fn) { this.listenHostname = hostname; - // eslint-disable-next-line - const returnValue = this.listeningApp.listen(port, hostname, (err) => { const sockServer = sockjs.createServer({ // Use provided up-to-date sockjs-client sockjs_url: '/__webpack_dev_server__/sockjs.bundle.js', // Limit useless logs - log(severity, line) { + log: (severity, line) => { if (severity === 'error') { - log(line); + this.log.error(line); + } else { + this.log.debug(line); } } }); diff --git a/lib/createLog.js b/lib/createLog.js new file mode 100644 index 0000000000..2de7662e52 --- /dev/null +++ b/lib/createLog.js @@ -0,0 +1,19 @@ +'use strict'; + +const weblog = require('webpack-log'); + +module.exports = function createLog(options) { + let logLevel = options.logLevel || 'info'; + if (options.quiet === true) { + logLevel = 'silent'; + } + if (options.noInfo === true) { + logLevel = 'warn'; + } + + return weblog({ + level: logLevel, + name: 'wds', + timestamp: options.logTime + }); +}; diff --git a/lib/optionsSchema.json b/lib/optionsSchema.json index 73cebe96d3..572a7955a8 100644 --- a/lib/optionsSchema.json +++ b/lib/optionsSchema.json @@ -66,6 +66,17 @@ "description": "Response headers that are added to each response.", "type": "object" }, + "logLevel": { + "description": "Log level in the terminal/console (trace, debug, info, warn, error or none)", + "enum": [ + "trace", + "debug", + "info", + "warn", + "error", + "none" + ] + }, "clientLogLevel": { "description": "Controls the log messages shown in the browser.", "enum": [ diff --git a/package.json b/package.json index 34fc5229cd..98b5a4d430 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "strip-ansi": "^3.0.0", "supports-color": "^5.1.0", "webpack-dev-middleware": "2.0.6", + "webpack-log": "^1.1.2", "yargs": "9.0.1" }, "devDependencies": { diff --git a/test/Validation.test.js b/test/Validation.test.js index 0d3d93fba4..86e7278f5e 100644 --- a/test/Validation.test.js +++ b/test/Validation.test.js @@ -49,7 +49,7 @@ describe('Validation', () => { message: [ " - configuration has an unknown property 'asdf'. These properties are valid:", ' object { hot?, hotOnly?, lazy?, bonjour?, host?, allowedHosts?, filename?, publicPath?, port?, socket?, ' + - 'watchOptions?, headers?, clientLogLevel?, overlay?, progress?, key?, cert?, ca?, pfx?, pfxPassphrase?, requestCert?, ' + + 'watchOptions?, headers?, logLevel?, clientLogLevel?, overlay?, progress?, key?, cert?, ca?, pfx?, pfxPassphrase?, requestCert?, ' + 'inline?, disableHostCheck?, public?, https?, contentBase?, watchContentBase?, open?, useLocalIp?, openPage?, features?, ' + 'compress?, proxy?, historyApiFallback?, staticOptions?, setup?, before?, after?, stats?, reporter?, logTime?, ' + 'noInfo?, quiet?, serverSideRender?, index?, log?, warn? }'