feat: update head tags during dev

pull/1/head
Evan You 4 years ago
parent 2dd1a15d56
commit bdbbdd556f

@ -0,0 +1,51 @@
import { watchEffect } from 'vue'
import { useSiteData } from './siteData'
/**
* @param {import('./pageData').PageDataRef} pageData
*/
export function useUpdateHead(pageData) {
const siteData = useSiteData()
/**
* @type {HTMLElement[]}
*/
const siteHeadTags = []
/**
* @type {HTMLElement[]}
*/
const pageHeadTags = []
/**
* @param {HTMLElement[]} tags
* @param {import('src').HeadConfig[]} newTags
*/
const updateHeadTags = (tags, newTags) => {
tags.forEach((el) => document.head.removeChild(el))
tags.length = 0
if (newTags && newTags.length) {
newTags.forEach(([tag, attrs, innerHTML]) => {
const el = document.createElement(tag)
for (const key in attrs) {
el.setAttribute(key, attrs[key])
}
if (innerHTML) {
el.innerHTML = innerHTML
}
document.head.appendChild(el)
tags.push(el)
})
}
}
watchEffect(() => {
updateHeadTags(siteHeadTags, siteData.value.head)
})
watchEffect(() => {
updateHeadTags(
pageHeadTags,
pageData.value && pageData.value.frontmatter.head
)
})
}

@ -1,11 +1,7 @@
import { inject } from 'vue'
/**
* @typedef {{
* a: 1
* }} PageData
*
* @typedef {import('vue').Ref<PageData>} PageDataRef
* @typedef {import('vue').Ref<import('src').PageData>} PageDataRef
*/
/**

@ -4,10 +4,13 @@ import { ref, readonly } from 'vue'
/**
* @param {string} data
* @returns {any}
*/
const parse = (data) => readonly(JSON.parse(data))
// site data
/**
* @type {import('vue').Ref<import('src').SiteData>}
*/
const siteDataRef = ref(parse(serialized))
export function useSiteData() {

@ -6,6 +6,7 @@ import {
} from 'vue'
import { Content } from './components/Content'
import { createRouter, RouterSymbol } from './router'
import { useUpdateHead } from './composables/head'
import { useSiteData } from './composables/siteData'
import { usePageData, pageDataSymbol } from './composables/pageData'
import Theme from '/@theme/index'
@ -18,8 +19,12 @@ const NotFound = Theme.NotFound || (() => '404 Not Found')
export function createApp() {
const pageDataRef = ref()
// hot reload pageData
if (__DEV__ && inBrowser) {
// dynamically update head tags during dev since it's an SPA
// this is not needed in production.
useUpdateHead(pageDataRef)
// hot reload pageData
hot.on('vitepress:pageData', (data) => {
if (
data.path.replace(/\.md$/, '') ===

@ -10,7 +10,8 @@
"paths": {
"/@app/*": ["app/*"],
"/@theme/*": ["theme-default/*"],
"vitepress": ["app/exports.js"]
"vitepress": ["app/exports.js"],
"src": ["../dist/index.d.ts"]
}
},
"include": ["."]

@ -4,6 +4,7 @@ import globby from 'globby'
import { promises as fs } from 'fs'
import { createResolver, APP_PATH } from './utils/pathResolver'
import { Resolver } from 'vite'
import { Header } from './markdown/plugins/header'
const debug = require('debug')('vitepress:config')
@ -20,14 +21,6 @@ export interface UserConfig<ThemeConfig = any> {
// TODO locales support etc.
}
export interface SiteData<ThemeConfig = any> {
title: string
description: string
base: string
head: HeadConfig[]
themeConfig: ThemeConfig
}
export interface SiteConfig<ThemeConfig = any> {
root: string
site: SiteData<ThemeConfig>
@ -39,6 +32,21 @@ export interface SiteConfig<ThemeConfig = any> {
pages: string[]
}
export interface SiteData<ThemeConfig = any> {
title: string
description: string
base: string
head: HeadConfig[]
themeConfig: ThemeConfig
}
export interface PageData {
title: string
frontmatter: Record<string, any>
headers: Header[]
lastUpdated: number
}
const resolve = (root: string, file: string) =>
path.join(root, `.vitepress`, file)

@ -1,2 +1,3 @@
export * from './server'
export * from './build/build'
export * from './config'

@ -2,8 +2,8 @@ import path from 'path'
import matter from 'gray-matter'
import LRUCache from 'lru-cache'
import { createMarkdownRenderer, MarkdownOpitons } from './markdown/markdown'
import { Header } from './markdown/plugins/header'
import { deeplyParseHeader } from './utils/parseHeader'
import { PageData } from './config'
const debug = require('debug')('vitepress:md')
const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
@ -13,13 +13,6 @@ interface MarkdownCompileResult {
pageData: PageData
}
export interface PageData {
title: string
frontmatter: Record<string, any>
headers: Header[]
lastUpdated: number
}
export function createMarkdownToVueRenderFn(
root: string,
options: MarkdownOpitons = {}
@ -53,8 +46,10 @@ export function createMarkdownToVueRenderFn(
pageData
)
// double wrapping since tempalte root node is never hoisted or turned into
// a static node.
const vueSrc =
`<template><div class="vitepress-content">${html}</div></template>\n` +
`<template><div><div class="vitepress-content">${html}</div></div></template>\n` +
additionalBlocks.join('\n')
debug(`[render] ${file} in ${Date.now() - start}ms.`)

Loading…
Cancel
Save