From b4ff6a74f3de3c50cc9823d0d47c1f0d80448a5f Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Wed, 11 Sep 2024 00:57:03 +0800 Subject: [PATCH 01/11] refactor: remove temp page files and load page component via bundler --- .../components/ComponentForMarkdownImport.vue | 5 - .../ComponentForMarkdownImportBar.vue | 5 + .../ComponentForMarkdownImportFoo.vue | 5 + .../markdowns/dangling-markdown-file.md | 5 + e2e/docs/README.md | 2 + e2e/docs/markdown/vue-components.md | 11 +- e2e/tests/markdown/vue-components.spec.ts | 7 +- packages/bundler-vite/src/plugins/index.ts | 1 + .../src/plugins/vuepressMarkdownPlugin.ts | 53 +++ .../src/plugins/vuepressVuePlugin.ts | 1 + .../bundler-vite/src/resolveViteConfig.ts | 2 + packages/bundler-webpack/package.json | 1 + .../src/build/createClientConfig.ts | 12 - .../src/build/createServerConfig.ts | 15 - .../src/config/createBaseConfig.ts | 2 +- .../src/config/handleModule.ts | 5 +- .../src/config/handleModuleVue.ts | 62 +++- .../src/loaders/vuepressMarkdownLoader.cts | 3 + .../src/loaders/vuepressMarkdownLoader.ts | 37 +++ packages/bundler-webpack/tsup.config.ts | 1 + packages/core/src/app/appInit.ts | 4 +- .../src/app/prepare/preparePageComponent.ts | 12 +- packages/core/src/app/resolveAppPages.ts | 11 +- packages/core/src/page/createPage.ts | 2 + .../core/src/page/resolvePageComponentInfo.ts | 13 +- packages/core/src/types/app/app.ts | 7 + .../core/tests/app/resolveAppPages.spec.ts | 8 +- .../page/resolvePageComponentInfo.spec.ts | 18 +- .../src/plugins/assetsPlugin/assetsPlugin.ts | 17 +- .../src/plugins/assetsPlugin/resolveLink.ts | 24 +- .../tests/plugins/assetsPlugin.spec.ts | 313 ++++-------------- 31 files changed, 319 insertions(+), 345 deletions(-) delete mode 100644 e2e/docs/.vuepress/components/ComponentForMarkdownImport.vue create mode 100644 e2e/docs/.vuepress/components/ComponentForMarkdownImportBar.vue create mode 100644 e2e/docs/.vuepress/components/ComponentForMarkdownImportFoo.vue create mode 100644 e2e/docs/.vuepress/markdowns/dangling-markdown-file.md create mode 100644 packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts create mode 100644 packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.cts create mode 100644 packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts diff --git a/e2e/docs/.vuepress/components/ComponentForMarkdownImport.vue b/e2e/docs/.vuepress/components/ComponentForMarkdownImport.vue deleted file mode 100644 index 7108c4a426..0000000000 --- a/e2e/docs/.vuepress/components/ComponentForMarkdownImport.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/e2e/docs/.vuepress/components/ComponentForMarkdownImportBar.vue b/e2e/docs/.vuepress/components/ComponentForMarkdownImportBar.vue new file mode 100644 index 0000000000..0d9fa2f2f6 --- /dev/null +++ b/e2e/docs/.vuepress/components/ComponentForMarkdownImportBar.vue @@ -0,0 +1,5 @@ + diff --git a/e2e/docs/.vuepress/components/ComponentForMarkdownImportFoo.vue b/e2e/docs/.vuepress/components/ComponentForMarkdownImportFoo.vue new file mode 100644 index 0000000000..3905e34a83 --- /dev/null +++ b/e2e/docs/.vuepress/components/ComponentForMarkdownImportFoo.vue @@ -0,0 +1,5 @@ + diff --git a/e2e/docs/.vuepress/markdowns/dangling-markdown-file.md b/e2e/docs/.vuepress/markdowns/dangling-markdown-file.md new file mode 100644 index 0000000000..5bf006ada9 --- /dev/null +++ b/e2e/docs/.vuepress/markdowns/dangling-markdown-file.md @@ -0,0 +1,5 @@ +
+ +dangling markdown file + +
diff --git a/e2e/docs/README.md b/e2e/docs/README.md index eb63f0ccbf..b3586d97fe 100644 --- a/e2e/docs/README.md +++ b/e2e/docs/README.md @@ -1,3 +1,5 @@ foo ## Home H2 + +demo diff --git a/e2e/docs/markdown/vue-components.md b/e2e/docs/markdown/vue-components.md index c038c08795..f38b703d0b 100644 --- a/e2e/docs/markdown/vue-components.md +++ b/e2e/docs/markdown/vue-components.md @@ -1,8 +1,13 @@ - + + + diff --git a/e2e/tests/markdown/vue-components.spec.ts b/e2e/tests/markdown/vue-components.spec.ts index f33b1dbc68..1f3f1818d6 100644 --- a/e2e/tests/markdown/vue-components.spec.ts +++ b/e2e/tests/markdown/vue-components.spec.ts @@ -6,7 +6,10 @@ test('should render vue components correctly', async ({ page }) => { await expect(page.locator('.component-for-markdown-global p')).toHaveText( 'component for markdown global', ) - await expect(page.locator('.component-for-markdown-import p')).toHaveText( - 'component for markdown import', + await expect(page.locator('.component-for-markdown-import-foo p')).toHaveText( + 'component for markdown import foo', + ) + await expect(page.locator('.component-for-markdown-import-bar p')).toHaveText( + 'component for markdown import bar', ) }) diff --git a/packages/bundler-vite/src/plugins/index.ts b/packages/bundler-vite/src/plugins/index.ts index 0268dc0dba..9ff20c8972 100644 --- a/packages/bundler-vite/src/plugins/index.ts +++ b/packages/bundler-vite/src/plugins/index.ts @@ -1,5 +1,6 @@ export * from './vuepressBuildPlugin.js' export * from './vuepressConfigPlugin.js' export * from './vuepressDevPlugin.js' +export * from './vuepressMarkdownPlugin.js' export * from './vuepressUserConfigPlugin.js' export * from './vuepressVuePlugin.js' diff --git a/packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts b/packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts new file mode 100644 index 0000000000..eb072f840c --- /dev/null +++ b/packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts @@ -0,0 +1,53 @@ +import type { App } from '@vuepress/core' +import { parsePageContent, renderPageSfcBlocksToVue } from '@vuepress/core' +import { path } from '@vuepress/utils' +import type { Plugin } from 'vite' + +/** + * Handle markdown transformation + */ +export const vuepressMarkdownPlugin = ({ app }: { app: App }): Plugin => ({ + name: 'vuepress:markdown', + + enforce: 'pre', + + transform(code, id) { + if (!id.endsWith('.md')) return + + // get the matched page by file path (id) + const page = app.pagesMap[id] + + // if the page content is not changed, render it to vue component directly + if (page?.content === code) { + return renderPageSfcBlocksToVue(page.sfcBlocks) + } + + // parse the markdown content to sfc blocks and render it to vue component + const { sfcBlocks } = parsePageContent({ + app, + content: code, + filePath: id, + filePathRelative: path.relative(app.dir.source(), id), + options: {}, + }) + return renderPageSfcBlocksToVue(sfcBlocks) + }, + + async handleHotUpdate(ctx) { + if (!ctx.file.endsWith('.md')) return + + // read the source code + const code = await ctx.read() + + // parse the content to sfc blocks + const { sfcBlocks } = parsePageContent({ + app, + content: code, + filePath: ctx.file, + filePathRelative: path.relative(app.dir.source(), ctx.file), + options: {}, + }) + + ctx.read = () => renderPageSfcBlocksToVue(sfcBlocks) + }, +}) diff --git a/packages/bundler-vite/src/plugins/vuepressVuePlugin.ts b/packages/bundler-vite/src/plugins/vuepressVuePlugin.ts index d85656c731..5688e4c2fb 100644 --- a/packages/bundler-vite/src/plugins/vuepressVuePlugin.ts +++ b/packages/bundler-vite/src/plugins/vuepressVuePlugin.ts @@ -11,5 +11,6 @@ export const vuepressVuePlugin = ({ options: ViteBundlerOptions }): Plugin => vuePlugin({ + include: [/\.vue$/, /\.md$/], ...options.vuePluginOptions, }) diff --git a/packages/bundler-vite/src/resolveViteConfig.ts b/packages/bundler-vite/src/resolveViteConfig.ts index 6fafcec449..f950836f92 100644 --- a/packages/bundler-vite/src/resolveViteConfig.ts +++ b/packages/bundler-vite/src/resolveViteConfig.ts @@ -5,6 +5,7 @@ import { vuepressBuildPlugin, vuepressConfigPlugin, vuepressDevPlugin, + vuepressMarkdownPlugin, vuepressUserConfigPlugin, vuepressVuePlugin, } from './plugins/index.js' @@ -31,6 +32,7 @@ export const resolveViteConfig = ({ }, plugins: [ vuepressConfigPlugin({ app, isBuild, isServer }), + vuepressMarkdownPlugin({ app }), vuepressDevPlugin({ app }), vuepressBuildPlugin({ isServer }), vuepressVuePlugin({ options }), diff --git a/packages/bundler-webpack/package.json b/packages/bundler-webpack/package.json index 28d32a8f12..893252e963 100644 --- a/packages/bundler-webpack/package.json +++ b/packages/bundler-webpack/package.json @@ -20,6 +20,7 @@ "author": "meteorlxy", "type": "module", "imports": { + "#vuepress-markdown-loader": "./dist/vuepress-markdown-loader.cjs", "#vuepress-ssr-loader": "./dist/vuepress-ssr-loader.cjs" }, "exports": { diff --git a/packages/bundler-webpack/src/build/createClientConfig.ts b/packages/bundler-webpack/src/build/createClientConfig.ts index 6266b9bda1..7f0ae415de 100644 --- a/packages/bundler-webpack/src/build/createClientConfig.ts +++ b/packages/bundler-webpack/src/build/createClientConfig.ts @@ -1,4 +1,3 @@ -import { createRequire } from 'node:module' import type { App } from '@vuepress/core' import { fs } from '@vuepress/utils' import CopyWebpackPlugin from 'copy-webpack-plugin' @@ -10,8 +9,6 @@ import { createClientBaseConfig } from '../config/index.js' import type { WebpackBundlerOptions } from '../types.js' import { createClientPlugin } from './createClientPlugin.js' -const require = createRequire(import.meta.url) - /** * Filename of the client manifest file that generated by client plugin */ @@ -27,15 +24,6 @@ export const createClientConfig = async ( isBuild: true, }) - // use internal vuepress-ssr-loader to handle SSR dependencies - config.module - .rule('vue') - .test(/\.vue$/) - .use('vuepress-ssr-loader') - .before('vue-loader') - .loader(require.resolve('#vuepress-ssr-loader')) - .end() - // vuepress client plugin, handle client assets info for ssr config .plugin('vuepress-client') diff --git a/packages/bundler-webpack/src/build/createServerConfig.ts b/packages/bundler-webpack/src/build/createServerConfig.ts index d21b75b034..600141751d 100644 --- a/packages/bundler-webpack/src/build/createServerConfig.ts +++ b/packages/bundler-webpack/src/build/createServerConfig.ts @@ -1,11 +1,8 @@ -import { createRequire } from 'node:module' import type { App } from '@vuepress/core' import type Config from 'webpack-5-chain' import { createBaseConfig } from '../config/index.js' import type { WebpackBundlerOptions } from '../types.js' -const require = createRequire(import.meta.url) - export const createServerConfig = async ( app: App, options: WebpackBundlerOptions, @@ -43,17 +40,5 @@ export const createServerConfig = async ( // do not need to minimize server bundle config.optimization.minimize(false) - // use internal vuepress-ssr-loader to handle SSR dependencies - config.module - .rule('vue') - .test(/\.vue$/) - .use('vuepress-ssr-loader') - .before('vue-loader') - .loader(require.resolve('#vuepress-ssr-loader')) - .options({ - app, - }) - .end() - return config } diff --git a/packages/bundler-webpack/src/config/createBaseConfig.ts b/packages/bundler-webpack/src/config/createBaseConfig.ts index 0b6e0accc3..b6d8bec3b0 100644 --- a/packages/bundler-webpack/src/config/createBaseConfig.ts +++ b/packages/bundler-webpack/src/config/createBaseConfig.ts @@ -52,7 +52,7 @@ export const createBaseConfig = async ({ /** * module */ - handleModule({ options, config, isBuild, isServer }) + handleModule({ app, options, config, isBuild, isServer }) /** * plugins diff --git a/packages/bundler-webpack/src/config/handleModule.ts b/packages/bundler-webpack/src/config/handleModule.ts index be33ca6a73..14d8a57b0c 100644 --- a/packages/bundler-webpack/src/config/handleModule.ts +++ b/packages/bundler-webpack/src/config/handleModule.ts @@ -1,3 +1,4 @@ +import type { App } from '@vuepress/core' import type Config from 'webpack-5-chain' import type { WebpackBundlerOptions } from '../types.js' import { handleModuleAssets } from './handleModuleAssets.js' @@ -11,11 +12,13 @@ import { handleModuleVue } from './handleModuleVue.js' * Set webpack module */ export const handleModule = ({ + app, options, config, isBuild, isServer, }: { + app: App options: WebpackBundlerOptions config: Config isBuild: boolean @@ -27,7 +30,7 @@ export const handleModule = ({ ) // vue files - handleModuleVue({ options, config, isServer }) + handleModuleVue({ app, options, config, isBuild, isServer }) // pug files, for templates handleModulePug({ config }) diff --git a/packages/bundler-webpack/src/config/handleModuleVue.ts b/packages/bundler-webpack/src/config/handleModuleVue.ts index 335159cc1b..4065ff16a7 100644 --- a/packages/bundler-webpack/src/config/handleModuleVue.ts +++ b/packages/bundler-webpack/src/config/handleModuleVue.ts @@ -1,7 +1,9 @@ import { createRequire } from 'node:module' +import type { App } from '@vuepress/core' import type { VueLoaderOptions } from 'vue-loader' import { VueLoaderPlugin } from 'vue-loader' import type Config from 'webpack-5-chain' +import type { VuepressMarkdownLoaderOptions } from '../loaders/vuepressMarkdownLoader' import type { WebpackBundlerOptions } from '../types.js' const require = createRequire(import.meta.url) @@ -10,26 +12,62 @@ const require = createRequire(import.meta.url) * Set webpack module to handle vue files */ export const handleModuleVue = ({ + app, options, config, + isBuild, isServer, }: { + app: App options: WebpackBundlerOptions config: Config + isBuild: boolean isServer: boolean }): void => { - // .vue files - config.module - .rule('vue') - .test(/\.vue$/) - // use vue-loader - .use('vue-loader') - .loader(require.resolve('vue-loader')) - .options({ - ...options.vue, - isServerBuild: isServer, - } as VueLoaderOptions) - .end() + const applyVuePipeline = ({ + rule, + isMd, + }: { + rule: Config.Rule + isMd: boolean + }): void => { + // use internal vuepress-ssr-loader to handle SSR dependencies + if (isBuild) { + rule + .use('vuepress-ssr-loader') + .loader(require.resolve('#vuepress-ssr-loader')) + .end() + } + + // use official vue-loader + rule + .use('vue-loader') + .loader(require.resolve('vue-loader')) + .options({ + ...options.vue, + isServerBuild: isServer, + } satisfies VueLoaderOptions) + .end() + + // use internal vuepress-markdown-loader to handle markdown files + if (isMd) { + rule + .use('vuepress-markdown-loader') + .loader(require.resolve('#vuepress-markdown-loader')) + .options({ app } satisfies VuepressMarkdownLoaderOptions) + .end() + } + } + + applyVuePipeline({ + rule: config.module.rule('md').test(/\.md$/), + isMd: true, + }) + + applyVuePipeline({ + rule: config.module.rule('vue').test(/\.vue$/), + isMd: false, + }) // use vue-loader plugin config.plugin('vue-loader').use(VueLoaderPlugin) diff --git a/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.cts b/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.cts new file mode 100644 index 0000000000..f4b3001431 --- /dev/null +++ b/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.cts @@ -0,0 +1,3 @@ +const loader = require('./vuepressMarkdownLoader.js') + +module.exports = loader.vuepressMarkdownLoader diff --git a/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts b/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts new file mode 100644 index 0000000000..d9ca435d14 --- /dev/null +++ b/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts @@ -0,0 +1,37 @@ +import type { App } from '@vuepress/core' +import type { LoaderDefinitionFunction } from 'webpack' + +export interface VuepressMarkdownLoaderOptions { + app: App +} + +/** + * A webpack loader to transform markdown content to vue component + */ +export const vuepressMarkdownLoader: LoaderDefinitionFunction = + async function vuepressMarkdownLoader(source) { + // import esm dependencies + const [{ parsePageContent, renderPageSfcBlocksToVue }, { path }] = + await Promise.all([import('@vuepress/core'), import('@vuepress/utils')]) + + // get app instance from loader options + const { app } = this.getOptions() + + // get the matched page by file path + const page = app.pagesMap[this.resourcePath] + + // if the page content is not changed, render it to vue component directly + if (page?.content === source) { + return renderPageSfcBlocksToVue(page.sfcBlocks) + } + + // parse the markdown content to sfc blocks and render it to vue component + const { sfcBlocks } = parsePageContent({ + app, + content: source, + filePath: this.resourcePath, + filePathRelative: path.relative(app.dir.source(), this.resourcePath), + options: {}, + }) + return renderPageSfcBlocksToVue(sfcBlocks) + } diff --git a/packages/bundler-webpack/tsup.config.ts b/packages/bundler-webpack/tsup.config.ts index 4899bc89aa..9f8379c060 100644 --- a/packages/bundler-webpack/tsup.config.ts +++ b/packages/bundler-webpack/tsup.config.ts @@ -18,6 +18,7 @@ export default defineConfig([ { ...shared, entry: { + 'vuepress-markdown-loader': './src/loaders/vuepressMarkdownLoader.cts', 'vuepress-ssr-loader': './src/loaders/vuepressSsrLoader.cts', }, format: ['cjs'], diff --git a/packages/core/src/app/appInit.ts b/packages/core/src/app/appInit.ts index 1db287fd28..ac485cfe65 100644 --- a/packages/core/src/app/appInit.ts +++ b/packages/core/src/app/appInit.ts @@ -22,7 +22,9 @@ export const appInit = async (app: App): Promise => { app.markdown = await resolveAppMarkdown(app) // create pages - app.pages = await resolveAppPages(app) + const { pages, pagesMap } = await resolveAppPages(app) + app.pages = pages + app.pagesMap = pagesMap // plugin hook: onInitialized await app.pluginApi.hooks.onInitialized.process(app) diff --git a/packages/core/src/app/prepare/preparePageComponent.ts b/packages/core/src/app/prepare/preparePageComponent.ts index 569d63697a..e88d6123d5 100644 --- a/packages/core/src/app/prepare/preparePageComponent.ts +++ b/packages/core/src/app/prepare/preparePageComponent.ts @@ -2,14 +2,16 @@ import { renderPageSfcBlocksToVue } from '../../page/index.js' import type { App, Page } from '../../types/index.js' /** - * Generate page component temp file of a single page + * Generate page component temp file if the page does not have a source file */ export const preparePageComponent = async ( app: App, page: Page, ): Promise => { - await app.writeTemp( - page.componentFilePathRelative, - renderPageSfcBlocksToVue(page.sfcBlocks), - ) + if (page.filePath === null) { + await app.writeTemp( + page.componentFilePathRelative, + renderPageSfcBlocksToVue(page.sfcBlocks), + ) + } } diff --git a/packages/core/src/app/resolveAppPages.ts b/packages/core/src/app/resolveAppPages.ts index d8cd00bd41..33c280867b 100644 --- a/packages/core/src/app/resolveAppPages.ts +++ b/packages/core/src/app/resolveAppPages.ts @@ -7,7 +7,9 @@ const log = debug('vuepress:core/app') /** * Resolve pages for vuepress app */ -export const resolveAppPages = async (app: App): Promise => { +export const resolveAppPages = async ( + app: App, +): Promise> => { log('resolveAppPages start') // resolve page absolute file paths according to the page patterns @@ -19,9 +21,14 @@ export const resolveAppPages = async (app: App): Promise => { let hasNotFoundPage = false as boolean // create pages from files + const pagesMap: Record = {} const pages = await Promise.all( pageFilePaths.map(async (filePath) => { const page = await createPage(app, { filePath }) + // if there is a source file for the page, set it to the pages map + if (page.filePath) { + pagesMap[page.filePath] = page + } // if there is a 404 page, set the default layout to NotFound if (page.path === '/404.html') { page.frontmatter.layout ??= 'NotFound' @@ -44,5 +51,5 @@ export const resolveAppPages = async (app: App): Promise => { log('resolveAppPages finish') - return pages + return { pages, pagesMap } } diff --git a/packages/core/src/page/createPage.ts b/packages/core/src/page/createPage.ts index c000873c84..0c48399162 100644 --- a/packages/core/src/page/createPage.ts +++ b/packages/core/src/page/createPage.ts @@ -85,6 +85,8 @@ export const createPage = async ( const { componentFilePath, componentFilePathRelative } = resolvePageComponentInfo({ app, + filePath, + filePathRelative, htmlFilePathRelative, }) diff --git a/packages/core/src/page/resolvePageComponentInfo.ts b/packages/core/src/page/resolvePageComponentInfo.ts index b1ee312cc4..2105bdb187 100644 --- a/packages/core/src/page/resolvePageComponentInfo.ts +++ b/packages/core/src/page/resolvePageComponentInfo.ts @@ -6,15 +6,26 @@ import type { App } from '../types/index.js' */ export const resolvePageComponentInfo = ({ app, + filePath, + filePathRelative, htmlFilePathRelative, }: { app: App + filePath: string | null + filePathRelative: string | null htmlFilePathRelative: string }): { componentFilePath: string componentFilePathRelative: string } => { - // resolve component file path + // if there is a source file for the page, use it as the component file + if (filePath && filePathRelative) { + return { + componentFilePath: filePath, + componentFilePathRelative: filePathRelative, + } + } + // otherwise, generate a component file for the page const componentFilePathRelative = path.join( 'pages', `${htmlFilePathRelative}.vue`, diff --git a/packages/core/src/types/app/app.ts b/packages/core/src/types/app/app.ts index e943950ec9..3bab071811 100644 --- a/packages/core/src/types/app/app.ts +++ b/packages/core/src/types/app/app.ts @@ -79,6 +79,13 @@ export interface App { * Only available after initialization */ pages: Page[] + + /** + * Page source filepath map. + * + * Only available after initialization + */ + pagesMap: Record } /** diff --git a/packages/core/tests/app/resolveAppPages.spec.ts b/packages/core/tests/app/resolveAppPages.spec.ts index f394888238..a0366c1ab3 100644 --- a/packages/core/tests/app/resolveAppPages.spec.ts +++ b/packages/core/tests/app/resolveAppPages.spec.ts @@ -13,7 +13,7 @@ describe('core > app > resolveAppPages', () => { }) app.markdown = createMarkdown() - const pages = await resolveAppPages(app) + const { pages } = await resolveAppPages(app) const fooPage = pages.find((page) => page.path === '/foo.html') const barPage = pages.find((page) => page.path === '/bar.html') const notFoundPage = pages.find((page) => page.path === '/404.html') @@ -33,7 +33,7 @@ describe('core > app > resolveAppPages', () => { }) app.markdown = createMarkdown() - const pages = await resolveAppPages(app) + const { pages } = await resolveAppPages(app) const fooPage = pages.find((page) => page.path === '/foo.html') const barPage = pages.find((page) => page.path === '/bar.html') const notFoundPage = pages.find((page) => page.path === '/404.html') @@ -61,7 +61,7 @@ describe('core > app > resolveAppPages', () => { app.pluginApi.registerHooks() app.markdown = createMarkdown() - const pages = await resolveAppPages(app) + const { pages } = await resolveAppPages(app) pages.forEach((page) => { expect(page.frontmatter.foo).toBe('bar') @@ -84,7 +84,7 @@ describe('core > app > resolveAppPages', () => { app.pluginApi.registerHooks() app.markdown = createMarkdown() - const pages = await resolveAppPages(app) + const { pages } = await resolveAppPages(app) pages.forEach((page) => { expect(page.frontmatter.foo).toBe('baz') diff --git a/packages/core/tests/page/resolvePageComponentInfo.spec.ts b/packages/core/tests/page/resolvePageComponentInfo.spec.ts index 7feabdd495..c8a009e1ea 100644 --- a/packages/core/tests/page/resolvePageComponentInfo.spec.ts +++ b/packages/core/tests/page/resolvePageComponentInfo.spec.ts @@ -9,9 +9,11 @@ const app = createBaseApp({ bundler: {} as Bundler, }) -it('should resolve page component info correctly', () => { +it('should resolve page component info correctly without source file path', () => { const resolved = resolvePageComponentInfo({ app, + filePath: null, + filePathRelative: null, htmlFilePathRelative: 'foo.html', }) @@ -20,3 +22,17 @@ it('should resolve page component info correctly', () => { componentFilePathRelative: 'pages/foo.html.vue', }) }) + +it('should resolve page component info correctly with source file path', () => { + const resolved = resolvePageComponentInfo({ + app, + filePath: app.dir.source('foo.md'), + filePathRelative: 'foo.md', + htmlFilePathRelative: 'foo.html', + }) + + expect(resolved).toEqual({ + componentFilePath: app.dir.source('foo.md'), + componentFilePathRelative: 'foo.md', + }) +}) diff --git a/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts b/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts index 1434888055..2524963372 100644 --- a/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts +++ b/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts @@ -8,11 +8,6 @@ export interface AssetsPluginOptions { * Whether to prepend base to absolute path */ absolutePathPrependBase?: boolean - - /** - * Prefix to add to relative assets links - */ - relativePathPrefix?: string } /** @@ -20,10 +15,7 @@ export interface AssetsPluginOptions { */ export const assetsPlugin: PluginWithOptions = ( md, - { - absolutePathPrependBase = false, - relativePathPrefix = '@source', - }: AssetsPluginOptions = {}, + { absolutePathPrependBase = false }: AssetsPluginOptions = {}, ) => { // wrap raw image renderer rule const rawImageRule = md.renderer.rules.image! @@ -35,10 +27,7 @@ export const assetsPlugin: PluginWithOptions = ( if (link) { // replace the original link with resolved link - token.attrSet( - 'src', - resolveLink(link, { env, absolutePathPrependBase, relativePathPrefix }), - ) + token.attrSet('src', resolveLink(link, { env, absolutePathPrependBase })) } return rawImageRule(tokens, idx, options, env, self) @@ -57,7 +46,6 @@ export const assetsPlugin: PluginWithOptions = ( `${prefix}${quote}${resolveLink(src.trim(), { env, absolutePathPrependBase, - relativePathPrefix, strict: true, })}${quote}`, ) @@ -74,7 +62,6 @@ export const assetsPlugin: PluginWithOptions = ( `${resolveLink(url.trim(), { env, absolutePathPrependBase, - relativePathPrefix, strict: true, })}${descriptor.replace(/[ \n]+/g, ' ').trimEnd()}`, ), diff --git a/packages/markdown/src/plugins/assetsPlugin/resolveLink.ts b/packages/markdown/src/plugins/assetsPlugin/resolveLink.ts index b9277ed855..a1081fe9ed 100644 --- a/packages/markdown/src/plugins/assetsPlugin/resolveLink.ts +++ b/packages/markdown/src/plugins/assetsPlugin/resolveLink.ts @@ -5,18 +5,12 @@ import type { MarkdownEnv } from '../../types.js' interface ResolveLinkOptions { env: MarkdownEnv absolutePathPrependBase?: boolean - relativePathPrefix: string strict?: boolean } export const resolveLink = ( link: string, - { - env, - absolutePathPrependBase = false, - relativePathPrefix, - strict = false, - }: ResolveLinkOptions, + { env, absolutePathPrependBase = false }: ResolveLinkOptions, ): string => { // do not resolve data uri if (link.startsWith('data:')) return link @@ -24,22 +18,6 @@ export const resolveLink = ( // decode link to ensure bundler can find the file correctly let resolvedLink = decode(link) - // check if the link is relative path - const isRelativePath = strict - ? // in strict mode, only link that starts with `./` or `../` is considered as relative path - /^\.{1,2}\//.test(link) - : // in non-strict mode, link that does not start with `/` and does not have protocol is considered as relative path - !link.startsWith('/') && !/[A-z]+:\/\//.test(link) - - // if the link is relative path, and the `env.filePathRelative` exists - // add `@source` alias to the link - if (isRelativePath && env.filePathRelative) { - resolvedLink = `${relativePathPrefix}/${path.join( - path.dirname(env.filePathRelative), - resolvedLink, - )}` - } - // prepend base to absolute path if needed if (absolutePathPrependBase && env.base && link.startsWith('/')) { resolvedLink = path.join(env.base, resolvedLink) diff --git a/packages/markdown/tests/plugins/assetsPlugin.spec.ts b/packages/markdown/tests/plugins/assetsPlugin.spec.ts index af149f84d9..34dca2e41d 100644 --- a/packages/markdown/tests/plugins/assetsPlugin.spec.ts +++ b/packages/markdown/tests/plugins/assetsPlugin.spec.ts @@ -49,37 +49,36 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { md: MarkdownIt().use(assetsPlugin), env: { base: '/base/', - filePathRelative: 'sub/foo.md', }, expected: [ // relative paths - 'foo', - 'foo2', - 'foo-bar', - 'foo-bar2', - 'baz', - 'out', - '汉字', - '100%', + 'foo', + 'foo2', + 'foo-bar', + 'foo-bar2', + 'baz', + 'out', + '汉字', + '100%', // absolute paths 'absolute', 'absolute-foo', // no-prefix paths - 'no-prefix', - 'no-prefix-foo', - 'alias', - '汉字', - '100%', - '~alias', - '~汉字', - '~100%', + 'no-prefix', + 'no-prefix-foo', + 'alias', + '汉字', + '100%', + '~alias', + '~汉字', + '~100%', // keep as is 'url', 'empty', // invalid paths - 'invalid', - '汉字', - '100%', + 'invalid', + '汉字', + '100%', // data uri 'data-uri', ], @@ -91,87 +90,7 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { }), env: { base: '/base/', - filePathRelative: 'sub/foo.md', }, - expected: [ - // relative paths - 'foo', - 'foo2', - 'foo-bar', - 'foo-bar2', - 'baz', - 'out', - '汉字', - '100%', - // absolute paths - 'absolute', - 'absolute-foo', - // no-prefix paths - 'no-prefix', - 'no-prefix-foo', - 'alias', - '汉字', - '100%', - '~alias', - '~汉字', - '~100%', - // keep as is - 'url', - 'empty', - // invalid paths - 'invalid', - '汉字', - '100%', - // data uri - 'data-uri', - ], - }, - { - description: 'should respect `relativePathPrefix` option', - md: MarkdownIt().use(assetsPlugin, { - relativePathPrefix: '@foo', - }), - env: { - filePathRelative: 'sub/foo.md', - }, - expected: [ - // relative paths - 'foo', - 'foo2', - 'foo-bar', - 'foo-bar2', - 'baz', - 'out', - '汉字', - '100%', - // absolute paths - 'absolute', - 'absolute-foo', - // no-prefix paths - 'no-prefix', - 'no-prefix-foo', - 'alias', - '汉字', - '100%', - '~alias', - '~汉字', - '~100%', - // keep as is - 'url', - 'empty', - // invalid paths - 'invalid', - '汉字', - '100%', - // data uri - 'data-uri', - ], - }, - { - description: - 'should not handle relative paths if `env.filePathRelative` is not provided', - md: MarkdownIt().use(assetsPlugin), - env: {}, expected: [ // relative paths 'foo', @@ -183,8 +102,8 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { '汉字', '100%', // absolute paths - 'absolute', - 'absolute-foo', + 'absolute', + 'absolute-foo', // no-prefix paths 'no-prefix', 'no-prefix-foo', @@ -302,20 +221,20 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { description: 'should handle assets link with default options', md: MarkdownIt({ html: true }).use(assetsPlugin), env: { - filePathRelative: 'sub/foo.md', + base: '/base/', }, expected: [ /* src */ // relative paths - '', - '', - '', - '', - '', - '', - '', - '', - 'attrs', + '', + '', + '', + '', + '', + '', + '', + '', + 'attrs', // aliases '', '', @@ -344,34 +263,35 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { /* srcset */ // relative paths - '', - '', - 'attrs', + '', + '', + 'attrs', // aliases '', 'attrs', // webpack legacy aliases '', 'attrs', - // keep as is + // absolute paths and no-prefix paths '', + // keep as is '', 'attrs', // invalid paths '', 'attrs', // invalid srcset - '', + '', /* both */ // relative paths - '', - '', - 'attrs', + '', + '', + 'attrs', // aliases 'attrs', 'attrs', - // keep as is + // absolute paths and no-prefix paths 'attrs', /* data uri */ @@ -379,92 +299,13 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { ], }, { - description: 'should respect `relativePathPrefix` option', + description: 'should respect `absolutePathPrependBase` option', md: MarkdownIt({ html: true }).use(assetsPlugin, { - relativePathPrefix: '@foo', + absolutePathPrependBase: true, }), env: { - filePathRelative: 'sub/foo.md', + base: '/base/', }, - expected: [ - /* src */ - // relative paths - '', - '', - '', - '', - '', - '', - '', - '', - 'attrs', - // aliases - '', - '', - '', - 'attrs', - // webpack legacy aliases - '', - '', - '', - 'attrs', - // absolute paths - '', - '', - // no-prefix paths - '', - '', - 'attrs', - // keep as is - '', - '', - // invalid paths - '', - '', - '', - 'attrs', - - /* srcset */ - // relative paths - '', - '', - 'attrs', - // aliases - '', - 'attrs', - // webpack legacy aliases - '', - 'attrs', - // keep as is - '', - '', - 'attrs', - // invalid paths - '', - 'attrs', - // invalid srcset - '', - - /* both */ - // relative paths - '', - '', - 'attrs', - // aliases - 'attrs', - 'attrs', - // keep as is - 'attrs', - - /* data uri */ - '', - ], - }, - { - description: - 'should not handle relative paths if `env.filePathRelative` is not provided', - md: MarkdownIt({ html: true }).use(assetsPlugin), - env: {}, expected: [ /* src */ // relative paths @@ -488,8 +329,8 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { '', 'attrs', // absolute paths - '', - '', + '', + '', // no-prefix paths '', '', @@ -514,8 +355,9 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { // webpack legacy aliases '', 'attrs', + // absolute paths and no-prefix paths + '', // keep as is - '', '', 'attrs', // invalid paths @@ -532,8 +374,8 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { // aliases 'attrs', 'attrs', - // keep as is - 'attrs', + // absolute paths and no-prefix paths + 'attrs', /* data uri */ '', @@ -630,22 +472,25 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { `attrs`, + `attrs`, /* srcset */ ``, + 1024w ,../../out.png, /absolute/attrs.png">`, `attrs`, + ,default.png ,/absolute/attrs.png" width="100px">`, /** both */ ``, + 1024w ,../../out.png, /absolute/attrs.png">`, `attrs`, + ,default.png ,/absolute/attrs.png" width="100px">`, ] const TEST_CASES: { @@ -658,58 +503,42 @@ describe('@vuepress/markdown > plugins > assetsPlugin', () => { description: 'should handle assets link with default options', md: MarkdownIt({ html: true }).use(assetsPlugin), env: { - filePathRelative: 'sub/foo.md', + base: '/base/', }, expected: [ /* src */ '

