From 734551500af8caf792f277fa1334c628380b1dab Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Sat, 6 Oct 2018 00:52:07 +0800 Subject: [PATCH] feat($core): 'plugins' in plugin. --- .../@vuepress/core/lib/plugin-api/index.js | 42 +++++++++++++++---- .../@vuepress/core/lib/prepare/AppContext.js | 40 +++++++++++------- .../@vuepress/core/lib/prepare/loadTheme.js | 15 +++---- .../core/lib/webpack/createBaseConfig.js | 2 +- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/packages/@vuepress/core/lib/plugin-api/index.js b/packages/@vuepress/core/lib/plugin-api/index.js index 32ea357c40..fac3e639fe 100644 --- a/packages/@vuepress/core/lib/plugin-api/index.js +++ b/packages/@vuepress/core/lib/plugin-api/index.js @@ -9,7 +9,7 @@ const { flattenPlugin, normalizePluginsConfig } = require('./util') const { PLUGIN_OPTION_MAP } = require('./constants') const { shortcutPackageResolver: { resolvePlugin }, - datatypes: { assertTypes }, + datatypes: { assertTypes, isPlainObject }, env: { isDebug }, logger, chalk } = require('@vuepress/shared-utils') @@ -79,22 +79,50 @@ module.exports = class PluginAPI { if (this._initialized) { throw new Error(`Cannot add new plugins after initialization.`) } - let plugin = resolvePlugin(pluginRaw) - if (!plugin.module) { - console.warn(`[vuepress] cannot resolve plugin "${pluginRaw}"`) - return this + + let plugin + if (isPlainObject(pluginRaw) && pluginRaw.$$normalized) { + plugin = pluginRaw + } else { + plugin = this.normalizePlugin(pluginRaw, pluginOptions) } - plugin = flattenPlugin(plugin, pluginOptions, this._pluginContext, this) + 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(`\nStart to use plugins defined at ${chalk.gray(plugin.name)}`) + logger.debug(JSON.stringify(plugin.plugins, null, 2)) + this.useByPluginsConfig(plugin.plugins) + } + return this } + /** + * normalize plugin + * @param pluginRaw + * @param pluginOptions + * @api public + */ + + normalizePlugin (pluginRaw, pluginOptions = {}) { + let plugin = resolvePlugin(pluginRaw) + if (!plugin.module) { + 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. * @@ -183,7 +211,7 @@ module.exports = class PluginAPI { }) { const isInternalPlugin = pluginName.startsWith('@vuepress/internal-') if (shortcut) { - logger.tip(`\nApply plugin ${chalk.magenta(shortcut)} ${chalk.gray(`(i.e. "${pluginName}")`)} ...`, !isInternalPlugin) + logger.tip(`\nApply plugin ${chalk.magenta(shortcut)} ${chalk.gray(`(i.e. "${pluginName}")`)} ...`) } else if (!isInternalPlugin || isDebug) { logger.tip(`\nApply plugin ${chalk.magenta(pluginName)} ...`) } diff --git a/packages/@vuepress/core/lib/prepare/AppContext.js b/packages/@vuepress/core/lib/prepare/AppContext.js index 15d201bfbd..f22a2c894a 100644 --- a/packages/@vuepress/core/lib/prepare/AppContext.js +++ b/packages/@vuepress/core/lib/prepare/AppContext.js @@ -71,7 +71,11 @@ module.exports = class AppContext { this.normalizeHeadTagUrls() await this.resolveTheme() this.resolveTemplates() - this.resolvePlugins() + + this.applyInternalPlugins() + this.applyUserPlugins() + this.pluginAPI.initialize() + this.markdown = createMarkdown(this) await this.resolvePages() @@ -88,12 +92,12 @@ module.exports = class AppContext { } /** - * Apply internal and user plugins + * Apply internal plugins * * @api private */ - resolvePlugins () { + applyInternalPlugins () { const themeConfig = this.themeConfig const siteConfig = this.siteConfig @@ -105,8 +109,6 @@ module.exports = class AppContext { this.pluginAPI // internl core plugins - .use(Object.assign({}, siteConfig, { name: '@vuepress/internal-site-config' })) - .use(Object.assign({}, this.themeEntryFile, { name: '@vuepress/internal-theme-entry-file' })) .use(require('../internal-plugins/siteData')) .use(require('../internal-plugins/routes')) .use(require('../internal-plugins/rootMixins')) @@ -117,18 +119,25 @@ module.exports = class AppContext { .use(require('../internal-plugins/pageComponents')) .use(require('../internal-plugins/transformModule')) .use(require('../internal-plugins/dataBlock')) - // user plugin - .useByPluginsConfig(this.cliOptions.plugins) - .useByPluginsConfig(this.siteConfig.plugins) - .useByPluginsConfig(this.themePlugins) - // built-in plugins .use('@vuepress/last-updated', shouldUseLastUpdated) .use('@vuepress/register-components', { componentsDir: [ path.resolve(this.sourceDir, '.vuepress/components') ] }) - .initialize() + } + + /** + * Apply user plugins + * + * @api private + */ + + applyUserPlugins () { + this.pluginAPI + .useByPluginsConfig(this.cliOptions.plugins) + .use(this.themeEntryFile) + .use(Object.assign({}, this.siteConfig, { name: '@vuepress/internal-site-config' })) } /** @@ -194,8 +203,8 @@ module.exports = class AppContext { defaultDevTemplate ]) - logger.debug('SSR Template File: ' + chalk.gray(ssrTemplate)) - logger.debug('DEV Template File: ' + chalk.gray(devTemplate)) + logger.debug('\nSSR Template File: ' + chalk.gray(ssrTemplate)) + logger.debug('\nDEV Template File: ' + chalk.gray(devTemplate)) this.devTemplate = devTemplate this.ssrTemplate = ssrTemplate } @@ -252,8 +261,7 @@ module.exports = class AppContext { */ async resolveTheme () { - const theme = this.siteConfig.theme || this.cliOptions.theme - Object.assign(this, (await loadTheme(theme, this.sourceDir, this.vuepressDir))) + Object.assign(this, (await loadTheme(this))) } /** @@ -312,7 +320,7 @@ function createTemp (tempPath) { fs.emptyDirSync(tempPath) } - logger.tip(`Temp directory: ${chalk.gray(tempPath)}`) + logger.tip(`\nTemp directory: ${chalk.gray(tempPath)}`) const tempCache = new Map() async function writeTemp (file, content) { diff --git a/packages/@vuepress/core/lib/prepare/loadTheme.js b/packages/@vuepress/core/lib/prepare/loadTheme.js index 28c5014ff6..82b8dafa02 100644 --- a/packages/@vuepress/core/lib/prepare/loadTheme.js +++ b/packages/@vuepress/core/lib/prepare/loadTheme.js @@ -28,7 +28,10 @@ const { * @returns {Promise} */ -module.exports = async function loadTheme (theme, sourceDir, vuepressDir) { +module.exports = async function loadTheme (ctx) { + const { siteConfig, cliOptions, sourceDir, vuepressDir, pluginAPI } = ctx + const theme = siteConfig.theme || cliOptions.theme + const localThemePath = path.resolve(vuepressDir, 'theme') const useLocalTheme = !fs.existsSync(theme) && @@ -58,16 +61,15 @@ module.exports = async function loadTheme (theme, sourceDir, vuepressDir) { } try { - themeEntryFile = require(themePath) + themeEntryFile = pluginAPI.normalizePlugin(themePath, ctx.themeConfig) + themeEntryFile.name = '@vuepress/internal-theme-entry-file' + themeEntryFile.shortcut = null } catch (error) { themeEntryFile = {} } // handle theme api - const { - plugins: themePlugins, - palette: themePalette - } = themeEntryFile + const { palette: themePalette } = themeEntryFile const layoutDirs = [ path.resolve(themePath, 'layouts'), @@ -133,7 +135,6 @@ module.exports = async function loadTheme (theme, sourceDir, vuepressDir) { themePath, layoutComponentMap, themeEntryFile, - themePlugins, themePalette, themeName, themeShortcut diff --git a/packages/@vuepress/core/lib/webpack/createBaseConfig.js b/packages/@vuepress/core/lib/webpack/createBaseConfig.js index 667cf12ff2..b8f04b9ef6 100644 --- a/packages/@vuepress/core/lib/webpack/createBaseConfig.js +++ b/packages/@vuepress/core/lib/webpack/createBaseConfig.js @@ -82,7 +82,7 @@ module.exports = function createBaseConfig ({ } else { cacheDirectory = path.resolve(__dirname, '../../node_modules/.cache/vuepress') } - logger.debug('Cache directory: ' + chalk.gray(cacheDirectory)) + logger.debug('\nCache directory: ' + chalk.gray(cacheDirectory)) if (!cache) { logger.tip('\nClean cache...\n') fs.emptyDirSync(cacheDirectory)