index.js 3.8 KB
Newer Older
1
const chalk = require('chalk')
U
ULIVZ 已提交
2 3
const Hook = require('./core/Hook')
const instantiateAPI = require('./option/instantiateOption')
4
const logger = require('../util/logger')
U
ULIVZ 已提交
5 6
const { resolvePlugin, inferPluginName } = require('./util')
const { assertTypes } = require('../util/shared')
U
ULIVZ 已提交
7
const { HOOK, OPTION } = require('./constants')
U
ULIVZ 已提交
8

U
ULIVZ 已提交
9
module.exports = class Plugin {
U
ULIVZ 已提交
10
  constructor (context) {
U
ULIVZ 已提交
11
    this.hooks = {}
U
ULIVZ 已提交
12
    this.options = {}
U
ULIVZ 已提交
13
    this._pluginContext = context
U
ULIVZ 已提交
14 15
    this.extendHooks(Object.values(HOOK))
    this.extendOptions(Object.values(OPTION))
U
ULIVZ 已提交
16 17 18 19 20
  }

  use (pluginRaw, pluginOptions) {
    let plugin = resolvePlugin(pluginRaw)
    if (typeof plugin === 'function') {
21 22 23
      // 'Object.create' here is to give each plugin a separate context,
      // but also own the inheritance context.
      plugin = plugin(pluginOptions, Object.create(this._pluginContext))
U
ULIVZ 已提交
24
    }
U
ULIVZ 已提交
25 26 27 28 29 30 31 32 33 34 35

    plugin = Object.assign({
      enabled: true,
      name: inferPluginName(pluginRaw, plugin)
    }, plugin)

    if (plugin.enabled) {
      this.applyPlugin(plugin)
    } else {
      logger.debug(`\n${chalk.gray(`[vuepress-plugin-${plugin.name}]`)} disabled.`)
    }
U
ULIVZ 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49
    return this
  }

  useByConfigs (pluginConfigs) {
    if (!Array.isArray(pluginConfigs)) {
      pluginConfigs = []
    }
    pluginConfigs.forEach(pluginConfigs => {
      pluginConfigs = Array.isArray(pluginConfigs)
        ? pluginConfigs
        : [pluginConfigs]
      const [pluginRaw, pluginOptions] = pluginConfigs
      this.use(pluginRaw, pluginOptions)
    })
50
    return this
U
ULIVZ 已提交
51 52 53 54 55 56 57 58
  }

  extendHooks (hooks) {
    hooks.forEach(hook => {
      this.hooks[hook] = new Hook(hook)
    })
  }

U
ULIVZ 已提交
59 60 61
  extendOptions (options) {
    options.forEach(api => {
      this.options[api] = instantiateAPI(api)
U
ULIVZ 已提交
62 63 64
    })
  }

65 66 67 68 69 70 71
  registerHook (name, hook, pluginName, types) {
    const { valid, warnMsg } = assertTypes(hook, types)
    if (valid) {
      this.hooks[name].tap(pluginName, hook)
    } else if (hook !== undefined) {
      logger.warn(
        `${chalk.gray(`[vuepress-plugin-${pluginName}]`)} ` +
U
ULIVZ 已提交
72
        `Invalid value for "hook" ${chalk.cyan(name)}: ${warnMsg}`
73
      )
U
ULIVZ 已提交
74 75 76 77
    }
    return this
  }

U
ULIVZ 已提交
78
  registerOption (name, api, pluginName, types) {
79 80
    const { valid, warnMsg } = assertTypes(api, types)
    if (valid) {
U
ULIVZ 已提交
81
      this.options[name].tap(pluginName, api)
82 83 84 85 86
    } else if (api !== undefined) {
      logger.warn(
        `${chalk.gray(`[vuepress-plugin-${pluginName}]`)} ` +
        `Invalid value for "option" ${chalk.cyan(name)}: ${warnMsg}`
      )
U
ULIVZ 已提交
87 88 89 90
    }
    return this
  }

U
ULIVZ 已提交
91
  applyPlugin ({
U
ULIVZ 已提交
92 93 94 95 96 97 98 99 100 101
    name,
    chainWebpack,
    enhanceDevServer,
    extendMarkdown,
    enhanceAppFiles,
    outFiles,
    extendPageData,
    ready,
    compiled,
    updated,
U
ULIVZ 已提交
102
    generated,
103
    clientDynamicModules,
U
ULIVZ 已提交
104 105
    clientRootMixin,
    additionalPages
U
ULIVZ 已提交
106
  }) {
U
ULIVZ 已提交
107
    logger.tip(`\nApply plugin ${chalk.cyan(name)}...`)
U
ULIVZ 已提交
108

U
ULIVZ 已提交
109
    this
U
ULIVZ 已提交
110 111 112 113
      .registerHook(HOOK.READY, ready, name, [Function])
      .registerHook(HOOK.COMPILED, compiled, name, [Function])
      .registerHook(HOOK.UPDATED, updated, name, [Function])
      .registerHook(HOOK.GENERATED, generated, name, [Function])
U
ULIVZ 已提交
114 115

    this
U
ULIVZ 已提交
116 117 118 119 120 121
      .registerOption(OPTION.CHAIN_WEBPACK, chainWebpack, name, [Function])
      .registerOption(OPTION.ENHANCE_DEV_SERVER, enhanceDevServer, name, [Function])
      .registerOption(OPTION.EXTEND_MARKDOWN, extendMarkdown, name, [Function])
      .registerOption(OPTION.EXTEND_PAGE_DATA, extendPageData, name, [Function])
      .registerOption(OPTION.ENHANCE_APP_FILES, enhanceAppFiles, name, [Array, Function])
      .registerOption(OPTION.OUT_FILES, outFiles, name, [Object])
122
      .registerOption(OPTION.CLIENT_DYNAMIC_MODULES, clientDynamicModules, name, [Function])
123
      .registerOption(OPTION.CLIENT_ROOT_MIXIN, clientRootMixin, name, [String])
U
ULIVZ 已提交
124
      .registerOption(OPTION.ADDITIONAL_PAGES, additionalPages, name, [Function, Array])
U
ULIVZ 已提交
125 126
  }
}