From 5ea376b768a85246a09b8af0ec0ffc1f43d26252 Mon Sep 17 00:00:00 2001 From: Yuta Hiroto Date: Fri, 8 Feb 2019 20:09:29 +0900 Subject: [PATCH] feat: set `development` mode by default when unspecified (#1653) --- bin/webpack-dev-server.js | 175 +---------------- lib/utils/createConfig.js | 181 ++++++++++++++++++ test/CreateConfig.test.js | 43 +++++ test/__snapshots__/CreateConfig.test.js.snap | 75 ++++++++ test/fixtures/schema/webpack.config.simple.js | 36 ++++ 5 files changed, 340 insertions(+), 170 deletions(-) create mode 100644 lib/utils/createConfig.js create mode 100644 test/CreateConfig.test.js create mode 100644 test/__snapshots__/CreateConfig.test.js.snap create mode 100644 test/fixtures/schema/webpack.config.simple.js diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index db56eee948..7113687121 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -17,7 +17,6 @@ const debug = require('debug')('webpack-dev-server'); const fs = require('fs'); const net = require('net'); -const path = require('path'); const portfinder = require('portfinder'); const importLocal = require('import-local'); @@ -27,13 +26,14 @@ const webpack = require('webpack'); const options = require('./options'); -const { colors, status, version, bonjour, defaultTo } = require('./utils'); +const { colors, status, version, bonjour } = require('./utils'); const Server = require('../lib/Server'); const addEntries = require('../lib/utils/addEntries'); const createDomain = require('../lib/utils/createDomain'); const createLogger = require('../lib/utils/createLogger'); +const createConfig = require('../lib/utils/createConfig'); let server; @@ -88,6 +88,7 @@ const argv = yargs.argv; const config = require('webpack-cli/bin/convert-argv')(yargs, argv, { outputFilename: '/bundle.js', }); + // Taken out of yargs because we must know if // it wasn't given by the user, in which case // we should use portfinder. @@ -105,173 +106,9 @@ function processOptions(config) { return; } - const firstWpOpt = Array.isArray(config) ? config[0] : config; - - const options = config.devServer || firstWpOpt.devServer || {}; - - if (argv.bonjour) { - options.bonjour = true; - } - - if (argv.host !== 'localhost' || !options.host) { - options.host = argv.host; - } - - if (argv['allowed-hosts']) { - options.allowedHosts = argv['allowed-hosts'].split(','); - } - - if (argv.public) { - options.public = argv.public; - } - - if (argv.socket) { - options.socket = argv.socket; - } - - if (argv.progress) { - options.progress = argv.progress; - } - - if (!options.publicPath) { - // eslint-disable-next-line - options.publicPath = - (firstWpOpt.output && firstWpOpt.output.publicPath) || ''; - - if ( - !/^(https?:)?\/\//.test(options.publicPath) && - options.publicPath[0] !== '/' - ) { - options.publicPath = `/${options.publicPath}`; - } - } - - if (!options.filename) { - options.filename = firstWpOpt.output && firstWpOpt.output.filename; - } - - if (!options.watchOptions) { - options.watchOptions = firstWpOpt.watchOptions; - } - - if (argv.stdin) { - process.stdin.on('end', () => { - // eslint-disable-next-line no-process-exit - process.exit(0); - }); - - process.stdin.resume(); - } - - if (!options.hot) { - options.hot = argv.hot; - } + const options = createConfig(config, argv, { port: DEFAULT_PORT }); - if (!options.hotOnly) { - options.hotOnly = argv['hot-only']; - } - - if (!options.clientLogLevel) { - options.clientLogLevel = argv['client-log-level']; - } - - // eslint-disable-next-line - if (options.contentBase === undefined) { - if (argv['content-base']) { - options.contentBase = argv['content-base']; - - if (Array.isArray(options.contentBase)) { - options.contentBase = options.contentBase.map((p) => path.resolve(p)); - } else if (/^[0-9]$/.test(options.contentBase)) { - options.contentBase = +options.contentBase; - } else if (!/^(https?:)?\/\//.test(options.contentBase)) { - options.contentBase = path.resolve(options.contentBase); - } - // It is possible to disable the contentBase by using - // `--no-content-base`, which results in arg["content-base"] = false - } else if (argv['content-base'] === false) { - options.contentBase = false; - } - } - - if (argv['watch-content-base']) { - options.watchContentBase = true; - } - - if (!options.stats) { - options.stats = { - cached: false, - cachedAssets: false, - }; - } - - if ( - typeof options.stats === 'object' && - typeof options.stats.colors === 'undefined' - ) { - options.stats = Object.assign({}, options.stats, { colors: argv.color }); - } - - if (argv.lazy) { - options.lazy = true; - } - - if (!argv.info) { - options.noInfo = true; - } - - if (argv.quiet) { - options.quiet = true; - } - - if (argv.https) { - options.https = true; - } - - if (argv['pfx-passphrase']) { - options.pfxPassphrase = argv['pfx-passphrase']; - } - - if (argv.inline === false) { - options.inline = false; - } - - if (argv['history-api-fallback']) { - options.historyApiFallback = true; - } - - if (argv.compress) { - options.compress = true; - } - - if (argv['disable-host-check']) { - options.disableHostCheck = true; - } - - if (argv['open-page']) { - options.open = true; - options.openPage = argv['open-page']; - } - - if (typeof argv.open !== 'undefined') { - options.open = argv.open !== '' ? argv.open : true; - } - - if (options.open && !options.openPage) { - options.openPage = ''; - } - - if (argv.useLocalIp) { - options.useLocalIp = true; - } - // Kind of weird, but ensures prior behavior isn't broken in cases - // that wouldn't throw errors. E.g. both argv.port and options.port - // were specified, but since argv.port is 8080, options.port will be - // tried first instead. - options.port = - argv.port === DEFAULT_PORT - ? defaultTo(options.port, argv.port) - : defaultTo(argv.port, options.port); + portfinder.basePort = DEFAULT_PORT; if (options.port != null) { startDevServer(config, options); @@ -279,8 +116,6 @@ function processOptions(config) { return; } - portfinder.basePort = DEFAULT_PORT; - portfinder.getPort((err, port) => { if (err) { throw err; diff --git a/lib/utils/createConfig.js b/lib/utils/createConfig.js new file mode 100644 index 0000000000..a43eb84a08 --- /dev/null +++ b/lib/utils/createConfig.js @@ -0,0 +1,181 @@ +'use strict'; + +const path = require('path'); +const { defaultTo } = require('../../bin/utils'); + +function createConfig(config, argv, { port }) { + const firstWpOpt = Array.isArray(config) ? config[0] : config; + const options = firstWpOpt.devServer || {}; + + // This updates both config and firstWpOpt + firstWpOpt.mode = defaultTo(firstWpOpt.mode, 'development'); + + if (argv.bonjour) { + options.bonjour = true; + } + + if (argv.host !== 'localhost' || !options.host) { + options.host = argv.host; + } + + if (argv['allowed-hosts']) { + options.allowedHosts = argv['allowed-hosts'].split(','); + } + + if (argv.public) { + options.public = argv.public; + } + + if (argv.socket) { + options.socket = argv.socket; + } + + if (argv.progress) { + options.progress = argv.progress; + } + + if (!options.publicPath) { + // eslint-disable-next-line + options.publicPath = + (firstWpOpt.output && firstWpOpt.output.publicPath) || ''; + + if ( + !/^(https?:)?\/\//.test(options.publicPath) && + options.publicPath[0] !== '/' + ) { + options.publicPath = `/${options.publicPath}`; + } + } + + if (!options.filename) { + options.filename = firstWpOpt.output && firstWpOpt.output.filename; + } + + if (!options.watchOptions) { + options.watchOptions = firstWpOpt.watchOptions; + } + + if (argv.stdin) { + process.stdin.on('end', () => { + // eslint-disable-next-line no-process-exit + process.exit(0); + }); + + process.stdin.resume(); + } + + if (!options.hot) { + options.hot = argv.hot; + } + + if (!options.hotOnly) { + options.hotOnly = argv['hot-only']; + } + + if (!options.clientLogLevel) { + options.clientLogLevel = argv['client-log-level']; + } + + // eslint-disable-next-line + if (options.contentBase === undefined) { + if (argv['content-base']) { + options.contentBase = argv['content-base']; + + if (Array.isArray(options.contentBase)) { + options.contentBase = options.contentBase.map((p) => path.resolve(p)); + } else if (/^[0-9]$/.test(options.contentBase)) { + options.contentBase = +options.contentBase; + } else if (!/^(https?:)?\/\//.test(options.contentBase)) { + options.contentBase = path.resolve(options.contentBase); + } + // It is possible to disable the contentBase by using + // `--no-content-base`, which results in arg["content-base"] = false + } else if (argv['content-base'] === false) { + options.contentBase = false; + } + } + + if (argv['watch-content-base']) { + options.watchContentBase = true; + } + + if (!options.stats) { + options.stats = { + cached: false, + cachedAssets: false, + }; + } + + if ( + typeof options.stats === 'object' && + typeof options.stats.colors === 'undefined' + ) { + options.stats = Object.assign({}, options.stats, { colors: argv.color }); + } + + if (argv.lazy) { + options.lazy = true; + } + + if (!argv.info) { + options.noInfo = true; + } + + if (argv.quiet) { + options.quiet = true; + } + + if (argv.https) { + options.https = true; + } + + if (argv['pfx-passphrase']) { + options.pfxPassphrase = argv['pfx-passphrase']; + } + + if (argv.inline === false) { + options.inline = false; + } + + if (argv['history-api-fallback']) { + options.historyApiFallback = true; + } + + if (argv.compress) { + options.compress = true; + } + + if (argv['disable-host-check']) { + options.disableHostCheck = true; + } + + if (argv['open-page']) { + options.open = true; + options.openPage = argv['open-page']; + } + + if (typeof argv.open !== 'undefined') { + options.open = argv.open !== '' ? argv.open : true; + } + + if (options.open && !options.openPage) { + options.openPage = ''; + } + + if (argv.useLocalIp) { + options.useLocalIp = true; + } + + // Kind of weird, but ensures prior behavior isn't broken in cases + // that wouldn't throw errors. E.g. both argv.port and options.port + // were specified, but since argv.port is 8080, options.port will be + // tried first instead. + options.port = + argv.port === port + ? defaultTo(options.port, argv.port) + : defaultTo(argv.port, options.port); + + return options; +} + +module.exports = createConfig; diff --git a/test/CreateConfig.test.js b/test/CreateConfig.test.js new file mode 100644 index 0000000000..b7da21f35e --- /dev/null +++ b/test/CreateConfig.test.js @@ -0,0 +1,43 @@ +'use strict'; + +const createConfig = require('../lib/utils/createConfig'); +const webpackConfig = require('./fixtures/schema/webpack.config.simple'); + +const argv = { + host: 'foo', + public: 'public', + socket: 'socket', + progress: 'progress', + publicPath: 'publicPath', + filename: 'filename', + hot: 'hot', + hotOnly: 'hotOnly', + clientLogLevel: 'clientLogLevel', + contentBase: 'contentBase', + watchContentBase: 'watchContentBase', + stats: { + cached: 'cached', + cachedAssets: 'cachedAssets', + colors: 'colors', + }, + lazy: 'lazy', + noInfo: 'noInfo', + quiet: 'quiet', + https: 'https', + pfxPassphrase: 'pfxPassphrase', + inline: 'inline', + historyApiFallback: 'historyApiFallback', + compress: 'compress', + disableHostCheck: 'disableHostCheck', + open: 'open', + openPage: 'openPage', + useLocalIp: 'useLocalIp', + port: 'port', +}; + +describe('createConfig', () => { + it('simple', () => { + expect(createConfig(webpackConfig, argv, { port: 8080 })).toMatchSnapshot(); + expect(webpackConfig).toMatchSnapshot(); + }); +}); diff --git a/test/__snapshots__/CreateConfig.test.js.snap b/test/__snapshots__/CreateConfig.test.js.snap new file mode 100644 index 0000000000..1c86c5ed35 --- /dev/null +++ b/test/__snapshots__/CreateConfig.test.js.snap @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`createConfig simple 1`] = ` +Object { + "clientLogLevel": "_clientLogLevel", + "compress": true, + "contentBase": "_contentBase", + "disableHostCheck": "_disableHostCheck", + "filename": "_filename", + "historyApiFallback": "_historyApiFallback", + "host": "foo", + "hot": "_hot", + "hotOnly": "_hotOnly", + "https": true, + "inline": "_inline", + "lazy": true, + "noInfo": true, + "open": "open", + "openPage": "_openPage", + "pfxPassphrase": "_pfxPassphrase", + "port": "port", + "progress": "progress", + "public": "public", + "publicPath": "_publicPath", + "quiet": true, + "socket": "socket", + "stats": Object { + "cached": "_cached", + "cachedAssets": "_cachedAssets", + "colors": "_colors", + }, + "useLocalIp": true, + "watchContentBase": "_watchContentBase", + "watchOptions": undefined, +} +`; + +exports[`createConfig simple 2`] = ` +Object { + "devServer": Object { + "clientLogLevel": "_clientLogLevel", + "compress": true, + "contentBase": "_contentBase", + "disableHostCheck": "_disableHostCheck", + "filename": "_filename", + "historyApiFallback": "_historyApiFallback", + "host": "foo", + "hot": "_hot", + "hotOnly": "_hotOnly", + "https": true, + "inline": "_inline", + "lazy": true, + "noInfo": true, + "open": "open", + "openPage": "_openPage", + "pfxPassphrase": "_pfxPassphrase", + "port": "port", + "progress": "progress", + "public": "public", + "publicPath": "_publicPath", + "quiet": true, + "socket": "socket", + "stats": Object { + "cached": "_cached", + "cachedAssets": "_cachedAssets", + "colors": "_colors", + }, + "useLocalIp": true, + "watchContentBase": "_watchContentBase", + "watchOptions": undefined, + }, + "entry": "./app.js", + "mode": "development", +} +`; diff --git a/test/fixtures/schema/webpack.config.simple.js b/test/fixtures/schema/webpack.config.simple.js new file mode 100644 index 0000000000..b50102ea4c --- /dev/null +++ b/test/fixtures/schema/webpack.config.simple.js @@ -0,0 +1,36 @@ +'use strict'; + +module.exports = { + entry: './app.js', + devServer: { + host: '_foo', + public: '_public', + socket: '_socket', + progress: '_progress', + publicPath: '_publicPath', + filename: '_filename', + hot: '_hot', + hotOnly: '_hotOnly', + clientLogLevel: '_clientLogLevel', + contentBase: '_contentBase', + watchContentBase: '_watchContentBase', + stats: { + cached: '_cached', + cachedAssets: '_cachedAssets', + colors: '_colors', + }, + lazy: '_lazy', + noInfo: '_noInfo', + quiet: '_quiet', + https: '_https', + pfxPassphrase: '_pfxPassphrase', + inline: '_inline', + historyApiFallback: '_historyApiFallback', + compress: '_compress', + disableHostCheck: '_disableHostCheck', + open: '_open', + openPage: '_openPage', + useLocalIp: '_useLocalIp', + port: '_port', + }, +};