Skip to content
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

Hook to act after others plugins invocation #1754

Closed
yabab-dev opened this issue Jul 4, 2018 · 5 comments · Fixed by #2337
Closed

Hook to act after others plugins invocation #1754

yabab-dev opened this issue Jul 4, 2018 · 5 comments · Fixed by #2337

Comments

@yabab-dev
Copy link

yabab-dev commented Jul 4, 2018

What problem does this feature solve?

(Plugins dev API)

I don't know if this already exists or possible, but I need a method to listen other plugins
invocation inside my plugin, to alter files contents.

Simple use case:

I want to replace default import of PWA plugin (import './registerServiceWorker') to :

if (process.client) require('./registerServiceWorker');

ATM, I use api.postProcessFiles() function, but this one only work if I do:

vue add @vue/pwa
vue add my-plugin

But if I do

vue add my-plugin
vue add @vue/pwa

my-plugin is not aware that PWA was added/invoked, so I cant transform the import statement.

What does the proposed API look like?

Something like api.postProcessFiles()

api.hookPluginInvoke('pluginName', (files) => {})

Thanks !

@yabab-dev yabab-dev changed the title Hook to act after others plugins invokation Hook to act after others plugins invocation Jul 4, 2018
@pksunkara
Copy link
Contributor

We can also use hook mechanism for events.

For example, apollo plugin has a postprocess where it's checks for typescripts and converts accordingly. Ideally this should be done by other 3rd party plugins too, but isn't it better that only typescript defines this and other plugins doesn't need to care about it? So, the typescript plugin defines something like this,

api.hook('afterGenerate', (files) => {
  convertFiles(files)
});

@pksunkara
Copy link
Contributor

pksunkara commented Jul 7, 2018

Here's my proposal. @yyx990803 @LinusBorg @Akryum Would appreciate thoughts.

Callback/Hook API Proposal

There are a lot of different reasons for having a plugin system. But one of the main reasons is to provide flexibility. A good system should allow plugins to interact with each other but still be independent of each other. All related code for certain feature should be contained to a certain plugin rather than relying on other plugins. Given below is the proposal of the API

Type of Callbacks

afterRender (postProcessFiles)

It behaves like how the current postProcessFiles behave. The function provided to this will be executed after template rendering is done and we get an JS object containing the files. It will only be executed for the plugins which were invoked. The new postProcessFiles will just be a wrapper for this.

Example

A plugin which generates modules would want to insert those modules into certain parts of existing code. This hook can be used to do that after the module is created.

afterAnyRender

The function provided to this will be executed after template rendering is done and we get an JS object containing the files. It will be executed for all the plugins installed in the project.

Example

Typescript plugin would want to convert all the files irrespective of which plugin they were generated from before writing them to the disk.

afterWrite (onCreateComplete)

It behaves like how the current onCreateComplete behave. The function provided to this will be executed after writing the generated files to the disk and installing the injected dependencies. It will only be executed for the plugins which were invoked. The new onCreateComplete will just be a wrapper for this.

Example

Similar example to afterRender.

afterAnyWrite

The function provided to this will be executed after writing the generated files to the disk and installing the injected dependencies. It will be executed for all the plugins installed in the project.

Example

Eslint plugin would want to lint --fix all the files.

beforeAnyRender

The function provided to this will be executed before the files are resolved in vue-cli. It will be executed for all the plugins installed in the project.

Example

Typescript plugin (or other conversion plugins) would want to convert the files from local disk to JS first, then let the other plugins manipulate them without caring what kind of format the files are in. And then after the files are rendered, the plugins can convert them back with afterAnyRender.

Drawbacks

Whenever a plugin is invoked, all the other plugins which were installed would be loaded to be checked if they have any callbacks. This might increase the running time of vue invoke.

Why in 3.0.0?

Once we release 3.0.0, there will be a lot of 3rd party plugins created by the users, and it will become an issue if they don't take care of how their plugins will interact with other plugins (especially typescript, lint). In order to make sure that it won't become a big mess that we try to unravel with the next major update, we should try to make sure that we do this before releasing v3.

@Akryum
Copy link
Member

Akryum commented Jul 8, 2018

@yyx990803 Thoughts?

@pksunkara
Copy link
Contributor

@yyx990803 Does the label you added means I can work on this and submit PR?

@pksunkara
Copy link
Contributor

Implemented in #2337. Please take a look. Will write docs as a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants