-
-
Notifications
You must be signed in to change notification settings - Fork 200
Add Encore.sortPlugins() method #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
c7fb64c
to
903abc4
Compare
Yo! I’m not against this solution... but I want to exhaust all other possibilities, just be sure this solution is inherently a bit complex. First, is the manifest plugin & copy plugin ordering issue confirmed? Do we know for sure that order matters? Second, do we know any other issues? Stop mentioned one about Uglify, can we find a real example? Also, what about adding a prependPlugin() method. Along with the existing method, you could then add plugins before the core plugins or after... which doesn’t give you complete flexibility, but much more. What do you think? |
Hi Ryan, I have no idea if that's the right solution either... see this more as a POC of what I described in the comments of the issue :) I tried to find a middle ground between something that wouldn't be flexible enough and something that would do the same than
I think it is, I've also seen it mentionned in this thread (ping @davidmpaz). From my understanding the order of plugins does matter. Let's say you have two plugins that both have a callback on the same event: function Plugin1() {}
Plugin1.prototype.apply = function(compiler) {
compiler.plugin('emit', function(compilation, callback) {
// ...
}
}
function Plugin2() {}
Plugin2.prototype.apply = function(compiler) {
compiler.plugin('emit', function(compilation, callback) {
// ...
}
} If you add I don't know if that's the case for UglifyJsPlugin since it highly depends on how it is implemented but I definitely think that's something that users should be able to configure.
I thought about that too, but I'm not sure that it would be flexible enough... what if a plugin needs to be added between two of the plugins added by Encore? |
Yes, this is certainly true. The question is: how often will this be a problem? Since it will be a problem at least sometimes (even if it's an edge-case), it makes sense to add a solution for it (and most people won't need this solution anyways, so it's not something they will even need to know about).
Very true again :) I have 2 counter-proposals: A) Add a and B) Internally, give each plugin a "priority" number - e.g. 10, 20, -10, 20. Then, add a 2nd argument to Wdyt? This PR is perfect... but it's trying to work around an inflexibility in Encore itself... so it's not super user friendly. Maybe (B) is a bit nicer? |
We should probably add it anyway but that'll not be enough if other plugins have the same kind of issue (e.g. ConcatPlugin).
I thought about that before starting to work on this PR. My main concern was that it wouldn't be easy enough to use/understand either: // We would have to add constants so we can still change priorities
// if needed later on without introducing breaking changes... but
// that'll only work if the users use them.
const PluginPriorities = require('@symfony/webpack-encore/lib/plugin-priorities');
Encore
.addPlugin(new Plugin1())
// Since we'll have the same priority than Plugin1 here (default),
// are we sure that it won't end-up being added before it when sorting
// all the plugins? AFAIK JavaScript sort is not guaranteed to be stable.
.addPlugin(new Plugin2())
// Unless we provide constants like "PluginPriorities.BeforeManifestPlugin"
// or "PluginPriorities.AfterUglifyJsPlugin" the user will have to do it manually
.addPlugin(new Plugin3(), PluginPriorities.ManifestPlugin - 1)
.addPlugin(new Plugin4(), PluginPriorities.UglifyJsPlugin + 1)
; |
A) Let's plan to add the About the priority stuff, I'm happy you were also thinking about it :)
It would still be a BC break to change the orders, even if we use the constants. This is exactly how Symfony does it with event listeners. It's a bit odd to choose random integers for priority. But, in practice, it works fine. I would expect to start with everything as a 0 priority, except (unless I'm missing something) the plugin in the future
This is an implementation detail... but yea... we would need to make sure the sort is maintained when the priorities are equal. We just need to figure that out :) I was picturing something like this: Encore
.addPlugin(new Plugin1())
.addPlugin(new Plugin2())
.addPlugin(new Plugin3(), -50)
.addPlugin(new Plugin4(), 50)
; Internally, if we had a file where all the plugin priorities were set to constants (even if most were 0), this would be a cool way of documenting them. In the future, if we realize that people need to be able to add plugins between two core plugins that have a 0 priority, we'll need to break BC (in a minor way) by giving those existing plugins different priority. We're not even sure if this is going to happen, so that's why I like this simple solution. |
If you don't mind the BC breaks I'm ok with that solution too 👍 Closing this PR! |
…d (Lyrkan) This PR was merged into the master branch. Discussion ---------- Add a priority parameter to the Encore.addPlugin() method Following the discussion in #165 this PR adds a `priority` parameter to the `Encore.addPlugin()` method in order to allow people to choose where their custom plugins will be added in the generated Webpack config (fixes #163). __Examples:__ ```js const Encore = require('@symfony/webpack-encore'); // Without setting the priority a plugin will be // appended to the other plugins. Encore.addPlugin(new CustomPlugin()); ``` ```js const Encore = require('@symfony/webpack-encore'); // If two plugins need to be sorted relatively to // eachother (CustomPluginB will be placed before // CustomPluginA): Encore .addPlugin(new CustomPluginA(), 100); .addPlugin(new CustomPluginB(), 50) ; ``` ```js const Encore = require('@symfony/webpack-encore'); const PluginPriorities = require('@symfony/webpack-encore/lib/plugins/plugin-priorities.js'); // For now all plugins added by Encore have a // priority of 0 (the same as the default priority for // custom plugins), but constants are available in // order to avoid BC breaks: Encore.addPlugin(new CustomPlugin(), PluginPriorities.UglifyJsPlugin); ``` Commits ------- b7461a1 Add a priority parameter to the Encore.addPlugin() method
This PR tries to solve #163 (ping @stof) by adding a
sortPlugins
method to the public API.Usage:
Since it relies on
instanceof
checks it won't allow to sort two instances of a given plugin relatively to eachother but I'm not sure that case needs to be handled anyway...I also changed the default position of the
ManifestPlugin
so it is added after custom plugins. This is done in order to prevent issues with other plugins that emit assets (e.g.CopyWebpackPlugin
andConcatPlugin
after #164 is merged).