-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[Proposal] Plugin API #329
Comments
Looks cool. Current code of core is a little messy, so I did some refactor work. But it's not a thorogh solution to the problem. With the help of plugin API, many existed functions could be separated into plugins. We should ensure the core has basic function, and then extract others into plugins.
Looks like an entire rewrite. No wonder you didn't merge my PRs. 😈 |
I was going to merge, but I saw @yyx990803 approved it just a few minutes ago, so I let it go. but then, Evan didn't merge it, LOL. 😅 |
@ulivz Will this plan begin after approved? Or you have had some draft code? |
I have started worked for that by following my plan, but writing code behind closed doors is not a good habit to write open source, so I want to hear more about your guys opinions. Just want it to be better. so welcome to all your ideas here. |
What about a dev branch to work together? (btw so when will the approved pr to be merged 😅 ) |
This is just what I feel 😳, maybe I haven't read and understood enough, but the idea of using the I probably prefer a config-based way to define the plugin, similar to how we define Vue components: module.exports = {
chainWebpack(config) {
...
}
extendMarkdown(md) {
md.use(require('markdown-it-xxx'))
}
clientHooks: {
beforeCreateApp(...) {
...
}
}
serverHooks: {
ready() {
}
compiled() {
}
updated() {
}
generated() {
}
}
}; Especially with the hooks, if we can make it looks like this, Vue developers might possibly find this more familiar? I personally find this a little bit more intuitive as the config describes what the methods are for. Perhaps bind Just some thoughts, not sure if you guys have considered yet. Let's make this plugin thing right! 🎉 |
|
Following Vue's convention is a better choice! cool ! |
What about a |
@yyx990803 After discussed at https://vuepress.slack.com/ with @meteorlxy and @ycmjason , we come up with a preliminary solution: 1 API1.1 Plugin's entryNow a plugin file would be like this: const path = require('path')
module.exports = options => ({
// Specify the client plugin's absolute path.
// If given, this file will be bundled to client's output
// and executed at client side.
client: path.resolve(__dirname, 'client.js'),
chainWebpack (config) { /* */ },
enhanceDevServer (server) { /* */ },
extendMarkdown (md) { /* */ },
enhanceAppFiles () {
return {
// Will be generated to '.temp/enhanceApp.js'
'enhanceApp.js': '[content]' // string | Buffer
}
},
outFiles () {
return {
// Will be generated to 'outDir/CNAME', BUILD only
'CNAME': options.domain // string | Buffer
}
},
// extend the $page's data
extendPageData ({ filepath, path /* router url */, content, frontmatter }) {
return {
lastModified: getLastModified(filepath)
}
},
// called when all options was resolved. (DEV & BUILD)
ready () { /* */ },
// called when webpack finished compiled. (DEV & BUILD)
compiled () { /* */ },
// called when dev server hot updated. (DEV only)
updated () { /* */ },
// called when all files are generated. (BUILD only)
generated () { /* */ }
})
1.2 Client entryAnd export default {
// API that vuepress only
beforeCreateApp ({ Vue, options, router, siteData }) {},
extendGlobalMixins ({ router, siteData }) {},
// Mix rest options in Layout component
mounted () {},
beforeDestroy () {},
methods: {}
} 2 Usage2.1 define at
|
May I just note that we don't have to keep a single entry. I prefer keeping them as We can refer to the // for the server entry
require('vuepress-plugin-blah/server')
// for the client entry
import plugin from 'vuepress-plugin-blah/client'; |
@meteorlxy and I originally also want it to be // .vuepress/config.js
module.exports = {
plugins: [
require('./xxxPlugin.js')
]
} and keep a single entry also doesn't restrict the structure and naming of a plugin. |
@ulivz This way we unify how things are done with plugins. |
We could also keep // .vuepress/config.js
module.exports = {
plugins: [
'./path/to/plugin-dir'
]
} Then we get ther const serverPlugins = config.plugins.map(dir => require(path.join(dir, 'server.js'))) |
Whether to keep a single entry is only a personal preference. just I prefer single entry with only using a @yyx990803 Need your opinion here. 😁 |
In addition, a single "main" entry may be more like a npm package. |
+1 @ycmjason client.js and server.js in same diretory. |
Background
Hey, guys, there is a previous work for plugin support: #240 (Lifecycle-based Plugin Support), but it seems only focus on providing Hook, and doesn't provide some useful APIs for plugin to use. so this issue is for that.
Proposal
My proposal is to leverage the plugin style from webpack. so for me, a ideal plugin would be like:
With this plugin mechanism, maybe we can do a lot of things we want to do.
Feel free to tell me your thoughts. and we can make plugin more powerful !!!
The text was updated successfully, but these errors were encountered: