Skip to content

Commit

Permalink
feat: setting up hookable
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Apr 16, 2024
1 parent e3a3992 commit 458023d
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 71 deletions.
43 changes: 43 additions & 0 deletions packages/slidev/node/slidev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { MarkdownTransformContext, ResolvedSlidevOptions, SlidevPluginOptions, SlidevServerOptions } from '@slidev/types'
import { createHooks } from 'hookable'
import type MarkdownIt from 'markdown-it'
import type { ViteDevServer } from 'vite'

export interface SlidevServerHooks {
/**
* Hook for the Vite server created
*/
'server:created': (server: ViteDevServer) => void
/**
* Hook for the Vite config resolved
*/
'vite:configResolved': (config: any) => void
/**
* Setting up the markdown-it instance
*/
'markdown:setup': (md: MarkdownIt) => Promise<void> | void
/**
* Transforming markdown content before any Slidev transformations
* You may manipulate MagicString instance
* The hook has to be sync
*/
'markdown:transform:pre': (context: MarkdownTransformContext, id: string) => void
/**
* Transforming markdown content after Slidev transformations
* You may manipulate MagicString instance
* The hook has to be sync
*/
'markdown:transform:post': (context: MarkdownTransformContext, id: string) => void
}

export class SlidevServerApp {
public readonly hooks = createHooks<SlidevServerHooks>()
public viteServer?: ViteDevServer

constructor(
public options: ResolvedSlidevOptions,
public pluginOptions: SlidevPluginOptions,
public serverOptions?: SlidevServerOptions,
) {
}
}
9 changes: 8 additions & 1 deletion packages/slidev/node/vite/extendConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { ResolvedSlidevOptions } from '@slidev/types'
import { getIndexHtml } from '../commands/shared'
import { resolveImportPath, toAtFS } from '../resolver'
import { dependencies } from '../../../client/package.json'
import type { SlidevServerApp } from '../slidev'

