mirror of https://github.com/vuejs/vitepress
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.1 KiB
105 lines
3.1 KiB
import { resolveConfig } from 'node/config'
|
|
import { PageArtifactStore } from 'node/pageArtifacts'
|
|
import { createVitePressPlugin } from 'node/plugin'
|
|
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import path from 'node:path'
|
|
import type { Plugin } from 'vite'
|
|
|
|
describe('resolved plugin artifact safety', () => {
|
|
let root: string | undefined
|
|
|
|
afterEach(async () => {
|
|
if (root) {
|
|
await rm(root, { recursive: true, force: true })
|
|
root = undefined
|
|
}
|
|
})
|
|
|
|
test('uses resolved-config plugins when deciding whether an artifact is reusable', async () => {
|
|
root = await mkdtemp(path.join(tmpdir(), 'vitepress-resolved-plugins-'))
|
|
const file = path.join(root, 'index.md')
|
|
const source = '# Resolved plugin safety\n'
|
|
await writeFile(file, source)
|
|
|
|
const siteConfig = await resolveConfig(root, 'build', 'production')
|
|
siteConfig.markdown = { cache: false }
|
|
siteConfig.vite = { plugins: [] }
|
|
|
|
const compileWithResolvedPlugin = async (
|
|
resolvedPlugin: Plugin,
|
|
namespace: string
|
|
) => {
|
|
const store = new PageArtifactStore(siteConfig.cacheDir, { namespace })
|
|
const plugins = await createVitePressPlugin(
|
|
siteConfig,
|
|
false,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
{
|
|
coordinatorClient: true,
|
|
pageArtifactStore: store,
|
|
skipGitScan: true
|
|
}
|
|
)
|
|
const vitePressPlugin = plugins[0] as Plugin
|
|
const configResolved = getHookHandler(vitePressPlugin.configResolved)
|
|
await configResolved.call(undefined, {
|
|
base: '/',
|
|
build: { rolldownOptions: { plugins: [] } },
|
|
command: 'build',
|
|
plugins: [vitePressPlugin, resolvedPlugin],
|
|
publicDir: siteConfig.publicDir
|
|
} as any)
|
|
|
|
const transform = getHookHandler(vitePressPlugin.transform as any)
|
|
await transform.call(
|
|
{
|
|
addWatchFile() {},
|
|
environment: { mode: 'build', name: 'client' }
|
|
},
|
|
source,
|
|
file
|
|
)
|
|
return store.getCurrentMetadata('index.md')
|
|
}
|
|
|
|
const resolvedConfigFilePlugin: Plugin = {
|
|
name: 'test:resolved-config-file-load',
|
|
load: {
|
|
filter: { id: /[.]md$/ },
|
|
handler() {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
expect(siteConfig.vite.plugins).not.toContain(resolvedConfigFilePlugin)
|
|
await expect(
|
|
compileWithResolvedPlugin(resolvedConfigFilePlugin, 'resolved-unsafe')
|
|
).resolves.toEqual({
|
|
staticPage: false,
|
|
requiresSourceModuleIdentity: true
|
|
})
|
|
|
|
const explicitlySafePlugin = {
|
|
...resolvedConfigFilePlugin,
|
|
api: { vitepress: { ssrArtifactSafe: true } }
|
|
} as Plugin
|
|
await expect(
|
|
compileWithResolvedPlugin(explicitlySafePlugin, 'resolved-safe')
|
|
).resolves.toEqual({
|
|
staticPage: true,
|
|
requiresSourceModuleIdentity: false
|
|
})
|
|
})
|
|
})
|
|
|
|
function getHookHandler<T extends (...args: any[]) => any>(
|
|
hook: T | { handler: T } | undefined
|
|
): T {
|
|
if (!hook) throw new Error('Expected plugin hook.')
|
|
return typeof hook === 'function' ? hook : hook.handler
|
|
}
|