Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Proposal] Plugin API #329

Closed
Closed
@ulivz

Description

@ulivz

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:

class XXXPlugin {
  constructor(pluginOptions) {
    this.options = pluginOptions
  }

  apply(app) {

    // app is the current VuePress app instance.
    // You can access all the app's properties and methods.
    // so to finish this plugin API, we need to rewrite the core as a class.

    ////////////////////////////
    // Basic extension
    ////////////////////////////

    // #1 extend webpack via webpack-chain.
    app.chainWebpack(config => { })

    // #2 extend markdown
    app.extendMarkdown(md => {
      md.use(require('markdown-it-xxx'))
    })

    // #3 add extra temp file.
    // so 'enhanceApp' and 'themeEnhanceApp' can be seperated as plugin.
    app.enhanceAppFiles.add('[relative]', content) // generate file to '.temp/relative'
    app.enhanceAppFiles.add('[absolute]') // copy to '.temp' if 'absolute' exists

    // #4. Write extra file to outDir.
    app.outFiles.add('[relative]', content) // generate file to 'outDir/relative'
    app.outFiles.add('[absolute]') // copy to outDir if 'absolute' exists

    // #5. Add extra data mixins, will be merged to core's dataMixin.
    app.dataMixin.add({
      computed: {
        $themeTitle () { /* ... */ }
      },
      methods: { /* ... */ }
    })

    // #6. enhance dev server ('webpack-serve')
    app.enhanceDevServer(server => {})

    // #7. extend the $page's data
    // so 'lastModified' support can be separated into a plugin.
    app.extendPageData((filepath, path, content, frontmatter) => {
      return {
        lastModified: getLastModified(filepath)
      }
    })

    ////////////////////////////
    // Life Cycle (Browser)
    ////////////////////////////

    // #8 called before creating Vue app. (DEV & BUILD)
    // So 'GA', 'SW' and 'scrollingActiveSidebarLink' could be separated into a plugin.
    // Consider if we should open the Layout's hooks ???
    app.hook.add('beforeCreateApp', ({ Vue, options, router, siteData }) => {})

    ////////////////////////////
    // Life Cycle (Node.js)
    ////////////////////////////

    // #9. called when all options was resolved. (DEV & BUILD)
    // with this hook, all the internal generate-related logic at prepare
    // can be separated into a plugin.
    app.hook.add('ready', () => {})

    // #10. called when webpack finished compiled. (DEV & BUILD)
    app.hook.add('compiled', () => {})

    // #11. called when webpack hot updated (only DEV)
    app.hook.add('updated', () => {})

    // #12. called when all files are generated (only BUILD)
    app.hook.add('generated', () => {})

    // ... we can also provide some useful utils.
  }
}

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 !!!

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions