Skip to content

fix: imporove processing of CLI flags #3313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,12 @@ Options:
--no-client-progress Do not print compilation progress in percentage in the browser.
--client-overlay Show a full-screen overlay in the browser when there are compiler errors or warnings.
--no-client-overlay Do not show a full-screen overlay in the browser when there are compiler errors or warnings.
--client-logging <value> Log level in the browser (none, error, warn, info, log, verbose).
--open [value...] Open the default browser.
--no-open Do not open the default browser.
--open-app <value> Open specified browser.
--open-target [value...] Open specified route in browser.
--no-open-target Do not open specified route in browser.
--client-logging <value> Log level in the browser (none, error, warn, info, log, verbose).
--history-api-fallback Fallback to /index.html for Single Page Applications.
--no-history-api-fallback Do not fallback to /index.html for Single Page Applications.
--compress Enable gzip compression.
Expand Down
64 changes: 33 additions & 31 deletions bin/cli-flags.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const normalizeOption = (option) => (typeof option === 'object' ? option : {});

module.exports = {
devServer: [
{
Expand Down Expand Up @@ -47,7 +49,7 @@ module.exports = {
],
description: 'Directory for static contents.',
processor(opts) {
opts.static = opts.static || {};
opts.static = normalizeOption(opts.static);
opts.static.directory = opts.staticDirectory;
delete opts.staticDirectory;
},
Expand All @@ -64,7 +66,7 @@ module.exports = {
'The bundled files will be available in the browser under this path.',
multiple: true,
processor(opts) {
opts.static = opts.static || {};
opts.static = normalizeOption(opts.static);
opts.static.publicPath = opts.staticPublicPath;
delete opts.staticPublicPath;
},
Expand All @@ -82,7 +84,7 @@ module.exports = {
'Do not tell dev-server to use serveIndex middleware.',
negative: true,
processor(opts) {
opts.static = opts.static || {};
opts.static = normalizeOption(opts.static);
opts.static.serveIndex = opts.staticServeIndex;
delete opts.staticServeIndex;
},
Expand All @@ -99,7 +101,7 @@ module.exports = {
negatedDescription: 'Do not watch for files in static content directory.',
negative: true,
processor(opts) {
opts.static = opts.static || {};
opts.static = normalizeOption(opts.static);
opts.static.watch = opts.staticWatch;
delete opts.staticWatch;
},
Expand Down Expand Up @@ -138,7 +140,7 @@ module.exports = {
],
description: 'Passphrase for a pfx file.',
processor(opts) {
opts.https = opts.https || {};
opts.https = normalizeOption(opts.https);
opts.https.passphrase = opts.httpsPassphrase;
delete opts.httpsPassphrase;
},
Expand All @@ -153,7 +155,7 @@ module.exports = {
],
description: 'Path to an SSL key.',
processor(opts) {
opts.https = opts.https || {};
opts.https = normalizeOption(opts.https);
opts.https.key = opts.httpsKey;
delete opts.httpsKey;
},
Expand All @@ -168,7 +170,7 @@ module.exports = {
],
description: 'Path to an SSL pfx file.',
processor(opts) {
opts.https = opts.https || {};
opts.https = normalizeOption(opts.https);
opts.https.pfx = opts.httpsPfx;
delete opts.httpsPfx;
},
Expand All @@ -183,7 +185,7 @@ module.exports = {
],
description: 'Path to an SSL certificate.',
processor(opts) {
opts.https = opts.https || {};
opts.https = normalizeOption(opts.https);
opts.https.cert = opts.httpsCert;
delete opts.httpsCert;
},
Expand All @@ -198,7 +200,7 @@ module.exports = {
],
description: 'Path to an SSL CA certificate.',
processor(opts) {
opts.https = opts.https || {};
opts.https = normalizeOption(opts.https);
opts.https.cacert = opts.httpsCacert;
delete opts.httpsCacert;
},
Expand All @@ -214,7 +216,7 @@ module.exports = {
description: 'Request for an SSL certificate.',
negatedDescription: 'Do not request for an SSL certificate.',
processor(opts) {
opts.https = opts.https || {};
opts.https = normalizeOption(opts.https);
opts.https.requestCert = opts.httpsRequestCert;
delete opts.httpsRequestCert;
},
Expand Down Expand Up @@ -257,7 +259,7 @@ module.exports = {
'Do not tell devServer to inject a Hot Module Replacement entry.',
negative: true,
processor(opts) {
opts.client = opts.client || {};
opts.client = normalizeOption(opts.client);
opts.client.hotEntry = opts.clientHotEntry;
delete opts.clientHotEntry;
},
Expand All @@ -275,7 +277,7 @@ module.exports = {
'Do not print compilation progress in percentage in the browser.',
negative: true,
processor(opts) {
opts.client = opts.client || {};
opts.client = normalizeOption(opts.client);
opts.client.progress = opts.clientProgress;
delete opts.clientProgress;
},
Expand All @@ -294,11 +296,27 @@ module.exports = {
'Do not show a full-screen overlay in the browser when there are compiler errors or warnings.',
negative: true,
processor(opts) {
opts.client = opts.client || {};
opts.client = normalizeOption(opts.client);
opts.client.overlay = opts.clientOverlay;
delete opts.clientOverlay;
},
},
{
name: 'client-logging',
type: String,
configs: [
{
type: 'string',
},
],
description:
'Log level in the browser (none, error, warn, info, log, verbose).',
processor(opts) {
opts.client = normalizeOption(opts.client);
opts.client.logging = opts.clientLogging;
delete opts.clientLogging;
},
},
{
name: 'open',
type: [Boolean, String],
Expand All @@ -325,7 +343,7 @@ module.exports = {
],
description: 'Open specified browser.',
processor(opts) {
opts.open = opts.open || {};
opts.open = normalizeOption(opts.open);
opts.open.app = opts.openApp;
delete opts.openApp;
},
Expand All @@ -343,30 +361,14 @@ module.exports = {
],
description: 'Open specified route in browser.',
processor(opts) {
opts.open = opts.open || {};
opts.open = normalizeOption(opts.open);
opts.open.target = opts.openTarget;
delete opts.openTarget;
},
negatedDescription: 'Do not open specified route in browser.',
multiple: true,
negative: true,
},
{
name: 'client-logging',
type: String,
configs: [
{
type: 'string',
},
],
description:
'Log level in the browser (none, error, warn, info, log, verbose).',
processor(opts) {
opts.client = opts.client || {};
opts.client.logging = opts.clientLogging;
delete opts.clientLogging;
},
},
{
name: 'history-api-fallback',
type: Boolean,
Expand Down
12 changes: 10 additions & 2 deletions test/cli/__snapshots__/cli.test.js.snap.webpack4
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ exports[`CLI --no-https-request-cert 1`] = `
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
`;

exports[`CLI https and other related options 1`] = `
"<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: https://localhost:<port>/
<i> [webpack-dev-server] On Your Network (IPv4): https://<network-ip-v4>:<port>/
<i> [webpack-dev-server] On Your Network (IPv6): https://[<network-ip-v6>]:<port>/
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
`;

exports[`CLI https options 1`] = `
"<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: https://localhost:<port>/
Expand Down Expand Up @@ -250,13 +258,13 @@ Options:
--no-client-overlay Do not show a full-screen overlay in the
browser when there are compiler errors or
warnings.
--client-logging <value> Log level in the browser (none, error, warn,
info, log, verbose).
--open [value...] Open the default browser.
--no-open Do not open the default browser.
--open-app <value> Open specified browser.
--open-target [value...] Open specified route in browser.
--no-open-target Do not open specified route in browser.
--client-logging <value> Log level in the browser (none, error, warn,
info, log, verbose).
--history-api-fallback Fallback to /index.html for Single Page
Applications.
--no-history-api-fallback Do not fallback to /index.html for Single
Expand Down
12 changes: 10 additions & 2 deletions test/cli/__snapshots__/cli.test.js.snap.webpack5
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ exports[`CLI --no-https-request-cert 1`] = `
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
`;

exports[`CLI https and other related options 1`] = `
"<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: https://localhost:<port>/
<i> [webpack-dev-server] On Your Network (IPv4): https://<network-ip-v4>:<port>/
<i> [webpack-dev-server] On Your Network (IPv6): https://[<network-ip-v6>]:<port>/
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
`;

exports[`CLI https options 1`] = `
"<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: https://localhost:<port>/
Expand Down Expand Up @@ -251,13 +259,13 @@ Options:
--no-client-overlay Do not show a full-screen overlay in the
browser when there are compiler errors or
warnings.
--client-logging <value> Log level in the browser (none, error, warn,
info, log, verbose).
--open [value...] Open the default browser.
--no-open Do not open the default browser.
--open-app <value> Open specified browser.
--open-target [value...] Open specified route in browser.
--no-open-target Do not open specified route in browser.
--client-logging <value> Log level in the browser (none, error, warn,
info, log, verbose).
--history-api-fallback Fallback to /index.html for Single Page
Applications.
--no-history-api-fallback Do not fallback to /index.html for Single
Expand Down
52 changes: 52 additions & 0 deletions test/cli/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,26 @@ describe('CLI', () => {
.catch(done);
});

// For https://github.com/webpack/webpack-dev-server/issues/3306
it('https and other related options', (done) => {
const pfxFile = path.join(httpsCertificateDirectory, 'server.pfx');
const key = path.join(httpsCertificateDirectory, 'server.key');
const cert = path.join(httpsCertificateDirectory, 'server.crt');
const passphrase = 'webpack-dev-server';

testBin(
`--https --https-key ${key} --https-pfx ${pfxFile} --https-passphrase ${passphrase} --https-cert ${cert}`
)
.then((output) => {
expect(output.exitCode).toEqual(0);
expect(
normalizeStderr(output.stderr, { ipv6: true, https: true })
).toMatchSnapshot();
done();
})
.catch(done);
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add --open --open-target test here too?

it('--https-request-cert', (done) => {
testBin('--https-request-cert')
.then((output) => {
Expand Down Expand Up @@ -484,6 +504,15 @@ describe('CLI', () => {
.catch(done);
});

it(' --open --open-target index.html', (done) => {
testBin('--open --open-target index.html')
.then((output) => {
expect(output.exitCode).toEqual(0);
done();
})
.catch(done);
});

it('--open-target /first.html second.html', (done) => {
testBin('--open-target /first.html second.html')
.then((output) => {
Expand All @@ -502,6 +531,15 @@ describe('CLI', () => {
.catch(done);
});

it('--open --open-target /index.html --open-app google-chrome', (done) => {
testBin('--open --open-target /index.html --open-app google-chrome')
.then((output) => {
expect(output.exitCode).toEqual(0);
done();
})
.catch(done);
});

it('--client-overlay', (done) => {
testBin('--client-overlay')
.then((output) => {
Expand Down Expand Up @@ -593,6 +631,20 @@ describe('CLI', () => {
.catch(done);
});

it('--static --static-directory', (done) => {
testBin(
`--static --static-directory ${path.resolve(
__dirname,
'../fixtures/static/webpack.config.js'
)}`
)
.then((output) => {
expect(output.exitCode).toEqual(0);
done();
})
.catch(done);
});

it('--static-serve-index', (done) => {
testBin('--static-serve-index')
.then((output) => {
Expand Down