Skip to content

Commit c9e9178

Browse files
John Richard Chipps-Hardingevilebottnawi
authored andcommitted
feat(options): add multiple openPage support (#2266)
1 parent 06e014b commit c9e9178

File tree

12 files changed

+265
-21
lines changed

12 files changed

+265
-21
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# CLI: Open Page Option (Multiple)
2+
3+
```console
4+
npm run webpack-dev-server -- --open-page example1.html,example2.html
5+
```
6+
7+
Some applications may consist of multiple pages. During development it may
8+
be useful to directly open multiple pages at the same time. The pages to open
9+
may be specified as the argument to the `open-page` option.
10+
11+
## What Should Happen
12+
13+
The script should open `http://localhost:8080/example1.html` and
14+
`http://localhost:8080/example2.html` in your default browser.
15+
You should see the text on the page itself change to read `Success!`.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
const target = document.querySelector('#target');
4+
5+
if (window.location.href.endsWith('example1.html')) {
6+
target.classList.add('pass');
7+
target.innerHTML = 'Success!';
8+
} else {
9+
target.classList.add('fail');
10+
target.innerHTML = 'Houston, we have a problem.';
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
const target = document.querySelector('#target');
4+
5+
if (window.location.href.endsWith('example2.html')) {
6+
target.classList.add('pass');
7+
target.innerHTML = 'Success!';
8+
} else {
9+
target.classList.add('fail');
10+
target.innerHTML = 'Houston, we have a problem.';
11+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const HtmlWebpackPlugin = require('html-webpack-plugin');
4+
// our setup function adds behind-the-scenes bits to the config that all of our
5+
// examples need
6+
const { setup } = require('../../util');
7+
8+
module.exports = [
9+
setup({
10+
context: __dirname,
11+
entry: './app1.js',
12+
output: {
13+
filename: 'app1.js',
14+
},
15+
plugins: [
16+
new HtmlWebpackPlugin({
17+
filename: 'example1.html',
18+
template: '../../.assets/layout.html',
19+
title: 'Open Page (Multiple) / Example / Page 1',
20+
}),
21+
],
22+
}),
23+
setup({
24+
context: __dirname,
25+
entry: './app2.js',
26+
output: {
27+
filename: 'app2.js',
28+
},
29+
plugins: [
30+
new HtmlWebpackPlugin({
31+
filename: 'example2.html',
32+
template: '../../.assets/layout.html',
33+
title: 'Open Page (Multiple) / Example / Page 2',
34+
}),
35+
],
36+
}),
37+
];

examples/cli/open-page/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ as the argument to the `open-page` option.
1010

1111
## What Should Happen
1212

13-
The script should open `http://localhost:8080/` in your default browser.
14-
You should see the text on the page itself change to read `Success!`.
13+
The script should open `http://localhost:8080/example.html#page1` in your
14+
default browser. You should see the text on the page itself change to read `Success!`.

lib/options.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,18 @@
209209
]
210210
},
211211
"openPage": {
212-
"type": "string"
212+
"anyOf": [
213+
{
214+
"type": "string"
215+
},
216+
{
217+
"type": "array",
218+
"items": {
219+
"type": "string"
220+
},
221+
"minItems": 1
222+
}
223+
]
213224
},
214225
"overlay": {
215226
"anyOf": [
@@ -436,7 +447,7 @@
436447
"noInfo": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devservernoinfo-)",
437448
"onListening": "should be {Function} (https://webpack.js.org/configuration/dev-server/#onlistening)",
438449
"open": "should be {String|Boolean} (https://webpack.js.org/configuration/dev-server/#devserveropen)",
439-
"openPage": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserveropenpage)",
450+
"openPage": "should be {String|Array} (https://webpack.js.org/configuration/dev-server/#devserveropenpage)",
440451
"overlay": "should be {Boolean|Object} (https://webpack.js.org/configuration/dev-server/#devserveroverlay)",
441452
"pfx": "should be {String|Buffer} (https://webpack.js.org/configuration/dev-server/#devserverpfx)",
442453
"pfxPassphrase": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpfxpassphrase)",

