index.js 3.5 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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
    }
    plugin = Object.assign(plugin, { name: inferPluginName(pluginRaw, plugin) })
    this.applyPlugin(plugin)
    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)
    })
41
    return this
U
ULIVZ 已提交
42 43 44 45 46 47 48 49
  }

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

U
ULIVZ 已提交
50 51 52
  extendOptions (options) {
    options.forEach(api => {
      this.options[api] = instantiateAPI(api)
U
ULIVZ 已提交
53 54 55
    })
  }

56 57 58 59 60 61 62
  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 已提交
63
        `Invalid value for "hook" ${chalk.cyan(name)}: ${warnMsg}`
64
      )
U
ULIVZ 已提交
65 66 67 68
    }
    return this
  }

U
ULIVZ 已提交
69
  registerOption (name, api, pluginName, types) {
70 71
    const { valid, warnMsg } = assertTypes(api, types)
    if (valid) {
U
ULIVZ 已提交
72
      this.options[name].tap(pluginName, api)
73 74 75 76 77
    } else if (api !== undefined) {
      logger.warn(
        `${chalk.gray(`[vuepress-plugin-${pluginName}]`)} ` +
        `Invalid value for "option" ${chalk.cyan(name)}: ${warnMsg}`
      )
U
ULIVZ 已提交
78 79 80 81
    }
    return this
  }

U
ULIVZ 已提交
82
  applyPlugin ({
U
ULIVZ 已提交
83 84 85 86 87 88 89 90 91 92
    name,
    chainWebpack,
    enhanceDevServer,
    extendMarkdown,
    enhanceAppFiles,
    outFiles,
    extendPageData,
    ready,
    compiled,
    updated,
U
ULIVZ 已提交
93
    generated,
94 95
    clientDynamicModules,
    clientRootMixin
U
ULIVZ 已提交
96
  }) {
U
ULIVZ 已提交
97
    logger.tip(`\nApply plugin ${chalk.cyan(name)}...`)
U
ULIVZ 已提交
98

U
ULIVZ 已提交
99
    this
U
ULIVZ 已提交
100 101 102 103
      .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 已提交
104 105

    this
U
ULIVZ 已提交
106 107 108 109 110 111
      .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])
112
      .registerOption(OPTION.CLIENT_DYNAMIC_MODULES, clientDynamicModules, name, [Function])
113
      .registerOption(OPTION.CLIENT_ROOT_MIXIN, clientRootMixin, name, [String])
U
ULIVZ 已提交
114 115
  }
}