diff --git a/packages/@vuepress/core/lib/node/Page.js b/packages/@vuepress/core/lib/node/Page.js index 0da8783010..0ea0242d84 100644 --- a/packages/@vuepress/core/lib/node/Page.js +++ b/packages/@vuepress/core/lib/node/Page.js @@ -142,7 +142,7 @@ module.exports = class Page { this._computed = computed this._localePath = computed.$localePath - this.enhance(enhancers) + await this.enhance(enhancers) this.buildPermalink() } @@ -282,13 +282,13 @@ module.exports = class Page { * @api private */ - enhance (enhancers) { + async enhance (enhancers) { for (const { name: pluginName, value: enhancer } of enhancers) { try { - enhancer(this) + await enhancer(this) } catch (error) { console.log(error) - throw new Error(`[${pluginName}] excuete extendPageData failed.`) + throw new Error(`[${pluginName}] execute extendPageData failed.`) } } } diff --git a/packages/@vuepress/core/lib/node/__tests__/prepare/Page.spec.js b/packages/@vuepress/core/lib/node/__tests__/prepare/Page.spec.js index 2f3b4b6f30..530f7f4af5 100644 --- a/packages/@vuepress/core/lib/node/__tests__/prepare/Page.spec.js +++ b/packages/@vuepress/core/lib/node/__tests__/prepare/Page.spec.js @@ -102,5 +102,54 @@ describe('Page', () => { expect(page._content.startsWith('---')).toBe(true) expect(page._strippedContent.startsWith('---')).toBe(false) }) + + describe('enhance - ', () => { + let page + let enhancers + + beforeEach(() => { + page = new Page({ path: '/' }, app) + enhancers = [ + { + pluginName: 'foo', + value: jest.fn() + }, + { + pluginName: 'foo', + value: jest.fn() + } + ] + global.console.log = jest.fn() + }) + + test('should loop over sync enhancers', async () => { + await page.enhance(enhancers) + + return enhancers.map(enhancer => expect(enhancer.value).toBeCalled()) + }) + + test('should loop over sync and async enhancers', async () => { + const mixedEnhancers = [...enhancers, { + pluginName: 'blog', + value: jest.fn().mockResolvedValue({}) + }] + await page.enhance(mixedEnhancers) + + return mixedEnhancers.map(enhancer => expect(enhancer.value).toBeCalled()) + }) + + test('should log when enhancing when failing', async () => { + const error = { errorMessage: 'this is an error message' } + expect.assertions(1) + try { + await page.enhance([{ + pluginName: 'error-plugin', + value: jest.fn().mockRejectedValue(error) + }]) + } catch (e) { + expect(console.log).toBeCalledWith(error) + } + }) + }) }) diff --git a/packages/docs/docs/plugin/option-api.md b/packages/docs/docs/plugin/option-api.md index b9c729fc89..53e594c3b9 100644 --- a/packages/docs/docs/plugin/option-api.md +++ b/packages/docs/docs/plugin/option-api.md @@ -280,7 +280,7 @@ import { SOURCE_DIR } from '@dynamic/constants' ## extendPageData -- Type: `Function` +- Type: `Function|AsyncFunction` - Default: `undefined` A function used to extend or edit the [$page](../guide/global-computed.md#page) object. This function will be invoking once for each page at compile time. @@ -308,6 +308,16 @@ module.exports = { } ``` +Note that `extendPageData` can also be defined as an asynchronous function. + +```js +module.exports = { + async extendPageData ($page) { + $page.xxx = await getAsyncData() + } +} +``` + ::: warning Note These fields starting with an `_` means you can only access them during build time. :::