const INCLUDE = [
...Object.keys(dependencies),
Expand Down Expand Up @@ -51,7 +52,8 @@ const ASYNC_MODULES = [
'@vue',
]

export function createConfigPlugin(options: ResolvedSlidevOptions): Plugin {
export function createConfigPlugin(app: SlidevServerApp): Plugin {
const { options } = app
return {
name: 'slidev:config',
async config(config) {
Expand Down Expand Up @@ -165,7 +167,12 @@ export function createConfigPlugin(options: ResolvedSlidevOptions): Plugin {

return mergeConfig(injection, config)
},
configResolved(resolved) {
app.hooks.callHook('vite:configResolved', resolved)
},
configureServer(server) {
app.viteServer = server
app.hooks.callHook('server:created', server)
// serve our index.html after vite history fallback
return () => {
server.middlewares.use(async (req, res, next) => {
Expand Down
20 changes: 9 additions & 11 deletions packages/slidev/node/vite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import IconsResolver from 'unplugin-icons/resolver'
import Components from 'unplugin-vue-components/vite'
import ServerRef from 'vite-plugin-vue-server-ref'
import { notNullish } from '@antfu/utils'
import type { ResolvedSlidevOptions, SlidevPluginOptions, SlidevServerOptions } from '@slidev/types'
import { loadDrawings, writeDrawings } from '../integrations/drawings'
import type { SlidevServerApp } from '../slidev'
import { createConfigPlugin } from './extendConfig'
import { createSlidesLoader } from './loaders'

Expand All @@ -18,11 +18,9 @@ import { createVueCompilerFlagsPlugin } from './compilerFlagsVue'
import { createMonacoTypesLoader } from './monacoTypes'
import { createVuePlugin } from './vue'

export async function ViteSlidevPlugin(
options: ResolvedSlidevOptions,
pluginOptions: SlidevPluginOptions,
serverOptions: SlidevServerOptions = {},
): Promise<Plugin[]> {
export async function ViteSlidevPlugin(app: SlidevServerApp): Promise<Plugin[]> {
const { options, pluginOptions } = app

const {
components: componentsOptions = {},
icons: iconsOptions = {},
Expand All @@ -43,10 +41,9 @@ export async function ViteSlidevPlugin(
const publicRoots = [...themeRoots, ...addonRoots].map(i => join(i, 'public')).filter(existsSync)

const plugins = [
createMarkdownPlugin(options, pluginOptions),

createVuePlugin(options, pluginOptions),
createSlidesLoader(options, pluginOptions, serverOptions),
createMarkdownPlugin(app),
createVuePlugin(app),
createSlidesLoader(app),

Components({
extensions: ['vue', 'md', 'js', 'ts', 'jsx', 'tsx'],
Expand Down Expand Up @@ -115,7 +112,7 @@ export async function ViteSlidevPlugin(
},
}),

createConfigPlugin(options),
createConfigPlugin(app),
createMonacoTypesLoader(options),
createVueCompilerFlagsPlugin(options),

Expand All @@ -128,6 +125,7 @@ export async function ViteSlidevPlugin(
})),
}))
: null,

options.inspect
? import('vite-plugin-inspect').then(r => (r.default || r)({
dev: true,
Expand Down
13 changes: 5 additions & 8 deletions packages/slidev/node/vite/loaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { VIRTUAL_SLIDE_PREFIX, templateSlides } from '../virtual/slides'
import { templateConfigs } from '../virtual/configs'
import { templateMonacoRunDeps } from '../virtual/monaco-deps'
import { templateMonacoTypes } from '../virtual/monaco-types'
import type { SlidevServerApp } from '../slidev'

const regexId = /^\/\@slidev\/slide\/(\d+)\.(md|json)(?:\?import)?$/
const regexIdQuery = /(\d+?)\.(md|json|frontmatter)$/
Expand Down Expand Up @@ -93,11 +94,7 @@ function withRenderedNote(data: SlideInfo): SlideInfo {
}
}

export function createSlidesLoader(
options: ResolvedSlidevOptions,
pluginOptions: SlidevPluginOptions,
serverOptions: SlidevServerOptions,
): Plugin[] {
export function createSlidesLoader(app: SlidevServerApp): Plugin[] {
const hmrPages = new Set<number>()
let server: ViteDevServer | undefined

Expand All @@ -106,7 +103,7 @@ export function createSlidesLoader(

let skipHmr: { filePath: string, fileContent: string } | null = null

const { data, clientRoot, roots, mode } = options
const { data, clientRoot, roots, mode } = app.options

const templateCtx: VirtualModuleTempalteContext = {
md,
Expand Down Expand Up @@ -203,7 +200,7 @@ export function createSlidesLoader(

await ctx.read()

const newData = await serverOptions.loadData?.()
const newData = await app.serverOptions?.loadData?.()
if (!newData)
return []

Expand Down Expand Up @@ -311,7 +308,7 @@ export function createSlidesLoader(
const template = templates.find(i => i.id === id)
if (template) {
return {
code: await template.getContent(options, templateCtx, this),
code: await template.getContent(app.options, templateCtx, this),
map: { mappings: '' },
}
}
Expand Down
18 changes: 11 additions & 7 deletions packages/slidev/node/vite/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ import { loadShikiSetups } from '../setups/shiki'
import { loadSetups } from '../setups/load'
import { transformCodeWrapper, transformKaTexWrapper, transformMagicMove, transformMermaid, transformMonaco, transformPageCSS, transformPlantUml, transformSlotSugar, transformSnippet } from '../syntax/transform'
import { escapeVueInCode } from '../syntax/transform/utils'
import type { SlidevServerApp } from '../slidev'

let shiki: Highlighter | undefined
let shikiOptions: MarkdownItShikiOptions | undefined

export async function createMarkdownPlugin(
options: ResolvedSlidevOptions,
{ markdown: mdOptions }: SlidevPluginOptions,
): Promise<Plugin> {
export async function createMarkdownPlugin(app: SlidevServerApp): Promise<Plugin> {
const { options, pluginOptions: { markdown: mdOptions } } = app
const { data: { config }, roots, mode, entry, clientRoot } = options

const setups: ((md: MarkdownIt) => void)[] = []
Expand Down Expand Up @@ -95,7 +94,6 @@ export async function createMarkdownPlugin(
setups.push(md => md.use(MarkdownItMdc))

const KatexOptions: KatexOptions = await loadSetups(options.clientRoot, roots, 'katex.ts', {}, { strict: false }, false)

const sourceMapConsumers: Record<string, SourceMapConsumer> = {}

return Markdown({
Expand All @@ -112,7 +110,7 @@ export async function createMarkdownPlugin(
...mdOptions?.markdownItOptions,
},
...mdOptions,
markdownItSetup(md) {
async markdownItSetup(md) {
md.use(MarkdownItAttrs, {
attrs: {
target: '_blank',
Expand All @@ -126,7 +124,9 @@ export async function createMarkdownPlugin(
md.use(MarkdownItVDrag, sourceMapConsumers)

setups.forEach(i => i(md))
mdOptions?.markdownItSetup?.(md)

await mdOptions?.markdownItSetup?.(md)
await app.hooks.callHook('markdown:setup', md)
},
transforms: {
before(code, id) {
Expand All @@ -143,6 +143,8 @@ export async function createMarkdownPlugin(
},
}

app.hooks.callHook('markdown:transform:pre', ctx, id)

transformSnippet(ctx, options, id)

if (config.highlighter === 'shiki')
Expand All @@ -157,6 +159,8 @@ export async function createMarkdownPlugin(
transformPageCSS(ctx, id)
transformSlotSugar(ctx)

app.hooks.callHook('markdown:transform:post', ctx, id)

const sourceMap = ctx.s.generateMap()
sourceMapConsumers[id] = new SourceMapConsumer({
...sourceMap,
Expand Down
9 changes: 3 additions & 6 deletions packages/slidev/node/vite/vue.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Plugin } from 'vite'
import Vue from '@vitejs/plugin-vue'
import VueJsx from '@vitejs/plugin-vue-jsx'
import type { ResolvedSlidevOptions, SlidevPluginOptions } from '@slidev/types'
import type { SlidevServerApp } from '../slidev'

const customElements = new Set([
// katex
Expand Down Expand Up @@ -34,14 +34,11 @@ const customElements = new Set([
'semantics',
])

export async function createVuePlugin(
options: ResolvedSlidevOptions,
pluginOptions: SlidevPluginOptions,
): Promise<Plugin[]> {
export async function createVuePlugin(app: SlidevServerApp): Promise<Plugin[]> {
const {
vue: vueOptions = {},
vuejsx: vuejsxOptions = {},
} = pluginOptions
} = app.pluginOptions

const VuePlugin = Vue({
include: [/\.vue$/, /\.vue\?vue/, /\.vue\?v=/, /\.md$/, /\.md\?vue/],
Expand Down
1 change: 1 addition & 0 deletions packages/slidev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"fs-extra": "^11.2.0",
"get-port-please": "^3.1.2",
"global-directory": "^4.0.1",
"hookable": "^5.5.3",
"htmlparser2": "^9.1.0",
"is-installed-globally": "^1.0.0",
"jiti": "^1.21.0",
Expand Down

0 comments on commit 458023d

Please sign in to comment.