mirror of
https://github.com/wahyd4/vuepress.git
synced 2026-08-11 22:36:59 +10:00
244 lines
6.3 KiB
JavaScript
244 lines
6.3 KiB
JavaScript
'use strict'
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
const instantiateOption = require('./override/instantiateOption')
|
|
const { flattenPlugin, normalizePluginsConfig } = require('./util')
|
|
const { PLUGIN_OPTION_MAP } = require('./constants')
|
|
const {
|
|
moduleResolver: { getPluginResolver },
|
|
datatypes: { assertTypes, isPlainObject },
|
|
logger, chalk
|
|
} = require('@vuepress/shared-utils')
|
|
|
|
/**
|
|
* Expose PluginAPI class.
|
|
*/
|
|
|
|
module.exports = class PluginAPI {
|
|
constructor (context) {
|
|
this.options = {}
|
|
this._pluginContext = context
|
|
this._pluginQueue = []
|
|
this._initialized = false
|
|
this._pluginResolver = getPluginResolver()
|
|
this.initializeOptions(PLUGIN_OPTION_MAP)
|
|
}
|
|
|
|
/**
|
|
* Get enabled plugins
|
|
*
|
|
* @returns {array}
|
|
* @api public
|
|
*/
|
|
|
|
get enabledPlugins () {
|
|
return this._pluginQueue.filter(({ enabled }) => enabled)
|
|
}
|
|
|
|
/**
|
|
* Get disabled plugins
|
|
*
|
|
* @returns {array}
|
|
* @api public
|
|
*/
|
|
|
|
get disabledPlugins () {
|
|
return this._pluginQueue.filter(({ enabled }) => !enabled)
|
|
}
|
|
|
|
/**
|
|
* initialize plugin.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
initialize () {
|
|
this._initialized = true
|
|
this._pluginQueue.forEach(plugin => {
|
|
if (plugin.enabled) {
|
|
this.applyPlugin(plugin)
|
|
} else {
|
|
logger.debug(`${chalk.gray(`[${plugin.name}]`)} disabled.`)
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Normalize plugin and push it to the plugin queue.
|
|
*
|
|
* @param {object} pluginRaw
|
|
* @param {object} pluginOptions
|
|
* @returns {module.PluginAPI}
|
|
* @api public
|
|
*/
|
|
|
|
use (pluginRaw, pluginOptions = {}) {
|
|
if (this._initialized) {
|
|
throw new Error(`Cannot add new plugins after initialization.`)
|
|
}
|
|
|
|
let plugin
|
|
if (isPlainObject(pluginRaw) && pluginRaw.$$normalized) {
|
|
plugin = pluginRaw
|
|
} else {
|
|
plugin = this.normalizePlugin(pluginRaw, pluginOptions)
|
|
}
|
|
|
|
if (plugin.multiple !== true) {
|
|
const duplicateIndex = this._pluginQueue.findIndex(({ name }) => name === plugin.name)
|
|
if (duplicateIndex !== -1) {
|
|
this._pluginQueue.splice(duplicateIndex, 1)
|
|
}
|
|
}
|
|
|
|
this._pluginQueue.push(plugin)
|
|
|
|
if (plugin.plugins) {
|
|
logger.debug(`Plugins defined at ${chalk.gray(plugin.name)}`, plugin.plugins)
|
|
this.useByPluginsConfig(plugin.plugins)
|
|
}
|
|
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* normalize plugin
|
|
* @param pluginRaw
|
|
* @param pluginOptions
|
|
* @api public
|
|
*/
|
|
|
|
normalizePlugin (pluginRaw, pluginOptions = {}) {
|
|
let plugin = this._pluginResolver.resolve(pluginRaw)
|
|
if (!plugin.entry) {
|
|
console.warn(`[vuepress] cannot resolve plugin "${pluginRaw}"`)
|
|
return this
|
|
}
|
|
plugin = flattenPlugin(plugin, pluginOptions, this._pluginContext, this)
|
|
plugin.$$normalized = true
|
|
return plugin
|
|
}
|
|
|
|
/**
|
|
* Use plugin by config.
|
|
*
|
|
* @param pluginsConfig
|
|
* @returns {module.PluginAPI}
|
|
* @api public
|
|
*/
|
|
|
|
useByPluginsConfig (pluginsConfig) {
|
|
pluginsConfig = normalizePluginsConfig(pluginsConfig)
|
|
pluginsConfig.forEach(([pluginRaw, pluginOptions]) => {
|
|
this.use(pluginRaw, pluginOptions)
|
|
})
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* initialize plugin options.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
initializeOptions () {
|
|
Object.keys(PLUGIN_OPTION_MAP).forEach(key => {
|
|
const option = PLUGIN_OPTION_MAP[key]
|
|
this.options[option.name] = instantiateOption(option)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Register plugin option.
|
|
*
|
|
* @param {string} key
|
|
* @param {any} value
|
|
* @param {string} pluginName
|
|
* @returns {module.PluginAPI}
|
|
* @api private
|
|
*/
|
|
|
|
registerOption (key, value, pluginName) {
|
|
const option = PLUGIN_OPTION_MAP[key]
|
|
const types = option.types
|
|
const { valid, warnMsg } = assertTypes(value, types)
|
|
if (valid) {
|
|
this.options[option.name].add(pluginName, value)
|
|
} else if (value !== undefined) {
|
|
logger.warn(
|
|
`${chalk.gray(pluginName)} `
|
|
+ `Invalid value for "option" ${chalk.cyan(option.name)}: ${warnMsg}`
|
|
)
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* apply plugin.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
applyPlugin ({
|
|
// info
|
|
name: pluginName,
|
|
shortcut,
|
|
|
|
// hooks
|
|
ready,
|
|
compiled,
|
|
updated,
|
|
generated,
|
|
|
|
// options
|
|
chainWebpack,
|
|
extendMarkdown,
|
|
chainMarkdown,
|
|
enhanceAppFiles,
|
|
outFiles,
|
|
extendPageData,
|
|
clientDynamicModules,
|
|
clientRootMixin,
|
|
additionalPages,
|
|
globalUIComponents,
|
|
define,
|
|
alias,
|
|
extendCli,
|
|
beforeDevServer,
|
|
afterDevServer
|
|
}) {
|
|
const isInternalPlugin = pluginName.startsWith('@vuepress/internal-')
|
|
logger[isInternalPlugin ? 'debug' : 'tip'](pluginLog(pluginName, shortcut))
|
|
|
|
this
|
|
.registerOption(PLUGIN_OPTION_MAP.READY.key, ready, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.COMPILED.key, compiled, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.UPDATED.key, updated, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.GENERATED.key, generated, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.CHAIN_WEBPACK.key, chainWebpack, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.EXTEND_MARKDOWN.key, extendMarkdown, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.CHAIN_MARKDOWN.key, chainMarkdown, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.EXTEND_PAGE_DATA.key, extendPageData, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.ENHANCE_APP_FILES.key, enhanceAppFiles, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.OUT_FILES.key, outFiles, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.CLIENT_DYNAMIC_MODULES.key, clientDynamicModules, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.CLIENT_ROOT_MIXIN.key, clientRootMixin, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.ADDITIONAL_PAGES.key, additionalPages, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.GLOBAL_UI_COMPONENTS.key, globalUIComponents, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.DEFINE.key, define, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.ALIAS.key, alias, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.EXTEND_CLI.key, extendCli, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.BEFORE_DEV_SERVER.key, beforeDevServer, pluginName)
|
|
.registerOption(PLUGIN_OPTION_MAP.AFTER_DEV_SERVER.key, afterDevServer, pluginName)
|
|
}
|
|
}
|
|
|
|
function pluginLog (name, shortcut) {
|
|
return shortcut
|
|
? `Apply plugin ${chalk.magenta(shortcut)} ${chalk.gray(`(i.e. "${name}")`)} ...`
|
|
: `Apply plugin ${chalk.magenta(name)} ...`
|
|
}
|