Skip to content

Commit

Permalink
feat(server/client): made progress option available to API (webpack#1961
Browse files Browse the repository at this point in the history
)

* 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
  • Loading branch information
knagaitsev committed Jul 31, 2019
1 parent 90c17ff commit 82de98f
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 22 deletions.
4 changes: 4 additions & 0 deletions bin/options.js
Expand Up @@ -37,6 +37,10 @@ const options = {
describe:
'Inline mode (set to false to disable including client scripts like livereload)',
},
profile: {
type: 'boolean',
describe: 'Print compilation profile data for progress steps',
},
progress: {
type: 'boolean',
describe: 'Print compilation progress in percentage',
Expand Down
6 changes: 0 additions & 6 deletions bin/webpack-dev-server.js
Expand Up @@ -97,12 +97,6 @@ function startDevServer(config, options) {
throw err;
}

if (options.progress) {
new webpack.ProgressPlugin({
profile: argv.profile,
}).apply(compiler);
}

try {
server = new Server(compiler, options, log);
} catch (err) {
Expand Down
26 changes: 14 additions & 12 deletions lib/Server.js
Expand Up @@ -154,23 +154,25 @@ class Server {
}

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

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

if (addInfo) {
msg = `${msg} (${addInfo})`;
}
if (percent === 100) {
msg = 'Compilation completed';
}

this.sockWrite(this.sockets, 'progress-update', { percent, msg });
if (addInfo) {
msg = `${msg} (${addInfo})`;
}
);

progressPlugin.apply(this.compiler);
this.sockWrite(this.sockets, 'progress-update', { percent, msg });
}).apply(this.compiler);
}

setupApp() {
Expand Down
4 changes: 4 additions & 0 deletions lib/options.json
Expand Up @@ -249,6 +249,9 @@
}
]
},
"profile": {
"type": "boolean"
},
"progress": {
"type": "boolean"
},
Expand Down Expand Up @@ -417,6 +420,7 @@
"pfx": "should be {String|Buffer} (https://webpack.js.org/configuration/dev-server/#devserverpfx)",
"pfxPassphrase": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpfxpassphrase)",
"port": "should be {Number|String|Null} (https://webpack.js.org/configuration/dev-server/#devserverport)",
"profile": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprofile)",
"progress": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprogress---cli-only)",
"proxy": "should be {Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverproxy)",
"public": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpublic)",
Expand Down
4 changes: 4 additions & 0 deletions lib/utils/createConfig.js
Expand Up @@ -47,6 +47,10 @@ function createConfig(config, argv, { port }) {
options.liveReload = false;
}

if (argv.profile) {
options.profile = argv.profile;
}

if (argv.progress) {
options.progress = argv.progress;
}
Expand Down
29 changes: 25 additions & 4 deletions test/cli/cli.test.js
Expand Up @@ -15,10 +15,31 @@ const keyPath = resolve(httpsCertificateDirectory, 'server.key');
const certPath = resolve(httpsCertificateDirectory, 'server.crt');

