Skip to content

Commit 6fec895

Browse files
committed
Add Encore.enableBuildNotifications() method
1 parent c6057af commit 6fec895

11 files changed

+315
-2
lines changed

index.js

+24
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,30 @@ const publicApi = {
608608
return this;
609609
},
610610

611+
/**
612+
* If enabled, display build notifications using
613+
* webpack-notifier.
614+
*
615+
* https://github.com/Turbo87/webpack-notifier
616+
*
617+
* Encore.enableBuildNotifications();
618+
*
619+
* // or configure the webpack-notifier options
620+
* // https://github.com/Turbo87/webpack-notifier#configuration
621+
* Encore.enableBuildNotifications(true, function(options) {
622+
* options.title = 'Webpack build';
623+
* });
624+
*
625+
* @param {boolean} enabled
626+
* @param {function} notifierPluginOptionsCallback
627+
* @returns {exports}
628+
*/
629+
enableBuildNotifications(enabled = true, notifierPluginOptionsCallback = () => {}) {
630+
webpackConfig.enableBuildNotifications(enabled, notifierPluginOptionsCallback);
631+
632+
return this;
633+
},
634+
611635
/**
612636
* Call this if you wish to disable the default
613637
* images loader.

lib/WebpackConfig.js

+11
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class WebpackConfig {
6060
this.useVueLoader = false;
6161
this.useTypeScriptLoader = false;
6262
this.useForkedTypeScriptTypeChecking = false;
63+
this.useWebpackNotifier = false;
6364

6465
// Features/Loaders options
6566
this.sassOptions = {
@@ -89,6 +90,7 @@ class WebpackConfig {
8990
this.loaderOptionsPluginOptionsCallback = () => {};
9091
this.manifestPluginOptionsCallback = () => {};
9192
this.uglifyJsPluginOptionsCallback = () => {};
93+
this.notifierPluginOptionsCallback = () => {};
9294
}
9395

9496
getContext() {
@@ -389,6 +391,15 @@ class WebpackConfig {
389391
this.vueLoaderOptionsCallback = vueLoaderOptionsCallback;
390392
}
391393

394+
enableBuildNotifications(enabled = true, notifierPluginOptionsCallback = () => {}) {
395+
if (typeof notifierPluginOptionsCallback !== 'function') {
396+
throw new Error('Argument 2 to enableBuildNotifications() must be a callback function.');
397+
}
398+
399+
this.useWebpackNotifier = enabled;
400+
this.notifierPluginOptionsCallback = notifierPluginOptionsCallback;
401+
}
402+
392403
disableImagesLoader() {
393404
this.useImagesLoader = false;
394405
}

lib/config-generator.js

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const definePluginUtil = require('./plugins/define');
3131
const uglifyPluginUtil = require('./plugins/uglify');
3232
const friendlyErrorPluginUtil = require('./plugins/friendly-errors');
3333
const assetOutputDisplay = require('./plugins/asset-output-display');
34+
const notifierPluginUtil = require('./plugins/notifier');
3435
const PluginPriorities = require('./plugins/plugin-priorities');
3536

3637
class ConfigGenerator {
@@ -232,6 +233,8 @@ class ConfigGenerator {
232233

233234
uglifyPluginUtil(plugins, this.webpackConfig);
234235

236+
notifierPluginUtil(plugins, this.webpackConfig);
237+
235238
const friendlyErrorPlugin = friendlyErrorPluginUtil(this.webpackConfig);
236239
plugins.push({
237240
plugin: friendlyErrorPlugin,

lib/features.js

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ const features = {
5757
// vue-template-compiler is a peer dep of vue-loader
5858
packages: ['vue', 'vue-loader', 'vue-template-compiler'],
5959
description: 'load VUE files'
60+
},
61+
notifier: {
62+
method: 'enableBuildNotifications()',
63+
packages: ['webpack-notifier'],
64+
description: 'display build notifications'
6065
}
6166
};
6267

lib/plugins/notifier.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
const pluginFeatures = require('../features');
13+
const PluginPriorities = require('./plugin-priorities');
14+
15+
/**
16+
* @param {Array} plugins
17+
* @param {WebpackConfig} webpackConfig
18+
* @return {void}
19+
*/
20+
module.exports = function(plugins, webpackConfig) {
21+
if (!webpackConfig.useWebpackNotifier) {
22+
return;
23+
}
24+
25+
pluginFeatures.ensurePackagesExist('notifier');
26+
27+
const notifierPluginOptions = {
28+
title: 'Webpack Encore'
29+
};
30+
31+
webpackConfig.notifierPluginOptionsCallback.apply(
32+
notifierPluginOptions,
33+
[notifierPluginOptions]
34+
);
35+
36+
const WebpackNotifier = require('webpack-notifier'); // eslint-disable-line
37+
plugins.push({
38+
plugin: new WebpackNotifier(notifierPluginOptions),
39+
priority: PluginPriorities.WebpackNotifier
40+
});
41+
};

