Skip to content

Commit 0cc9f35

Browse files
committed
Add a priority parameter to the Encore.addPlugin() method
1 parent 929a253 commit 0cc9f35

25 files changed

+276
-80
lines changed

index.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,35 @@ const publicApi = {
269269
* For example, if you want to add the "webpack.IgnorePlugin()", then:
270270
* .addPlugin(new webpack.IgnorePlugin(requestRegExp, contextRegExp))
271271
*
272+
* By default custom plugins are added after the ones managed by Encore
273+
* but you can also set a priority to define where your plugin will be
274+
* added in the generated Webpack config.
275+
*
276+
* For example, if a plugin has a priority of 0 and you want to add
277+
* another plugin before it, then:
278+
*
279+
* .addPlugin(new MyWebpackPlugin(), -10)
280+
*
281+
* The priority of each plugin added by Encore can be found in the
282+
* "lib/plugins/plugin-priorities.js" file. It is recommended to use
283+
* these constants if you want to add a plugin using the same priority
284+
* as one managed by Encore in order to avoid backward compatibility
285+
* breaks.
286+
*
287+
* For example, if you want one of your plugins to have the same priority
288+
* than the DefinePlugin:
289+
*
290+
* const Encore = require('@symfony/webpack-encore');
291+
* const PluginPriorities = require('@symfony/webpack-encore/lib/plugins/plugin-priorities.js');
292+
*
293+
* Encore.addPlugin(new MyWebpackPlugin(), PluginPriorities.DefinePlugin);
294+
*
272295
* @param {string} plugin
296+
* @param {number} priority
273297
* @return {exports}
274298
*/
275-
addPlugin(plugin) {
276-
webpackConfig.addPlugin(plugin);
299+
addPlugin(plugin, priority = 0) {
300+
webpackConfig.addPlugin(plugin, priority);
277301

278302
return this;
279303
},

lib/WebpackConfig.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,15 @@ class WebpackConfig {
252252
this.styleEntries.set(name, src);
253253
}
254254

255-
addPlugin(plugin) {
256-
this.plugins.push(plugin);
255+
addPlugin(plugin, priority = 0) {
256+
if (typeof priority !== 'number') {
257+
throw new Error('Argument 2 to addPlugin() must be a number.');
258+
}
259+
260+
this.plugins.push({
261+
plugin: plugin,
262+
priority: priority
263+
});
257264
}
258265

259266
addLoader(loader) {

lib/config-generator.js

Lines changed: 24 additions & 3 deletions
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 PluginPriorities = require('./plugins/plugin-priorities');
3435

3536
class ConfigGenerator {
3637
/**
@@ -207,7 +208,7 @@ class ConfigGenerator {
207208
}
208209

209210
buildPluginsConfig() {
210-
let plugins = [];
211+
const plugins = [];
211212

212213
extractTextPluginUtil(plugins, this.webpackConfig);
213214

@@ -232,15 +233,35 @@ class ConfigGenerator {
232233
uglifyPluginUtil(plugins, this.webpackConfig);
233234

234235
const friendlyErrorPlugin = friendlyErrorPluginUtil(this.webpackConfig);
235-
plugins.push(friendlyErrorPlugin);
236+
plugins.push({
237+
plugin: friendlyErrorPlugin,
238+
priority: PluginPriorities.FriendlyErrorsWebpackPlugin
239+
});
236240

237241
assetOutputDisplay(plugins, this.webpackConfig, friendlyErrorPlugin);
238242

239243
this.webpackConfig.plugins.forEach(function(plugin) {
240244
plugins.push(plugin);
241245
});
242246

243-
return plugins;
247+
// Return sorted plugins
248+
return plugins
249+
.map((plugin, position) => Object.assign({}, plugin, { position: position }))
250+
.sort((a, b) => {
251+
// Keep the original order if two plugins have the same priority
252+
if (a.priority === b.priority) {
253+
return a.position - b.position;
254+
}
255+
256+
// A plugin with a priority of -10 will be placed before one
257+
// that has a priority of 0.
258+
if (a.priority < b.priority) {
259+
return -1;
260+
}
261+
262+
return 1;
263+
})
264+
.map((plugin) => plugin.plugin);
244265
}
245266

246267
buildStatsConfig() {

lib/plugins/asset-output-display.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
const pathUtil = require('../config/path-util');
1313
const AssetOutputDisplayPlugin = require('../friendly-errors/asset-output-display-plugin');
14+
const PluginPriorities = require('./plugin-priorities');
1415

1516
/**
1617
* Updates plugins array passed adding AssetOutputDisplayPlugin instance
@@ -26,5 +27,8 @@ module.exports = function(plugins, webpackConfig, friendlyErrorsPlugin) {
2627
}
2728

2829
const outputPath = pathUtil.getRelativeOutputPath(webpackConfig);
29-
plugins.push(new AssetOutputDisplayPlugin(outputPath, friendlyErrorsPlugin));
30+
plugins.push({
31+
plugin: new AssetOutputDisplayPlugin(outputPath, friendlyErrorsPlugin),
32+
priority: PluginPriorities.AssetOutputDisplayPlugin
33+
});
3034
};

lib/plugins/clean.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const CleanWebpackPlugin = require('clean-webpack-plugin');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* Updates plugins array passed adding CleanWebpackPlugin instance
@@ -34,8 +35,11 @@ module.exports = function(plugins, webpackConfig) {
3435
[cleanWebpackPluginOptions]
3536
);
3637

37-
plugins.push(new CleanWebpackPlugin(
38-
webpackConfig.cleanWebpackPluginPaths,
39-
cleanWebpackPluginOptions
40-
));
38+
plugins.push({
39+
plugin: new CleanWebpackPlugin(
40+
webpackConfig.cleanWebpackPluginPaths,
41+
cleanWebpackPluginOptions
42+
),
43+
priority: PluginPriorities.CleanWebpackPlugin
44+
});
4145
};

lib/plugins/commons-chunks.js

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const webpack = require('webpack');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -23,18 +24,21 @@ module.exports = function(plugins, webpackConfig) {
2324
}
2425

2526
// if we're extracting a vendor chunk, set it up!
26-
plugins.push(new webpack.optimize.CommonsChunkPlugin({
27-
name: [
28-
webpackConfig.sharedCommonsEntryName,
29-
/*
30-
* Always dump a 2nd file - manifest.json that
31-
* will contain the webpack manifest information.
32-
* This changes frequently, and without this line,
33-
* it would be packaged inside the "shared commons entry"
34-
* file - e.g. vendor.js, which would prevent long-term caching.
35-
*/
36-
'manifest'
37-
],
38-
minChunks: Infinity,
39-
}));
27+
plugins.push({
28+
plugin: new webpack.optimize.CommonsChunkPlugin({
29+
name: [
30+
webpackConfig.sharedCommonsEntryName,
31+
/*
32+
* Always dump a 2nd file - manifest.json that
33+
* will contain the webpack manifest information.
34+
* This changes frequently, and without this line,
35+
* it would be packaged inside the "shared commons entry"
36+
* file - e.g. vendor.js, which would prevent long-term caching.
37+
*/
38+
'manifest'
39+
],
40+
minChunks: Infinity,
41+
}),
42+
priority: PluginPriorities.CommonsChunkPlugin
43+
});
4044
};

