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
RFC for "Inline Plugins" #515
base: master
Are you sure you want to change the base?
RFC for "Inline Plugins" #515
Conversation
@achambers perhaps the RFC should include an example of how one would extend from the base plugin class when defining an inline plugin. I don't think the second section (overriding hooks for existing plugins) is clear -- is this the same as subclassing an existing plugin? Could one do that by importing it, extending it and including it in inline plugins? |
@lukemelia said:
I was trying to give the simplest case, which I imagine is what most people will want this for. After all, the base plugin just returns the same object with some extra functionality. Having said that, I'd say most people probably just used the base plugin for the most part so that might be most familiar. I'll add that example in as well, to show that, just as with creating stand alone plugins, you can use the base plugin too.
Great question. So, my line of thought there as that we would be exposing a way to override hooks that will be added to the plugin instance, rather than override the plugin itself. Love to explore your thinking here. Could you elaborate on a use case on where you might want something more than simply overriding/adding hooks to the existing plugin instance? |
@lukemelia Just re-reading your comment again and noticed I misinterpreted your questions slightly.
The second part is not the same as subclassing a plugin. The intention of this section is to describe the ability to modify existing plugin instances by implement new hooks or overriding existing hooks.
Technically, yeh, I suppose they could. I guess they would need to do it something like this: let RedisPlugin = require('ember-cli-deploy-redis');
// ...snip...
inlinePlugins: [
{
name: 'log-to-console',
createDeployPlugin(/*options*/) {
let pluginInstance = RedisPlugin.createDeployPlugin(...arguments);
let pluginInstance.didBuild = function(context) {
console.log(`Project files built in: ${context.distDir}`);
};
return pluginInstance;
}
}
] Is this sort of what you were referring to? It feels kind of ugly but I'm not sure of a better way to do it because, as it stands, I'm proposing that the objects in the This has kind of turned in to a bit of a brain dump there as I explored my own thoughts while writing. Does it make sense? Does it answer your question? |
It helps to read the thinking here. I think learnability would be best supported by using well-understood extensibility tactics rather than introducing what is essentially a syntax to modify existing instances of objects to add new hooks or overriding existing hooks. i.e. let's either provide the ability to subclass prior to instantiation, OR the ability to access and mutate instances after instantiation, but not a novel way of extending a plugin. The point about |
This is interesting. I'd like to explore this. Instead of: redis: {
pipeline: {
hooks: {
upload() {
}
}
}
} we could do something like: redis: {
pipeline: {
mutatePluginInstance(pluginInstance) {
// enhance existing hook
let oldUpload = pluginInstance.upload;
pluginInstance.upload = function() {
// do something
return oldUpload(...arguments);
};
// override existing hook
pluginInstance.didUpload = function() {
// do something
}
// implement new hook
pluginInstance.didDeploy = function() {
// do something
}
return pluginInstance;
}
}
} I'm not so much of a fan of the Also, not mad about the naming of
I don't mind so much about the naming because that's what we use, although that might be more internally in the code more than publicly. We refer to the factory as plugins everywhere. Then when we alias plugins, we end up with plugin instances. This is no different really. This is an array plugins just like you Is there any difference? What will be possible here is also this: pipeline: {
alias: {
'log-to-console': { as: ['logA', 'logB'] }
},
inlinePlugins: [
{
name: 'log-to-console',
createDeployPlugin(options) {
name: options.name,
didBuild(context) {
console.log(`Project files built in: ${context.distDir}`);
}
}
}
]
},
logA: {
// config here
},
logB: {
// config here
} |
In regards to the naming, I guess the two potential paths we could take are:
Currently, |
I'm +1 on the approach for adding plugins. I think we should split off/defer the concept of mutating plugins to a separate effort. I don't like any of the solutions we've come up with yet, and I'm not clear on the use case either. |
@lukemelia said
Yep, that was my original intention. I'm in favour of that. |
@lukemelia I'm having a little internal debate with myself. Wondering if you could enlighten me with your thoughts. The {
name: 'ember-cli-deploy-build',
createDeployPlugin(options) {
return {
name: options.name,
willDeploy() {}
};
}
} Currently we have an expectation in our code that the addon name begins with When defining an inlinePlugin, it feels redundant to require I think I'm beginning to lean on keeping them symmetrical now, then, as a separate thread, opening up the conversation as to whether the requirement is needed at all, across the board. Do you have any strong feelings one way or the other? |
From DeployJS point of view (which is just an abstract layer over Ember CLI Deploy to bring it to React / Vue / Angular), not requiring
doesn't work as before then if you have to specify |
@achambers I don't think we need to require |
@achambers @lukemelia a bit late to the party here but my initial gut reaction seems to be confirmed after reading your discussion I think "part 1" of this RFC is very clear and good to go (adding plugins) while the second part (editing config) is not so yeah I think we all agreed on splitting 👍 |
re: the naming, agreed with @lukemelia iirc (hopefully I'm right) |
@lukemelia said:
@ghedamat said:
So, correct me if I'm wrong but the I totally understand our intention initially. I'm just not convinced it actually has anything to do with the So, the expectation in our code that the I totally agree with ye that the prefix is not needed for inline plugins. In fact I'm proposing that it's not needed for standalone plugins either. However that part is a separate RFC/PR/discussion. So, my preference (I flip flop here but for now this is it) would be to keep things symmetrical between standalone and inline plugins (for learnability, and consistency - I just see the deploy.js as another source from where to discover plugins), and keep the prefix, for now, and follow up with an across the board change after. This removes the slightly confusing "Well, you need to name them like this when creating a standalone plugin, but like this when you create an inline plugin" situation. Just to clarify, both of ye (@lukemelia and @ghedamat ) are happy for the naming "requirements" of inline plugins to be different to that of standalone plugins in this case? |
We could, when evaluating the inline plugin name, check for the Then we can also discuss, in a separate thread, whether this same logic could/should be applied for the stand alone addon name. |
RENDERED
This is a continuation from achambers#1 which was opened against the wrong repo.