lib/plugins/plugin-priorities.js

+1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ module.exports = {
2525
HashedModuleIdsPlugin: 0,
2626
NamedModulesPlugin: 0,
2727
WebpackChunkHash: 0,
28+
WebpackNotifier: 0,
2829
};

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"vue": "^2.3.4",
7676
"vue-loader": "^12.2.1",
7777
"vue-template-compiler": "^2.3.4",
78+
"webpack-notifier": "^1.5.0",
7879
"zombie": "^5.0.5"
7980
}
8081
}

test/WebpackConfig.js

+32
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,38 @@ describe('WebpackConfig object', () => {
604604
});
605605
});
606606

607+
608+
describe('enableBuildNotifications', () => {
609+
it('Calling method with default values', () => {
610+
const config = createConfig();
611+
config.enableBuildNotifications();
612+
613+
expect(config.useWebpackNotifier).to.be.true;
614+
});
615+
616+
it('Calling method without enabling it', () => {
617+
const config = createConfig();
618+
config.enableBuildNotifications(false);
619+
620+
expect(config.useWebpackNotifier).to.be.false;
621+
});
622+
623+
it('Calling method with options callback', () => {
624+
const config = createConfig();
625+
const callback = () => {};
626+
config.enableBuildNotifications(true, callback);
627+
628+
expect(config.useWebpackNotifier).to.be.true;
629+
expect(config.notifierPluginOptionsCallback).to.equal(callback);
630+
});
631+
632+
it('Calling method with invalid options callback', () => {
633+
const config = createConfig();
634+
635+
expect(() => config.enableBuildNotifications(true, 'FOO')).to.throw('must be a callback function');
636+
});
637+
});
638+
607639
describe('addPlugin', () => {
608640
it('extends the current registered plugins', () => {
609641
const config = createConfig();

test/index.js

+9
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,15 @@ describe('Public API', () => {
215215

216216
});
217217

218+
describe('enableBuildNotifications', () => {
219+
220+
it('must return the API object', () => {
221+
const returnedValue = api.enableBuildNotifications();
222+
expect(returnedValue).to.equal(api);
223+
});
224+
225+
});
226+
218227
describe('disableImagesLoader', () => {
219228

220229
it('must return the API object', () => {

test/plugins/notifier.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
const expect = require('chai').expect;
13+
const WebpackNotifier = require('webpack-notifier');
14+
const WebpackConfig = require('../../lib/WebpackConfig');
15+
const RuntimeConfig = require('../../lib/config/RuntimeConfig');
16+
const notifierPluginUtil = require('../../lib/plugins/notifier');
17+
18+
function createConfig() {
19+
const runtimeConfig = new RuntimeConfig();
20+
runtimeConfig.context = __dirname;
21+
runtimeConfig.babelRcFileExists = false;
22+
23+
return new WebpackConfig(runtimeConfig);
24+
}
25+
26+
describe('plugins/notifier', () => {
27+
it('disabled by default', () => {
28+
const config = createConfig();
29+
const plugins = [];
30+
31+
notifierPluginUtil(plugins, config);
32+
expect(plugins.length).to.equal(0);
33+
});
34+
35+
it('explicitly disabled', () => {
36+
const config = createConfig();
37+
const plugins = [];
38+
39+
config.enableBuildNotifications(false);
40+
41+
notifierPluginUtil(plugins, config);
42+
expect(plugins.length).to.equal(0);
43+
});
44+
45+
it('enabled with default settings', () => {
46+
const config = createConfig();
47+
const plugins = [];
48+
49+
config.enableBuildNotifications();
50+
51+
notifierPluginUtil(plugins, config);
52+
expect(plugins.length).to.equal(1);
53+
expect(plugins[0].plugin).to.be.instanceof(WebpackNotifier);
54+
expect(plugins[0].plugin.options.title).to.equal('Webpack Encore');
55+
});
56+
57+
it('enabled with options callback', () => {
58+
const config = createConfig();
59+
const plugins = [];
60+
61+
config.enableBuildNotifications(true, (options) => {
62+
options.title = 'foo';
63+
});
64+
65+
notifierPluginUtil(plugins, config);
66+
expect(plugins.length).to.equal(1);
67+
expect(plugins[0].plugin).to.be.instanceof(WebpackNotifier);
68+
expect(plugins[0].plugin.options.title).to.equal('foo');
69+
});
70+
});

0 commit comments

Comments
 (0)