lib/plugins/define.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const webpack = require('webpack');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -33,5 +34,8 @@ module.exports = function(plugins, webpackConfig) {
3334
[definePluginOptions]
3435
);
3536

36-
plugins.push(new webpack.DefinePlugin(definePluginOptions));
37+
plugins.push({
38+
plugin: new webpack.DefinePlugin(definePluginOptions),
39+
priority: PluginPriorities.DefinePlugin
40+
});
3741
};

lib/plugins/delete-unused-entries.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const DeleteUnusedEntriesJSPlugin = require('../webpack/delete-unused-entries-js-plugin');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -18,8 +19,11 @@ const DeleteUnusedEntriesJSPlugin = require('../webpack/delete-unused-entries-js
1819
*/
1920
module.exports = function(plugins, webpackConfig) {
2021

21-
plugins.push(new DeleteUnusedEntriesJSPlugin(
22-
// transform into an Array
23-
[... webpackConfig.styleEntries.keys()]
24-
));
22+
plugins.push({
23+
plugin: new DeleteUnusedEntriesJSPlugin(
24+
// transform into an Array
25+
[... webpackConfig.styleEntries.keys()]
26+
),
27+
priority: PluginPriorities.DeleteUnusedEntriesJSPlugin
28+
});
2529
};

lib/plugins/extract-text.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const ExtractTextPlugin = require('extract-text-webpack-plugin');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -49,5 +50,8 @@ module.exports = function(plugins, webpackConfig) {
4950
[extractTextPluginOptions]
5051
);
5152

52-
plugins.push(new ExtractTextPlugin(extractTextPluginOptions));
53+
plugins.push({
54+
plugin: new ExtractTextPlugin(extractTextPluginOptions),
55+
priority: PluginPriorities.ExtractTextWebpackPlugin
56+
});
5357
};

