Skip to content

Commit 56274e4

Browse files
knagaitsevhiroppy
authored andcommitted
feat(server/client): made progress option available to API (#1961)
* feat(server/client): made progress option available to API * test(client): switched snapshot test to single line confirmation * refactor(server): removed this.profile * test(client): fixed progress test css path * test(client): remove jest timeout * test(e2e): change how use of progress on client checked * test(e2e): moved css unlink into afterAll * test(e2e): use port assigner * test(client): add full progress snapshot * test(client): reg exp progress test * test(client): check end of progress updates in console * test(client): more generalized test reg exp * test(client): test to isolate ci problem * test(client): made custom progress plugin to test * test(client): new progress plugin multi handler test * test(client): more testing to identify progress problem * test(client): test with 1 progress plugin * test(client): new console.log to test sending of data * feat(server): re-add two progress plugins * test(client): revert to original changes * test(progress): added progress and profile option tests * fix(test): fix profile test port map
1 parent fa78347 commit 56274e4

11 files changed

+225
-18
lines changed

bin/options.js

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ const options = {
3737
describe:
3838
'Inline mode (set to false to disable including client scripts like livereload)',
3939
},
40+
profile: {
41+
type: 'boolean',
42+
describe: 'Print compilation profile data for progress steps',
43+
},
4044
progress: {
4145
type: 'boolean',
4246
describe: 'Print compilation progress in percentage',

bin/webpack-dev-server.js

-6
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,6 @@ function startDevServer(config, options) {
9797
throw err;
9898
}
9999

100-
if (options.progress) {
101-
new webpack.ProgressPlugin({
102-
profile: argv.profile,
103-
}).apply(compiler);
104-
}
105-
106100
try {
107101
server = new Server(compiler, options, log);
108102
} catch (err) {

lib/Server.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,25 @@ class Server {
154154
}
155155

156156
setupProgressPlugin() {
157-
const progressPlugin = new webpack.ProgressPlugin(
158-
(percent, msg, addInfo) => {
159-
percent = Math.floor(percent * 100);
157+
// for CLI output
158+
new webpack.ProgressPlugin({
159+
profile: !!this.options.profile,
160+
}).apply(this.compiler);
160161

161-
if (percent === 100) {
162-
msg = 'Compilation completed';
163-
}
162+
// for browser console output
163+
new webpack.ProgressPlugin((percent, msg, addInfo) => {
164+
percent = Math.floor(percent * 100);
164165

165-
if (addInfo) {
166-
msg = `${msg} (${addInfo})`;
167-
}
166+
if (percent === 100) {
167+
msg = 'Compilation completed';
168+
}
168169

169-
this.sockWrite(this.sockets, 'progress-update', { percent, msg });
170+
if (addInfo) {
171+
msg = `${msg} (${addInfo})`;
170172
}
171-
);
172173

173-
progressPlugin.apply(this.compiler);
174+
this.sockWrite(this.sockets, 'progress-update', { percent, msg });
175+
}).apply(this.compiler);
174176
}
175177

176178
setupApp() {

lib/options.json

+4
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@
258258
}
259259
]
260260
},
261+
"profile": {
262+
"type": "boolean"
263+
},
261264
"progress": {
262265
"type": "boolean"
263266
},
@@ -426,6 +429,7 @@
426429
"pfx": "should be {String|Buffer} (https://webpack.js.org/configuration/dev-server/#devserverpfx)",
427430
"pfxPassphrase": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpfxpassphrase)",
428431
"port": "should be {Number|String|Null} (https://webpack.js.org/configuration/dev-server/#devserverport)",
432+
"profile": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprofile)",
429433
"progress": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprogress---cli-only)",
430434
"proxy": "should be {Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverproxy)",
431435
"public": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpublic)",

lib/utils/createConfig.js

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ function createConfig(config, argv, { port }) {
4747
options.liveReload = false;
4848
}
4949

50+
if (argv.profile) {
51+
options.profile = argv.profile;
52+
}
53+
5054
if (argv.progress) {
5155
options.progress = argv.progress;
5256
}

test/cli/cli.test.js