lib/utils/createConfig.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ function createConfig(config, argv, { port }) {
203203

204204
if (argv.openPage) {
205205
options.open = true;
206-
options.openPage = argv.openPage;
206+
options.openPage = argv.openPage.split(',');
207207
}
208208

209209
if (typeof argv.open !== 'undefined') {

lib/utils/runOpen.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,29 @@ const isAbsoluteUrl = require('is-absolute-url');
66
function runOpen(uri, options, log) {
77
// https://github.com/webpack/webpack-dev-server/issues/1990
88
let openOptions = { wait: false };
9-
let openMessage = 'Unable to open browser';
9+
let openOptionValue = '';
1010

1111
if (typeof options.open === 'string') {
1212
openOptions = Object.assign({}, openOptions, { app: options.open });
13-
openMessage += `: ${options.open}`;
13+
openOptionValue = `: "${options.open}"`;
1414
}
1515

16-
const pageUrl =
17-
options.openPage && isAbsoluteUrl(options.openPage)
18-
? options.openPage
19-
: `${uri}${options.openPage || ''}`;
16+
const pages =
17+
typeof options.openPage === 'string'
18+
? [options.openPage]
19+
: options.openPage || [''];
2020

21-
return open(pageUrl, openOptions).catch(() => {
22-
log.warn(
23-
`${openMessage}. If you are running in a headless environment, please do not use the --open flag`
24-
);
25-
});
21+
return Promise.all(
22+
pages.map((page) => {
23+
const pageUrl = page && isAbsoluteUrl(page) ? page : `${uri}${page}`;
24+
25+
return open(pageUrl, openOptions).catch(() => {
26+
log.warn(
27+
`Unable to open "${pageUrl}" in browser${openOptionValue}. If you are running in a headless environment, please do not use the --open flag`
28+
);
29+
});
30+
})
31+
);
2632
}
2733

2834
module.exports = runOpen;

test/server/utils/__snapshots__/createConfig.test.js.snap

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,25 @@ Object {
818818
}
819819
`;
820820

821+
exports[`createConfig openPage multiple option (in devServer config) 1`] = `
822+
Object {
823+
"hot": true,
824+
"hotOnly": false,
825+
"noInfo": true,
826+
"open": true,
827+
"openPage": Array [
828+
"/different/page",
829+
"/different/page2",
830+
],
831+
"port": 8080,
832+
"publicPath": "/",
833+
"stats": Object {
834+
"cached": false,
835+
"cachedAssets": false,
836+
},
837+
}
838+
`;
839+
821840
exports[`createConfig openPage option (in devServer config) 1`] = `
822841
Object {
823842
"hot": true,
@@ -840,7 +859,9 @@ Object {
840859
"hotOnly": false,
841860
"noInfo": true,
842861
"open": true,
843-
"openPage": "/different/page",
862+
"openPage": Array [
863+
"/different/page",
864+
],
844865
"port": 8080,
845866
"publicPath": "/",
846867
"stats": Object {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`runOpen util on specify multiple absolute https URLs with pages in Google Chrome 1`] = `
4+
Array [
5+
"https://example2.com",
6+
Object {
7+
"app": "Google Chrome",
8+
"wait": false,
9+
},
10+
]
11+
`;
12+
13+
exports[`runOpen util on specify multiple absolute https URLs with pages in Google Chrome 2`] = `
14+
Array [
15+
"https://example3.com",
16+
Object {
17+
"app": "Google Chrome",
18+
"wait": false,
19+
},
20+
]
21+
`;
22+
23+
exports[`runOpen util on specify one relative URL and one absolute URL with pages in Google Chrome 1`] = `
24+
Array [
25+
"https://example.com/index.html",
26+
Object {
27+
"app": "Google Chrome",
28+
"wait": false,
29+
},
30+
]
31+
`;
32+
33+
exports[`runOpen util on specify one relative URL and one absolute URL with pages in Google Chrome 2`] = `
34+
Array [
35+
"https://example2.com",
36+
Object {
37+
"app": "Google Chrome",
38+
"wait": false,
39+
},
40+
]
41+
`;
42+
43+
exports[`runOpen util should open browser on specify URL with multiple pages inside array 1`] = `
44+
Array [
45+
"https://example.com/index.html",
46+
Object {
47+
"wait": false,
48+
},
49+
]
50+
`;
51+
52+
exports[`runOpen util should open browser on specify URL with multiple pages inside array 2`] = `
53+
Array [
54+
"https://example.com/index2.html",
55+
Object {
56+
"wait": false,
57+
},
58+
]
59+
`;
60+
61+
exports[`runOpen util should open browser on specify URL with page inside array 1`] = `
62+
Array [
63+
"https://example.com/index.html",
64+
Object {
65+
"wait": false,
66+
},
67+
]
68+
`;

0 commit comments

Comments
 (0)