describe('CLI', () => {
it('--progress', async () => {
const { code, stderr } = await testBin('--progress');
expect(code).toEqual(0);
expect(stderr.includes('0% compiling')).toBe(true);
it('--progress', (done) => {
testBin('--progress')
.then((output) => {
expect(output.code).toEqual(0);
expect(output.stderr.includes('0% compiling')).toBe(true);
// should not profile
expect(
output.stderr.includes('ms after chunk modules optimization')
).toBe(false);
done();
})
.catch(done);
});

it('--progress --profile', (done) => {
testBin('--progress --profile')
.then((output) => {
expect(output.code).toEqual(0);
// should profile
expect(
output.stderr.includes('ms after chunk modules optimization')
).toBe(true);
done();
})
.catch(done);
});

it('--bonjour', async () => {
Expand Down
71 changes: 71 additions & 0 deletions test/e2e/Progress.test.js
@@ -0,0 +1,71 @@
'use strict';

/* eslint-disable
no-undef
*/
const fs = require('fs');
const { resolve } = require('path');
const testServer = require('../helpers/test-server');
const reloadConfig = require('../fixtures/reload-config/webpack.config');
const runBrowser = require('../helpers/run-browser');
const port = require('../ports-map').Progress;

const cssFilePath = resolve(__dirname, '../fixtures/reload-config/main.css');

describe('client progress', () => {
describe('using hot', () => {
beforeAll((done) => {
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(0, 0, 255); }'
);
const options = {
port,
host: '0.0.0.0',
inline: true,
hot: true,
progress: true,
watchOptions: {
poll: 500,
},
};
testServer.startAwaitingCompilation(reloadConfig, options, done);
});

afterAll((done) => {
fs.unlinkSync(cssFilePath);
testServer.close(done);
});

describe('on browser client', () => {
it('should console.log progress', (done) => {
runBrowser().then(({ page, browser }) => {
const res = [];
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(255, 0, 0); }'
);
page.waitFor(10000).then(() => {
browser.close().then(() => {
// check that there is some percentage progress output
const regExp = /^\[WDS\] [0-9]{1,3}% - /;
const match = res.find((line) => {
return regExp.test(line);
});
// eslint-disable-next-line no-undefined
expect(match).not.toEqual(undefined);
done();
});
});
});

page.goto(`http://localhost:${port}/main`);
page.on('console', (data) => {
res.push(data.text());
});
});
});
});
});
});
4 changes: 4 additions & 0 deletions test/options.test.js
Expand Up @@ -230,6 +230,10 @@ describe('options', () => {
success: ['', 0, null],
failure: [false],
},
profile: {
success: [false],
failure: [''],
},
progress: {
success: [false],
failure: [''],
Expand Down
3 changes: 3 additions & 0 deletions test/ports-map.js
Expand Up @@ -40,6 +40,9 @@ const portsList = {
WebsocketServer: 1,
ClientMode: 1,
'clientMode-option': 1,
Progress: 1,
'progress-option': 1,
'profile-option': 1,
};

let startPort = 8079;
Expand Down
53 changes: 53 additions & 0 deletions test/server/profile-option.test.js
@@ -0,0 +1,53 @@
'use strict';

const webpack = require('webpack');
const Server = require('../../lib/Server');
const config = require('../fixtures/simple-config/webpack.config');
const port = require('../ports-map')['profile-option'];

describe('profile', () => {
describe('output', () => {
let mockStderr;

beforeAll(() => {
mockStderr = jest
.spyOn(process.stderr, 'write')
.mockImplementation(() => {});
});

it('should show percentage progress with profile data', (done) => {
const compiler = webpack(config);
const server = new Server(compiler, {
port,
// profile will only have an effect when progress is enabled
progress: true,
profile: true,
});

compiler.hooks.done.tap('webpack-dev-server', () => {
const calls = mockStderr.mock.calls;
mockStderr.mockRestore();
let foundProgress = false;
let foundProfile = false;
calls.forEach((call) => {
if (call[0].includes('0% compiling')) {
foundProgress = true;
}

// this is an indicator that the profile option is enabled,
// so we should expect to find it in stderr since profile is enabled
if (call[0].includes('ms after chunk modules optimization')) {
foundProfile = true;
}
});
expect(foundProgress).toBeTruthy();
expect(foundProfile).toBeTruthy();

server.close(done);
});

compiler.run(() => {});
server.listen(port, 'localhost');
});
});
});
51 changes: 51 additions & 0 deletions test/server/progress-option.test.js
@@ -0,0 +1,51 @@
'use strict';

const webpack = require('webpack');
const Server = require('../../lib/Server');
const config = require('../fixtures/simple-config/webpack.config');
const port = require('../ports-map')['progress-option'];

describe('progress', () => {
describe('output', () => {
let mockStderr;

beforeAll(() => {
mockStderr = jest
.spyOn(process.stderr, 'write')
.mockImplementation(() => {});
});

it('should show percentage progress without profile data', (done) => {
const compiler = webpack(config);
const server = new Server(compiler, {
port,
progress: true,
});

compiler.hooks.done.tap('webpack-dev-server', () => {
const calls = mockStderr.mock.calls;
mockStderr.mockRestore();
let foundProgress = false;
let foundProfile = false;
calls.forEach((call) => {
if (call[0].includes('0% compiling')) {
foundProgress = true;
}

// this is an indicator that the profile option is enabled,
// so we should expect to not find it in stderr since it is not enabled
if (call[0].includes('ms after chunk modules optimization')) {
foundProfile = true;
}
});
expect(foundProgress).toBeTruthy();
expect(foundProfile).toBeFalsy();

server.close(done);
});

compiler.run(() => {});
server.listen(port, 'localhost');
});
});
});

0 comments on commit 82de98f

Please sign in to comment.