attrs

', + '

attrs

', /* srcset */ - '

', - '

attrs

', + '

', + '

attrs

', /* both */ - '

', - '

attrs

', + '

', + '

attrs

', ], }, { - description: 'should respect `relativePathPrefix` option', + description: 'should respect `absolutePathPrependBase` option', md: MarkdownIt({ html: true }).use(assetsPlugin, { - relativePathPrefix: '@foo', + absolutePathPrependBase: true, }), env: { - filePathRelative: 'sub/foo.md', + base: '/base/', }, expected: [ /* src */ '

attrs

', + '

attrs

', /* srcset */ - '

', - '

attrs

', - - /* both */ - '

', - '

attrs

', - ], - }, - { - description: - 'should not handle assets link if `filePathRelative` is not provided', - md: MarkdownIt({ html: true }).use(assetsPlugin), - env: {}, - expected: [ - /* src */ - '

attrs

', - - /* srcset */ - '

', - '

attrs

', + '

', + '

attrs

', /* both */ - '

', - '

attrs

', + '

', + '

attrs

', ], }, ] From e681fb3f5a73e93c72fb62961eabe3044e3f0f58 Mon Sep 17 00:00:00 2001 From: meteorlxy Date: Wed, 11 Sep 2024 12:33:15 +0800 Subject: [PATCH 02/11] refactor: updates --- eslint.config.ts | 1 + .../src/plugins/vuepressMarkdownPlugin.ts | 25 +++--- .../src/loaders/vuepressMarkdownLoader.ts | 14 ++-- .../cli/src/commands/dev/handlePageAdd.ts | 11 +-- .../cli/src/commands/dev/handlePageChange.ts | 9 +-- .../cli/src/commands/dev/handlePageUnlink.ts | 1 + packages/client/src/components/Content.ts | 2 +- packages/client/src/setupGlobalComputed.ts | 11 ++- packages/client/src/types/routes.ts | 4 +- packages/core/src/app/appPrepare.ts | 7 +- packages/core/src/app/prepare/index.ts | 1 - .../core/src/app/prepare/preparePageChunk.ts | 32 +------- .../src/app/prepare/preparePageComponent.ts | 17 ---- packages/core/src/page/createPage.ts | 15 +--- packages/core/src/page/index.ts | 5 +- .../core/src/page/renderPageSfcBlocksToVue.ts | 17 ---- packages/core/src/page/renderPageToVue.ts | 79 +++++++++++++++++++ .../core/src/page/resolvePageChunkInfo.ts | 24 +++++- .../core/src/page/resolvePageComponentInfo.ts | 39 --------- ...geFileContent.ts => resolvePageContent.ts} | 18 +++-- packages/core/src/types/page.ts | 17 +--- ...ent.spec.ts => resolvePageContent.spec.ts} | 30 +++++-- 22 files changed, 181 insertions(+), 198 deletions(-) delete mode 100644 packages/core/src/app/prepare/preparePageComponent.ts delete mode 100644 packages/core/src/page/renderPageSfcBlocksToVue.ts create mode 100644 packages/core/src/page/renderPageToVue.ts delete mode 100644 packages/core/src/page/resolvePageComponentInfo.ts rename packages/core/src/page/{resolvePageFileContent.ts => resolvePageContent.ts} (51%) rename packages/core/tests/page/{resolvePageFileContent.spec.ts => resolvePageContent.spec.ts} (51%) diff --git a/eslint.config.ts b/eslint.config.ts index fa0eed31d7..1cb1edfb7b 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -19,6 +19,7 @@ export default vuepress( allow: [ '__dirname', '_context', + '_pageData', '_pageChunk', '_registeredComponents', ], diff --git a/packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts b/packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts index eb072f840c..94da9828c8 100644 --- a/packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts +++ b/packages/bundler-vite/src/plugins/vuepressMarkdownPlugin.ts @@ -1,6 +1,5 @@ import type { App } from '@vuepress/core' -import { parsePageContent, renderPageSfcBlocksToVue } from '@vuepress/core' -import { path } from '@vuepress/utils' +import { createPage, renderPageToVue } from '@vuepress/core' import type { Plugin } from 'vite' /** @@ -11,7 +10,7 @@ export const vuepressMarkdownPlugin = ({ app }: { app: App }): Plugin => ({ enforce: 'pre', - transform(code, id) { + async transform(code, id) { if (!id.endsWith('.md')) return // get the matched page by file path (id) @@ -19,18 +18,15 @@ export const vuepressMarkdownPlugin = ({ app }: { app: App }): Plugin => ({ // if the page content is not changed, render it to vue component directly if (page?.content === code) { - return renderPageSfcBlocksToVue(page.sfcBlocks) + return renderPageToVue(page) } - // parse the markdown content to sfc blocks and render it to vue component - const { sfcBlocks } = parsePageContent({ - app, + // create a new page with the new content + const newPage = await createPage(app, { content: code, filePath: id, - filePathRelative: path.relative(app.dir.source(), id), - options: {}, }) - return renderPageSfcBlocksToVue(sfcBlocks) + return renderPageToVue(newPage) }, async handleHotUpdate(ctx) { @@ -39,15 +35,12 @@ export const vuepressMarkdownPlugin = ({ app }: { app: App }): Plugin => ({ // read the source code const code = await ctx.read() - // parse the content to sfc blocks - const { sfcBlocks } = parsePageContent({ - app, + // create a new page with the new content + const newPage = await createPage(app, { content: code, filePath: ctx.file, - filePathRelative: path.relative(app.dir.source(), ctx.file), - options: {}, }) - ctx.read = () => renderPageSfcBlocksToVue(sfcBlocks) + ctx.read = () => renderPageToVue(newPage) }, }) diff --git a/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts b/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts index d9ca435d14..819dc29f66 100644 --- a/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts +++ b/packages/bundler-webpack/src/loaders/vuepressMarkdownLoader.ts @@ -11,8 +11,7 @@ export interface VuepressMarkdownLoaderOptions { export const vuepressMarkdownLoader: LoaderDefinitionFunction = async function vuepressMarkdownLoader(source) { // import esm dependencies - const [{ parsePageContent, renderPageSfcBlocksToVue }, { path }] = - await Promise.all([import('@vuepress/core'), import('@vuepress/utils')]) + const { createPage, renderPageToVue } = await import('@vuepress/core') // get app instance from loader options const { app } = this.getOptions() @@ -22,16 +21,13 @@ export const vuepressMarkdownLoader: LoaderDefinitionFunction - route.loader().then(({ comp }) => comp), + route.loader().then((m) => m.default), ) }) diff --git a/packages/client/src/setupGlobalComputed.ts b/packages/client/src/setupGlobalComputed.ts index e258cb7673..79c8fe459a 100644 --- a/packages/client/src/setupGlobalComputed.ts +++ b/packages/client/src/setupGlobalComputed.ts @@ -47,12 +47,15 @@ export const setupGlobalComputed = ( if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot)) { __VUE_HMR_RUNTIME__.updatePageData = async (newPageData: PageData) => { const oldPageChunk = await routes.value[newPageData.path].loader() - const newPageChunk = { comp: oldPageChunk.comp, data: newPageData } + const newPageChunk: PageChunk = { + default: oldPageChunk.default, + _pageData: newPageData, + } routes.value[newPageData.path].loader = async () => Promise.resolve(newPageChunk) if ( newPageData.path === - router.currentRoute.value.meta._pageChunk?.data.path + router.currentRoute.value.meta._pageChunk?._pageData.path ) { pageChunk.value = newPageChunk } @@ -67,8 +70,8 @@ export const setupGlobalComputed = ( const siteLocaleData = computed(() => resolvers.resolveSiteLocaleData(siteData.value, routeLocale.value), ) - const pageComponent = computed(() => pageChunk.value.comp) - const pageData = computed(() => pageChunk.value.data) + const pageComponent = computed(() => pageChunk.value.default) + const pageData = computed(() => pageChunk.value._pageData) const pageFrontmatter = computed(() => pageData.value.frontmatter) const pageHeadTitle = computed(() => resolvers.resolvePageHeadTitle(pageData.value, siteLocaleData.value), diff --git a/packages/client/src/types/routes.ts b/packages/client/src/types/routes.ts index 6aa5d10871..c102dee700 100644 --- a/packages/client/src/types/routes.ts +++ b/packages/client/src/types/routes.ts @@ -2,8 +2,8 @@ import type { Component } from 'vue' import type { PageData } from '../types/index.js' export interface PageChunk { - comp: Component - data: PageData + default: Component + _pageData: PageData } export type RouteMeta = Record diff --git a/packages/core/src/app/appPrepare.ts b/packages/core/src/app/appPrepare.ts index f8d2585f50..a41f8d72be 100644 --- a/packages/core/src/app/appPrepare.ts +++ b/packages/core/src/app/appPrepare.ts @@ -3,7 +3,6 @@ import type { App } from '../types/index.js' import { prepareClientConfigs, preparePageChunk, - preparePageComponent, prepareRoutes, prepareSiteData, } from './prepare/index.js' @@ -13,7 +12,6 @@ const log = debug('vuepress:core/app') /** * Prepare files for development or build * - * - page components * - page chunks * - routes * - site data @@ -23,10 +21,7 @@ export const appPrepare = async (app: App): Promise => { log('prepare start') await Promise.all([ - ...app.pages.flatMap((page) => [ - preparePageComponent(app, page), - preparePageChunk(app, page), - ]), + ...app.pages.map(async (page) => preparePageChunk(app, page)), prepareRoutes(app), prepareSiteData(app), prepareClientConfigs(app), diff --git a/packages/core/src/app/prepare/index.ts b/packages/core/src/app/prepare/index.ts index ea49aa7600..460f3b497f 100644 --- a/packages/core/src/app/prepare/index.ts +++ b/packages/core/src/app/prepare/index.ts @@ -1,5 +1,4 @@ export * from './prepareClientConfigs.js' export * from './preparePageChunk.js' -export * from './preparePageComponent.js' export * from './prepareRoutes.js' export * from './prepareSiteData.js' diff --git a/packages/core/src/app/prepare/preparePageChunk.ts b/packages/core/src/app/prepare/preparePageChunk.ts index 353a98eee1..2ade465418 100644 --- a/packages/core/src/app/prepare/preparePageChunk.ts +++ b/packages/core/src/app/prepare/preparePageChunk.ts @@ -1,35 +1,11 @@ +import { renderPageToVue } from '../../page/index.js' import type { App, Page } from '../../types/index.js' -const HMR_CODE = ` -if (import.meta.webpackHot) { - import.meta.webpackHot.accept() - if (__VUE_HMR_RUNTIME__.updatePageData) { - __VUE_HMR_RUNTIME__.updatePageData(data) - } -} - -if (import.meta.hot) { - import.meta.hot.accept(({ data }) => { - __VUE_HMR_RUNTIME__.updatePageData(data) - }) -} -` - /** - * Generate page chunk temp file of a single page + * Generate temp file the page does not have a source file */ export const preparePageChunk = async (app: App, page: Page): Promise => { - // page chunk file content - let content = `\ -import comp from ${JSON.stringify(page.componentFilePath)} -const data = JSON.parse(${JSON.stringify(JSON.stringify(page.data))}) -export { comp, data } -` - - // inject HMR code - if (app.env.isDev) { - content += HMR_CODE + if (page.filePath === null) { + await app.writeTemp(page.chunkFilePathRelative, renderPageToVue(page)) } - - await app.writeTemp(page.chunkFilePathRelative, content) } diff --git a/packages/core/src/app/prepare/preparePageComponent.ts b/packages/core/src/app/prepare/preparePageComponent.ts deleted file mode 100644 index e88d6123d5..0000000000 --- a/packages/core/src/app/prepare/preparePageComponent.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { renderPageSfcBlocksToVue } from '../../page/index.js' -import type { App, Page } from '../../types/index.js' - -/** - * Generate page component temp file if the page does not have a source file - */ -export const preparePageComponent = async ( - app: App, - page: Page, -): Promise => { - if (page.filePath === null) { - await app.writeTemp( - page.componentFilePathRelative, - renderPageSfcBlocksToVue(page.sfcBlocks), - ) - } -} diff --git a/packages/core/src/page/createPage.ts b/packages/core/src/page/createPage.ts index 0c48399162..9965abf4a4 100644 --- a/packages/core/src/page/createPage.ts +++ b/packages/core/src/page/createPage.ts @@ -2,9 +2,8 @@ import type { App, Page, PageOptions } from '../types/index.js' import { inferPagePath } from './inferPagePath.js' import { parsePageContent } from './parsePageContent.js' import { resolvePageChunkInfo } from './resolvePageChunkInfo.js' -import { resolvePageComponentInfo } from './resolvePageComponentInfo.js' +import { resolvePageContent } from './resolvePageContent.js' import { resolvePageDate } from './resolvePageDate.js' -import { resolvePageFileContent } from './resolvePageFileContent.js' import { resolvePageFilePath } from './resolvePageFilePath.js' import { resolvePageHtmlInfo } from './resolvePageHtmlInfo.js' import { resolvePageLang } from './resolvePageLang.js' @@ -27,7 +26,7 @@ export const createPage = async ( }) // read the raw file content according to the absolute file path - const content = await resolvePageFileContent({ filePath, options }) + const content = await resolvePageContent({ filePath, options }) // render page content and extract information const { @@ -81,18 +80,14 @@ export const createPage = async ( path, }) - // resolve page component and extract headers & links - const { componentFilePath, componentFilePathRelative } = - resolvePageComponentInfo({ + const { chunkFilePath, chunkFilePathRelative, chunkName } = + resolvePageChunkInfo({ app, filePath, filePathRelative, htmlFilePathRelative, }) - const { chunkFilePath, chunkFilePathRelative, chunkName } = - resolvePageChunkInfo({ app, htmlFilePathRelative }) - const page: Page = { // page data data: { @@ -127,8 +122,6 @@ export const createPage = async ( // file info filePath, filePathRelative, - componentFilePath, - componentFilePathRelative, chunkFilePath, chunkFilePathRelative, chunkName, diff --git a/packages/core/src/page/index.ts b/packages/core/src/page/index.ts index 6e1bc3d592..e6bc9edd07 100644 --- a/packages/core/src/page/index.ts +++ b/packages/core/src/page/index.ts @@ -1,11 +1,10 @@ export * from './createPage.js' export * from './inferPagePath.js' export * from './parsePageContent.js' -export * from './renderPageSfcBlocksToVue.js' +export * from './renderPageToVue.js' export * from './resolvePageChunkInfo.js' -export * from './resolvePageComponentInfo.js' export * from './resolvePageDate.js' -export * from './resolvePageFileContent.js' +export * from './resolvePageContent.js' export * from './resolvePageFilePath.js' export * from './resolvePageHtmlInfo.js' export * from './resolvePageLang.js' diff --git a/packages/core/src/page/renderPageSfcBlocksToVue.ts b/packages/core/src/page/renderPageSfcBlocksToVue.ts deleted file mode 100644 index 7428643823..0000000000 --- a/packages/core/src/page/renderPageSfcBlocksToVue.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { MarkdownSfcBlocks } from '@vuepress/markdown' - -/** - * Render page sfc blocks to vue component - */ -export const renderPageSfcBlocksToVue = ( - sfcBlocks: MarkdownSfcBlocks, -): string => - [ - // #688: wrap the content of `