From b193af45a7f31ea2afc11ad4ce67a65df1d6960a Mon Sep 17 00:00:00 2001 From: shellscape Date: Thu, 1 Mar 2018 22:11:22 -0500 Subject: [PATCH 1/3] add process.env flag on suggestion by @Kovensky --- index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.js b/index.js index a521072..e593db0 100644 --- a/index.js +++ b/index.js @@ -13,6 +13,8 @@ const pkg = require('./package.json'); module.exports = (opts) => { updateNotifier({ pkg }).notify(); + process.env.WEBPACK_SERVE = true; + return getOptions(opts) .then((results) => { const { options, configs } = results; From d0ee967ff07bf8f0d1752fd51cb3428deda5f947 Mon Sep 17 00:00:00 2001 From: shellscape Date: Fri, 2 Mar 2018 11:05:22 -0500 Subject: [PATCH 2/3] use cosmiconfig --- cli.js | 43 +++++++++++++++++++------------------------ lib/options.js | 2 +- package-lock.json | 39 +++++++++++++++++++++++---------------- package.json | 1 + test/tests/cli.js | 23 +++++++++++------------ 5 files changed, 55 insertions(+), 53 deletions(-) diff --git a/cli.js b/cli.js index bc94306..8f35649 100755 --- a/cli.js +++ b/cli.js @@ -10,22 +10,11 @@ if (!module.parent) { } const chalk = require('chalk'); +const cosmiconfig = require('cosmiconfig'); const debug = require('debug')('webpack-serve'); -const findUp = require('find-up'); const meow = require('meow'); +const merge = require('lodash/merge'); const importLocal = require('import-local'); // eslint-disable-line import/order -const WebpackServeError = require('./lib/WebpackServeError'); // eslint-disable-line import/order - -let webpackPackage; -let webpackVersion; - -try { - webpackPackage = require('webpack/package.json'); // eslint-disable-line global-require - webpackVersion = parseInt(webpackPackage.version, 10); -} catch (e) { - throw new WebpackServeError('webpack must be installed for webpack-serve to function.\n See: webpack-serve/package.json/peerDependencies'); -} - // Prefer the local installation of webpack-serve /* istanbul ignore if */ @@ -68,28 +57,34 @@ const cli = meow(chalk` `); const flags = Object.assign({}, cli.flags); +const cosmicOptions = { + rcExtensions: true, + sync: true +}; +const explorer = cosmiconfig('serve', cosmicOptions); +const { config } = explorer.load() || {}; +const options = merge({ flags }, config); if (cli.input.length) { [flags.config] = cli.input; } else if (!flags.config) { - const filePath = findUp.sync('webpack.config.js'); - flags.config = filePath; + const webpackExplorer = cosmiconfig('webpack', cosmicOptions); + const webpackConfig = webpackExplorer.load(); + + if (webpackConfig) { + options.config = webpackConfig.config; + flags.config = webpackConfig.filepath; + } } if (flags.help) { cli.showHelp(0); } -const options = { flags }; - if (!flags.config) { - if (webpackVersion < 4) { - cli.showHelp(0); - } else { - // webpack v4 defaults an empty config to { entry: './src' }. but since we - // need an array, we'll mimic that default config. - options.config = { entry: ['./src'] }; - } + // webpack v4 defaults an empty config to { entry: './src' }. but since we + // need an array, we'll mimic that default config. + options.config = { entry: ['./src'] }; } serve(options) diff --git a/lib/options.js b/lib/options.js index 1dfe148..a549ce1 100644 --- a/lib/options.js +++ b/lib/options.js @@ -64,7 +64,7 @@ function resolve(options) { return Promise.resolve([].concat(options.config)); } - const configPath = path.resolve(options.flags.config || options.config); + const configPath = path.resolve(options.flags.config); // eslint-disable-next-line global-require, import/no-dynamic-require let config = require(configPath); diff --git a/package-lock.json b/package-lock.json index c595579..5ba36c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -283,7 +283,6 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, "requires": { "sprintf-js": "1.0.3" } @@ -2353,6 +2352,17 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.10.0", + "parse-json": "4.0.0", + "require-from-string": "2.0.1" + } + }, "create-ecdh": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", @@ -3366,8 +3376,7 @@ "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", - "dev": true + "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=" }, "espurify": { "version": "1.7.0", @@ -5644,6 +5653,11 @@ } } }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -5981,7 +5995,6 @@ "version": "3.10.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", "integrity": "sha1-LnhEFka9RoLpY/IrbpKCPDCcYtw=", - "dev": true, "requires": { "argparse": "1.0.9", "esprima": "4.0.0" @@ -6661,16 +6674,6 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "lodash.merge": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" - }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -10588,6 +10591,11 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.1.tgz", + "integrity": "sha1-xUUjPp19pmFunVmt+zn8n1iGdv8=" + }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", @@ -11200,8 +11208,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.13.1", diff --git a/package.json b/package.json index c70240a..abae0de 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@shellscape/koa-static": "^4.0.2", "chalk": "^2.3.0", "clipboardy": "^1.2.2", + "cosmiconfig": "^4.0.0", "debug": "^3.1.0", "find-up": "^2.1.0", "get-port": "^3.2.0", diff --git a/test/tests/cli.js b/test/tests/cli.js index 8a81aad..14f8f45 100644 --- a/test/tests/cli.js +++ b/test/tests/cli.js @@ -21,6 +21,7 @@ function x(fn, ...args) { const proc = execa(...args); // webpack@4 has a lot more warnings const ready = new RegExp('(Compiled successfully)|(Compiled with warnings)'); + proc.stdout.on('data', (data) => { if (ready.test(data.toString())) { fn(proc); @@ -87,18 +88,16 @@ describe('webpack-serve CLI', () => { }, cliPath, { cwd: path.resolve(__dirname, '../fixtures/basic') }); }); - if (webpackVersion > 3) { - t('should run webpack-serve with webpack v4 defaults', (done) => { - x((proc) => { - fetch('http://localhost:8080') - .then((res) => { - assert(res.ok); - proc.kill('SIGINT'); - done(); - }); - }, cliPath, { cwd: path.resolve(__dirname, '../fixtures/webpack-4-defaults') }); - }); - } + t('should run webpack-serve with webpack v4 defaults', (done) => { + x((proc) => { + fetch('http://localhost:8080') + .then((res) => { + assert(res.ok); + proc.kill('SIGINT'); + done(); + }); + }, cliPath, { cwd: path.resolve(__dirname, '../fixtures/webpack-4-defaults') }); + }); t('should use the --content flag', (done) => { const confPath = path.resolve(__dirname, '../fixtures/content/webpack.config.js'); From 71cf270ad05bfbbc412504ad1eb9b05c1d16df80 Mon Sep 17 00:00:00 2001 From: shellscape Date: Fri, 2 Mar 2018 16:49:10 -0500 Subject: [PATCH 3/3] update readme with config info --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d7df03..6450d7d 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,23 @@ will display help and usage information. In order to accommodate the zero-config changes in webpack v4, users of webpack v4 will need to use the `--help` flag to display the same information. -## Webpack Config `serve` Property +## `webpack-serve` Config + +You can store and define configuration / options for `webpack-serve` in a number +of different ways. This module leverages [cosmiconfig](https://github.com/davidtheclark/cosmiconfig), +which allows you to define `webpack-serve` options in the following ways: + +- in your package.json file in a `serve` property +- in a `.serverc` or `.serverc.json` file, in either JSON or YML. +- in a `serve.config.js` file which exports a CommonJS module (just like webpack). + +It's most common to keep `serve` options in your `webpack.config.js` (see below), +however, you can utilize any of the options above _in tandem_ with +`webpack.config.js`, and the options from the two sources will be merged. This +can be useful for setups with multiple configs that share common options for +`webpack-serve`, but require subtle differences. + +### Webpack Config `serve` Property `webpack-serve` supports the `serve` property in your webpack config file, which may contain any of the supported [options](#Options).