From 0b0108d5ad14dddf77723edddeca4e5ae4f4c7fa Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Thu, 14 Sep 2023 11:42:07 +0800 Subject: [PATCH] feat(core): support templateBuildRenderer in app options and theme api (close #1120) --- docs/reference/config.md | 10 ++++++++++ docs/reference/theme-api.md | 17 +++++++++++++++-- docs/zh/reference/config.md | 12 +++++++++++- docs/zh/reference/theme-api.md | 17 +++++++++++++++-- packages/bundler-vite/src/build/renderPage.ts | 4 ++-- .../bundler-webpack/src/build/renderPage.ts | 4 ++-- packages/core/src/app/resolveAppOptions.ts | 3 ++- packages/core/src/app/resolveThemeInfo.ts | 4 ++++ .../core/src/app/setupAppThemeAndPlugins.ts | 4 ++++ packages/core/src/types/app/options.ts | 8 ++++++++ packages/core/src/types/theme.ts | 11 +++++++++++ .../core/tests/app/resolveAppOptions.spec.ts | 3 ++- 12 files changed, 86 insertions(+), 11 deletions(-) diff --git a/docs/reference/config.md b/docs/reference/config.md index 97a6f281fd..aac1f6c75b 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -334,6 +334,16 @@ Since VuePress will load temp files during dev and build, the temp directory sho Specify the path of the HTML template to be used for build. +### templateBuildRenderer + +- Type: `TemplateRenderer` + +- Default: `templateRenderer` + +- Details: + + Specify the HTML template renderer to be used for build. + ## Markdown Config ### markdown diff --git a/docs/reference/theme-api.md b/docs/reference/theme-api.md index 7eaaa5e259..5b5efed01c 100644 --- a/docs/reference/theme-api.md +++ b/docs/reference/theme-api.md @@ -73,13 +73,26 @@ export default { - Details: - Specify the HTML template for build. + Specify the path of the HTML template for build. - It would override the default value of [templateBuild](./config.md#templatebuild), but could be overridden by user config. + It would override the default value of [templateBuild](./config.md#templatebuild), and could be overridden by user config. - Also see: - [Config > templateBuild](./config.md#templatebuild) +### templateBuildRenderer + +- Type: `TemplateRenderer` + +- Details: + + Specify the HTML template renderer to be used for build. + + It would override the default value of [templateBuildRenderer](./config.md#templatebuildrenderer), and could be overridden by user config. + +- Also see: + - [Config > templateBuildRenderer](./config.md#templatebuildrenderer) + ### templateDev - Type: `string` diff --git a/docs/zh/reference/config.md b/docs/zh/reference/config.md index 518c04f9d8..67553315b6 100644 --- a/docs/zh/reference/config.md +++ b/docs/zh/reference/config.md @@ -331,7 +331,17 @@ VuePress 在开发和构建时会加载临时文件,因此临时文件目录 - 详情: - 指定构建时使用的 HTML 模板。 + 指定构建时使用的 HTML 模板路径。 + +### templateBuildRenderer + +- 类型: `TemplateRenderer` + +- 默认值: `templateRenderer` + +- 详情: + + 指定构建时使用的 HTML 模板渲染函数。 ## Markdown 配置 diff --git a/docs/zh/reference/theme-api.md b/docs/zh/reference/theme-api.md index 6d895046f0..5d3ff9cf8a 100644 --- a/docs/zh/reference/theme-api.md +++ b/docs/zh/reference/theme-api.md @@ -73,13 +73,26 @@ export default { - 详情: - 指定构建时使用的 HTML 模板。 + 指定构建时使用的 HTML 模板路径。 - 它会覆盖 [templateBuild](./config.md#templatebuild) 的默认值,但是也会被用户配置覆盖。 + 它会覆盖 [templateBuild](./config.md#templatebuild) 的默认值,同时也会被用户配置覆盖。 - 参考: - [配置 > templateBuild](./config.md#templatebuild) +### templateBuildRenderer + +- 类型: `TemplateRenderer` from `@vuepress/utils` + +- 详情: + + 指定构建时使用的 HTML 模板渲染函数。 + + 它会覆盖 [templateBuildRenderer](./config.md#templatebuildrenderer) 的默认值,同时也会被用户配置覆盖。 + +- 参考: + - [配置 > templateBuildRenderer](./config.md#templatebuildrenderer) + ### templateDev - 类型: `string` diff --git a/packages/bundler-vite/src/build/renderPage.ts b/packages/bundler-vite/src/build/renderPage.ts index b960ed4bb7..6e8af6ed88 100644 --- a/packages/bundler-vite/src/build/renderPage.ts +++ b/packages/bundler-vite/src/build/renderPage.ts @@ -1,5 +1,5 @@ import type { App, Page } from '@vuepress/core' -import { fs, renderHead, templateRenderer } from '@vuepress/utils' +import { fs, renderHead } from '@vuepress/utils' import type { OutputAsset, OutputChunk, RollupOutput } from 'rollup' import { ssrContextKey } from 'vue' import type { App as VueApp } from 'vue' @@ -50,7 +50,7 @@ export const renderPage = async ({ const pageChunkFiles = resolvePageChunkFiles({ page, output }) // generate html string - const html = await templateRenderer(ssrTemplate, { + const html = await app.options.templateBuildRenderer(ssrTemplate, { content: pageRendered, head: ssrContext.head.map(renderHead).join(''), lang: ssrContext.lang, diff --git a/packages/bundler-webpack/src/build/renderPage.ts b/packages/bundler-webpack/src/build/renderPage.ts index 17bd418955..ac7deb7378 100644 --- a/packages/bundler-webpack/src/build/renderPage.ts +++ b/packages/bundler-webpack/src/build/renderPage.ts @@ -1,6 +1,6 @@ import type { App, Page } from '@vuepress/core' import type { VuepressSSRContext } from '@vuepress/shared' -import { fs, renderHead, templateRenderer } from '@vuepress/utils' +import { fs, renderHead } from '@vuepress/utils' import { ssrContextKey } from 'vue' import type { App as VueApp } from 'vue' import type { SSRContext } from 'vue/server-renderer' @@ -67,7 +67,7 @@ export const renderPage = async ({ }) // generate html string - const html = await templateRenderer(ssrTemplate, { + const html = await app.options.templateBuildRenderer(ssrTemplate, { content: pageRendered, head: ssrContext.head.map(renderHead).join(''), lang: ssrContext.lang, diff --git a/packages/core/src/app/resolveAppOptions.ts b/packages/core/src/app/resolveAppOptions.ts index b34389644b..d851c3d969 100644 --- a/packages/core/src/app/resolveAppOptions.ts +++ b/packages/core/src/app/resolveAppOptions.ts @@ -1,5 +1,5 @@ import { createRequire } from 'node:module' -import { path } from '@vuepress/utils' +import { path, templateRenderer } from '@vuepress/utils' import type { AppConfig, AppOptions } from '../types/index.js' const require = createRequire(import.meta.url) @@ -61,6 +61,7 @@ export const resolveAppOptions = ({ shouldPreload, shouldPrefetch, templateBuild, + templateBuildRenderer: templateRenderer, bundler, debug, markdown, diff --git a/packages/core/src/app/resolveThemeInfo.ts b/packages/core/src/app/resolveThemeInfo.ts index 6dbbe3249b..34e9ff3b0d 100644 --- a/packages/core/src/app/resolveThemeInfo.ts +++ b/packages/core/src/app/resolveThemeInfo.ts @@ -10,6 +10,7 @@ export const resolveThemeInfo = (app: App, theme: Theme): ThemeInfo => { const themeInfo: ThemeInfo = { plugins: [...(themeObject.plugins ?? []), themeObject], templateBuild: themeObject.templateBuild, + templateBuildRenderer: themeObject.templateBuildRenderer, templateDev: themeObject.templateDev, } @@ -23,6 +24,9 @@ export const resolveThemeInfo = (app: App, theme: Theme): ThemeInfo => { return { plugins: [...parentThemeInfo.plugins, ...themeInfo.plugins], templateBuild: themeObject.templateBuild ?? parentThemeInfo.templateBuild, + templateBuildRenderer: + themeObject.templateBuildRenderer ?? + parentThemeInfo.templateBuildRenderer, templateDev: themeObject.templateDev ?? parentThemeInfo.templateDev, } } diff --git a/packages/core/src/app/setupAppThemeAndPlugins.ts b/packages/core/src/app/setupAppThemeAndPlugins.ts index 5c361567b0..f28c9f04e7 100644 --- a/packages/core/src/app/setupAppThemeAndPlugins.ts +++ b/packages/core/src/app/setupAppThemeAndPlugins.ts @@ -12,6 +12,10 @@ export const setupAppThemeAndPlugins = (app: App, config: AppConfig): void => { config.templateDev ?? themeInfo.templateDev ?? app.options.templateDev app.options.templateBuild = config.templateBuild ?? themeInfo.templateBuild ?? app.options.templateBuild + app.options.templateBuildRenderer = + config.templateBuildRenderer ?? + themeInfo.templateBuildRenderer ?? + app.options.templateBuildRenderer // use options plugins after theme plugins, allowing user to override theme plugins ;[...themeInfo.plugins, ...app.options.plugins] .flat() diff --git a/packages/core/src/types/app/options.ts b/packages/core/src/types/app/options.ts index 5aa26731b9..93271fd4bf 100644 --- a/packages/core/src/types/app/options.ts +++ b/packages/core/src/types/app/options.ts @@ -1,5 +1,6 @@ import type { MarkdownOptions } from '@vuepress/markdown' import type { SiteData } from '@vuepress/shared' +import type { TemplateRenderer } from '@vuepress/utils' import type { Bundler } from '../bundler.js' import type { PluginConfig } from '../plugin.js' import type { Theme } from '../theme.js' @@ -82,6 +83,13 @@ export interface AppConfigBuild { * @default '@vuepress/client/templates/build.html' */ templateBuild?: string + + /** + * Specify the HTML template renderer to be used for build + * + * @default templateRenderer from '@vuepress/utils' + */ + templateBuildRenderer?: TemplateRenderer } /** diff --git a/packages/core/src/types/theme.ts b/packages/core/src/types/theme.ts index a64e6c5227..40388ff975 100644 --- a/packages/core/src/types/theme.ts +++ b/packages/core/src/types/theme.ts @@ -1,3 +1,4 @@ +import type { TemplateRenderer } from '@vuepress/utils' import type { Plugin, PluginConfig, @@ -40,6 +41,11 @@ export interface ThemeObject extends Omit { */ templateBuild?: string + /** + * Allow specifying custom template renderer + */ + templateBuildRenderer?: TemplateRenderer + /** * Allow overriding default templateDev */ @@ -60,6 +66,11 @@ export interface ThemeInfo { */ templateBuild?: string + /** + * Default build template renderer + */ + templateBuildRenderer?: TemplateRenderer + /** * Default dev template */ diff --git a/packages/core/tests/app/resolveAppOptions.spec.ts b/packages/core/tests/app/resolveAppOptions.spec.ts index 3e4dc3ae19..a7f3ff125c 100644 --- a/packages/core/tests/app/resolveAppOptions.spec.ts +++ b/packages/core/tests/app/resolveAppOptions.spec.ts @@ -1,4 +1,4 @@ -import { path } from '@vuepress/utils' +import { path, templateRenderer } from '@vuepress/utils' import { describe, expect, it } from 'vitest' import { resolveAppOptions } from '../../src/index.js' @@ -38,6 +38,7 @@ describe('core > app > resolveAppOptions', () => { templateBuild: path.normalize( require.resolve('@vuepress/client/templates/build.html'), ), + templateBuildRenderer: templateRenderer, shouldPreload: true, shouldPrefetch: true, markdown: {},