diff --git a/lib/prepare.js b/lib/prepare.js index 2d0fc56db2..d32a6bde08 100644 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -5,7 +5,7 @@ const yamlParser = require('js-yaml') const tomlParser = require('toml') const createMarkdown = require('./markdown') const tempPath = path.resolve(__dirname, 'app/.temp') -const { inferTitle, extractHeaders, parseFrontmatter } = require('./util') +const { inferTitle, extractHeaders, parseFrontmatter, loadPlugin, cloneOptions } = require('./util') fs.ensureDirSync(tempPath) @@ -74,6 +74,30 @@ if (!Object.assign) Object.assign = require('object-assign')` fs.existsSync(options.themeEnhanceAppPath) ) + // 7. handle user plugins + if (options.siteConfig.plugins && Array.isArray(options.siteConfig.plugins)) { + const { plugins } = options.siteConfig + + for (const plugin of plugins) { + let pluginRequired + let pluginOptions + const exposedOptions = cloneOptions(options) + if (typeof plugin === 'string') { + pluginRequired = loadPlugin(plugin, sourceDir) + } else if (Array.isArray(plugin)) { + pluginRequired = loadPlugin(plugin[0], sourceDir) + pluginOptions = plugin[1] + } + if (pluginRequired) { + try { + await pluginRequired({ exposedOptions, pluginOptions }) + } catch (e) { + throw e + } + } + } + } + return options } diff --git a/lib/util/index.js b/lib/util/index.js index 01ef6ac77f..f5179a96f9 100644 --- a/lib/util/index.js +++ b/lib/util/index.js @@ -84,3 +84,43 @@ exports.extractHeaders = (content, include = [], md) => { cache.set(key, res) return res } + +exports.loadPlugin = (pluginPath, sourceDir) => { + const fs = require('fs-extra') + const path = require('path') + const vuepressDir = path.resolve(sourceDir, '.vuepress') + let plugin + try { + if (fs.existsSync(path.resolve(vuepressDir, pluginPath))) { + plugin = require(path.resolve(vuepressDir, pluginPath)) + } else { + plugin = require(pluginPath) + } + } catch (e) { + throw e + } + return plugin +} + +exports.cloneOptions = (options) => { + const optionClone = {} + const readonlyProperties = ['sourceDir', 'outDir', 'publicPath', 'markdown', 'themePath', 'useDefaultTheme', 'notFoundPath'] + const writableProperties = ['siteConfig', 'pageFiles', 'siteData'] + + readonlyProperties.forEach(prop => { + Object.defineProperty(optionClone, prop, { + value: options[prop], + enumerable: true + }) + }) + + writableProperties.forEach(prop => { + Object.defineProperty(optionClone, prop, { + value: options[prop], + writable: true, + enumerable: true + }) + }) + + return optionClone +}