lib/plugins/forked-ts-types.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); // eslint-disable-line
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {WebpackConfig} webpackConfig
@@ -25,5 +26,8 @@ module.exports = function(webpackConfig) {
2526
[config]
2627
);
2728

28-
webpackConfig.addPlugin(new ForkTsCheckerWebpackPlugin(config));
29+
webpackConfig.addPlugin(
30+
new ForkTsCheckerWebpackPlugin(config),
31+
PluginPriorities.ForkTsCheckerWebpackPlugin
32+
);
2933
};

lib/plugins/loader-options.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const webpack = require('webpack');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -39,5 +40,8 @@ module.exports = function(plugins, webpackConfig) {
3940
[loaderOptionsPluginOptions]
4041
);
4142

42-
plugins.push(new webpack.LoaderOptionsPlugin(loaderOptionsPluginOptions));
43+
plugins.push({
44+
plugin: new webpack.LoaderOptionsPlugin(loaderOptionsPluginOptions),
45+
priority: PluginPriorities.LoaderOptionsPlugin
46+
});
4347
};

lib/plugins/manifest.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const ManifestPlugin = require('../webpack/webpack-manifest-plugin');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -37,5 +38,8 @@ module.exports = function(plugins, webpackConfig) {
3738
[manifestPluginOptions]
3839
);
3940

40-
plugins.push(new ManifestPlugin(manifestPluginOptions));
41+
plugins.push({
42+
plugin: new ManifestPlugin(manifestPluginOptions),
43+
priority: PluginPriorities.WebpackManifestPlugin
44+
});
4145
};

lib/plugins/plugin-priorities.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <fabien@symfony.com>
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+
module.exports = {
13+
ExtractTextWebpackPlugin: 0,
14+
DeleteUnusedEntriesJSPlugin: 0,
15+
WebpackManifestPlugin: 0,
16+
LoaderOptionsPlugin: 0,
17+
ProvidePlugin: 0,
18+
CleanWebpackPlugin: 0,
19+
CommonsChunkPlugin: 0,
20+
DefinePlugin: 0,
21+
UglifyJsPlugin: 0,
22+
FriendlyErrorsWebpackPlugin: 0,
23+
AssetOutputDisplayPlugin: 0,
24+
ForkTsCheckerWebpackPlugin: 0,
25+
HashedModuleIdsPlugin: 0,
26+
NamedModulesPlugin: 0,
27+
WebpackChunkHash: 0,
28+
};

lib/plugins/uglify.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const webpack = require('webpack');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -31,5 +32,8 @@ module.exports = function(plugins, webpackConfig) {
3132
[uglifyJsPluginOptions]
3233
);
3334

34-
plugins.push(new webpack.optimize.UglifyJsPlugin(uglifyJsPluginOptions));
35+
plugins.push({
36+
plugin: new webpack.optimize.UglifyJsPlugin(uglifyJsPluginOptions),
37+
priority: PluginPriorities.UglifyJsPlugin
38+
});
3539
};

lib/plugins/variable-provider.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'use strict';
1111

1212
const webpack = require('webpack');
13+
const PluginPriorities = require('./plugin-priorities');
1314

1415
/**
1516
* @param {Array} plugins
@@ -18,6 +19,9 @@ const webpack = require('webpack');
1819
*/
1920
module.exports = function(plugins, webpackConfig) {
2021
if (Object.keys(webpackConfig.providedVariables).length > 0) {
21-
plugins.push(new webpack.ProvidePlugin(webpackConfig.providedVariables));
22+
plugins.push({
23+
plugin: new webpack.ProvidePlugin(webpackConfig.providedVariables),
24+
priority: PluginPriorities.ProvidePlugin
25+
});
2226
}
2327
};

0 commit comments

Comments
 (0)