+17
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,23 @@ describe('CLI', () => {
2020
.then((output) => {
2121
expect(output.code).toEqual(0);
2222
expect(output.stderr.includes('0% compiling')).toBe(true);
23+
// should not profile
24+
expect(
25+
output.stderr.includes('ms after chunk modules optimization')
26+
).toBe(false);
27+
done();
28+
})
29+
.catch(done);
30+
});
31+
32+
it('--progress --profile', (done) => {
33+
testBin('--progress --profile')
34+
.then((output) => {
35+
expect(output.code).toEqual(0);
36+
// should profile
37+
expect(
38+
output.stderr.includes('ms after chunk modules optimization')
39+
).toBe(true);
2340
done();
2441
})
2542
.catch(done);

test/e2e/Progress.test.js

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
'use strict';
2+
3+
/* eslint-disable
4+
no-undef
5+
*/
6+
const fs = require('fs');
7+
const { resolve } = require('path');
8+
const testServer = require('../helpers/test-server');
9+
const reloadConfig = require('../fixtures/reload-config/webpack.config');
10+
const runBrowser = require('../helpers/run-browser');
11+
const port = require('../ports-map').Progress;
12+
13+
const cssFilePath = resolve(__dirname, '../fixtures/reload-config/main.css');
14+
15+
describe('client progress', () => {
16+
describe('using hot', () => {
17+
beforeAll((done) => {
18+
fs.writeFileSync(
19+
cssFilePath,
20+
'body { background-color: rgb(0, 0, 255); }'
21+
);
22+
const options = {
23+
port,
24+
host: '0.0.0.0',
25+
inline: true,
26+
hot: true,
27+
progress: true,
28+
watchOptions: {
29+
poll: 500,
30+
},
31+
};
32+
testServer.startAwaitingCompilation(reloadConfig, options, done);
33+
});
34+
35+
afterAll((done) => {
36+
fs.unlinkSync(cssFilePath);
37+
testServer.close(done);
38+
});
39+
40+
describe('on browser client', () => {
41+
it('should console.log progress', (done) => {
42+
runBrowser().then(({ page, browser }) => {
43+
const res = [];
44+
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
45+
fs.writeFileSync(
46+
cssFilePath,
47+
'body { background-color: rgb(255, 0, 0); }'
48+
);
49+
page.waitFor(10000).then(() => {
50+
browser.close().then(() => {
51+
// check that there is some percentage progress output
52+
const regExp = /^\[WDS\] [0-9]{1,3}% - /;
53+
const match = res.find((line) => {
54+
return regExp.test(line);
55+
});
56+
// eslint-disable-next-line no-undefined
57+
expect(match).not.toEqual(undefined);
58+
done();
59+
});
60+
});
61+
});
62+
63+
page.goto(`http://localhost:${port}/main`);
64+
page.on('console', (data) => {
65+
res.push(data.text());
66+
});
67+
});
68+
});
69+
});
70+
});
71+
});

test/options.test.js

+4
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@ describe('options', () => {
309309
success: ['', 0, null],
310310
failure: [false],
311311
},
312+
profile: {
313+
success: [false],
314+
failure: [''],
315+
},
312316
progress: {
313317
success: [false],
314318
failure: [''],

test/ports-map.js

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ const portsList = {
4040
WebsocketServer: 1,
4141
ClientMode: 1,
4242
'clientMode-option': 1,
43+
Progress: 1,
44+
'progress-option': 1,
45+
'profile-option': 1,
4346
};
4447

4548
let startPort = 8079;

test/server/profile-option.test.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use strict';
2+
3+
const webpack = require('webpack');
4+
const Server = require('../../lib/Server');
5+
const config = require('../fixtures/simple-config/webpack.config');
6+
const port = require('../ports-map')['profile-option'];
7+
8+
describe('profile', () => {
9+
describe('output', () => {
10+
let mockStderr;
11+
12+
beforeAll(() => {
13+
mockStderr = jest
14+
.spyOn(process.stderr, 'write')
15+
.mockImplementation(() => {});
16+
});
17+
18+
it('should show percentage progress with profile data', (done) => {
19+
const compiler = webpack(config);
20+
const server = new Server(compiler, {
21+
port,
22+
// profile will only have an effect when progress is enabled
23+
progress: true,
24+
profile: true,
25+
});
26+
27+
compiler.hooks.done.tap('webpack-dev-server', () => {
28+
const calls = mockStderr.mock.calls;
29+
mockStderr.mockRestore();
30+
let foundProgress = false;
31+
let foundProfile = false;
32+
calls.forEach((call) => {
33+
if (call[0].includes('0% compiling')) {
34+
foundProgress = true;
35+
}
36+
37+
// this is an indicator that the profile option is enabled,
38+
// so we should expect to find it in stderr since profile is enabled
39+
if (call[0].includes('ms after chunk modules optimization')) {
40+
foundProfile = true;
41+
}
42+
});
43+
expect(foundProgress).toBeTruthy();
44+
expect(foundProfile).toBeTruthy();
45+
46+
server.close(done);
47+
});
48+
49+
compiler.run(() => {});
50+
server.listen(port, 'localhost');
51+
});
52+
});
53+
});

test/server/progress-option.test.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict';
2+
3+
const webpack = require('webpack');
4+
const Server = require('../../lib/Server');
5+
const config = require('../fixtures/simple-config/webpack.config');
6+
const port = require('../ports-map')['progress-option'];
7+
8+
describe('progress', () => {
9+
describe('output', () => {
10+
let mockStderr;
11+
12+
beforeAll(() => {
13+
mockStderr = jest
14+
.spyOn(process.stderr, 'write')
15+
.mockImplementation(() => {});
16+
});
17+
18+
it('should show percentage progress without profile data', (done) => {
19+
const compiler = webpack(config);
20+
const server = new Server(compiler, {
21+
port,
22+
progress: true,
23+
});
24+
25+
compiler.hooks.done.tap('webpack-dev-server', () => {
26+
const calls = mockStderr.mock.calls;
27+
mockStderr.mockRestore();
28+
let foundProgress = false;
29+
let foundProfile = false;
30+
calls.forEach((call) => {
31+
if (call[0].includes('0% compiling')) {
32+
foundProgress = true;
33+
}
34+
35+
// this is an indicator that the profile option is enabled,
36+
// so we should expect to not find it in stderr since it is not enabled
37+
if (call[0].includes('ms after chunk modules optimization')) {
38+
foundProfile = true;
39+
}
40+
});
41+
expect(foundProgress).toBeTruthy();
42+
expect(foundProfile).toBeFalsy();
43+
44+
server.close(done);
45+
});
46+
47+
compiler.run(() => {});
48+
server.listen(port, 'localhost');
49+
});
50+
});
51+
});

0 commit comments

Comments
 (0)