Skip to content

vitepress

几种引入代码的方式

1 导入代码片段(推荐)

markdown
<<< ./index.js#snippet
js
// #region snippet
export function foo (value) {
  ...
}
// #endregion snippet

2 引入整个文件

js
// 导入markdown,整合markdown很有用
`<!--@include: ./***.md-->`
// 导入markdown,局部内容
`<!--@include: ./parts/basics.md{3,10}-->`
// 导入代码片段不适用
`<!--@include: ./***.js-->`

3 使用vue引入(暂不推荐)

js
// index.js
export function foo (value) {
  ...
}
markdown
<!-- markdown -->
<script setup>
import {foo} from "./index.js"
</script>
<!-- 不是代码片段 -->
<pre><code class="language-javascript">{{ foo.toString() }}</code></pre>
<!-- 代码不高亮 -->
\`\`\`bash-vue
{{ foo }}
\`\`\`

参考:导入代码片段

动态引入

vite markdown configImport code snippets as dynamic path #3334MarkdownOptions 场景:

  • 动态加载.md文件 解决思路:
  • 1、对<!--@include: (.*?)-->进行重写覆盖
js
// vite.config.js
import { defineConfig } from 'vite';
import fs from 'fs';
import path from 'path';

export default defineConfig({
  plugins: [
    {
      name: 'vite-plugin-md-include',
      transform(src, id) {
        if (id.endsWith('.md')) {
          return src.replace(/<!--@include: (.*?)-->/g, (match, p1) => {
            const filePath = path.resolve(path.dirname(id), p1.trim());
            if (fs.existsSync(filePath)) {
              return fs.readFileSync(filePath, 'utf-8');
            } else {
              console.warn(`File not found: ${filePath}`);
              return ''; // 如果文件不存在,返回空字符串
            }
          });
        }
      }
    }
  ]
});
  • 2、动态加载数据,markdown-it解析,vue渲染
  • github markdown
markdown
<!-- 动态加载 github markdown 数据 -->
<script setup>
import { ref, onMounted } from 'vue';
import markdownit from 'markdown-it'
const md = markdownit()
const markdownContent = ref('');
onMounted(async () => {
  try {
    const response = await fetch('https://raw.githubusercontent.com/nzakas/understandinges6/master/manuscript/00-Introduction.md');
    if (response.ok) {
      const value = await response.text();
      markdownContent.value = md.render(value);
    } else {
      console.error('Failed to fetch markdown file');
    }
  } catch (error) {
    console.error('Error fetching markdown file:', error);
  }
});
</script>
<div v-html="markdownContent"></div>
  • 本地 markdown
js
// index.data.js
// 动态加载 本地 markdown 数据
import fs from 'node:fs'
import markdownit from 'markdown-it'
const md = markdownit()
// 在这里可以给 markdownit 添加代码高亮
export default {
  watch: ['./md/*.md'],
  load(watchedFiles) {
    return watchedFiles.sort((pre,next)=>{
      return pre.match(/(\d+)、/)[1] - next.match(/(\d+)、/)[1]
    }).map((file) => {
      return  md.render(fs.readFileSync(file, 'utf-8'))
    })
  }
}
markdown
<!--
1、解析出来的markdown 文档与vitepress基本一致
2、代码片段没有高亮 :可以尝试添加高亮组件
-->
<script setup>
  import { data } from './index.data.js'
</script>

<div v-for="item in data" v-html="item"></div>
  • 3、动态加载数据,marked解析,vue渲染
js
import fs from 'node:fs'
export default {
  watch: ['./md/*.md'],
  load(watchedFiles) {
    return watchedFiles.sort((pre,next)=>{
      return pre.match(/(\d+)、/)[1] - next.match(/(\d+)、/)[1]
    }).map((file) => {
      return  fs.readFileSync(file, 'utf-8')
    })
  }
}
markdown
<!-- 
1、marked 解析出来的markdown文档 与vitepress不一致,蓝色文字,theme需要调整
2、增加代码高亮,代码可以高亮,拷贝插件无法显示
3、改在md中解析md,CopyButtonPlugin在nodejs报错,找不到document
 -->
<script setup>
  import { data } from './dp.data.js'
  import hljs from 'highlight.js';
  import { Marked } from "marked";
  import { markedHighlight } from "marked-highlight";
  import CopyButtonPlugin from "highlightjs-copy"
  import javascript from 'highlight.js/lib/languages/javascript';
  import hljsVuePlugin from "@highlightjs/vue-plugin";
  const copyPlugin = new CopyButtonPlugin({
    hook: (text, el) => {
      if (el.dataset.copyright) {
        return `${text}\n\n${el.dataset.copyright}`;
      }
      if (el.dataset.highlight) {
        el.style.filter = "saturate(5)";
      }
      if (el.dataset.replace) {
        return text
          .replace("{{name}}", "Alexander Graham Bell")
          .replace("{{dog}}", "Platypus");
      }
      return text;
    },
  })
  hljs.addPlugin(copyPlugin);
  hljs.highlightAll()
  const highlightjs = hljsVuePlugin.component

  const marked = new Marked(
    markedHighlight({
      emptyLangClass: 'hljs',
      langPrefix: 'hljs language-',
      highlight(code, lang, info) {
        const language = hljs.getLanguage(lang) ? lang : 'plaintext';
        const val = hljs.highlight(code, { language }).value;
        return val
      }
    })
  );

  const dataHtml = data.map(item=> marked.parse(item))
</script>
<span>1 highlightjs</span>
<highlightjs language="js" code="console.log('Hello World');"></highlightjs>
<span>2 code class="hljs language-js"</span>
<pre><code class="hljs language-js">console.log('Hello world!');</code></pre>
<span>3 code class="hljs language-javascript"</span>
<pre><code class="hljs language-javascript">console.log('Hello world!');</code></pre>

<div v-for="val in dataHtml">
  <code class="hljs-html" v-html="val"></code>
</div>
  • 4、动态生成文件名称
js
export default {
  // 相对路径
  // watch: ['../../../../../front-end/DesignPatterns/md/*.md'],
  // 根目录路径
  // watch: ['docs/front-end/javaScript/ES6/md/*.md'],
  watch: ['docs/front-end/DesignPatterns/md/*.md'],
  // watch: ['docs/back-end/Lang/NodeJs/Book/note/**/*.md'],
  load(watchedFiles) {
    const files = watchedFiles.sort((pre,next)=>{
      const preNum = pre.match(/(\d+)[、-]?/)
      const nextNum = next.match(/(\d+)[、-]?/)
      if(preNum === null || nextNum===null)return 0
      return preNum[1] - nextNum[1]
    })
    // .map(item => {
    // // 相对路径 => ./md/${文件名}
    //   const path = item.match(/\/([^\/]+)$/)[1]
    //   return  `<!--@include: ./md/${path}-->`.replaceAll(/\\/g,'/')
    // })
    .map(item => {
    // 根路径 => ./md/${文件名}
      const path = item.replace("docs","@")
      return  `<!--@include: ${path}-->`.replaceAll(/\\/g,'/')
    })
    return files
  },
}

alias 路径别名

  • alias
    • /.vitepress/config.mts 中配置alias只对前端部分的开发、打包有效
      js
      import { defineConfig } from 'vitepress'
      import {fileURLToPath} from 'node:url'
      // import { resolve } from 'node:path';
      export default defineConfig({
        vite: {
          resolve: {
            alias: [
              // new URL('../../docs', import.meta.url) 使用import.meta.url了,所有路径是相对于当前这个文件的
              { find: '@', replacement: fileURLToPath(new URL('../../docs', import.meta.url).href)},
            ]
            // 或者
            // alias:{
              // '@': resolve(__dirname, '../../docs'),
            // }
          },
        },
      })
  • 在 tsconfig.json paths 配置 "@/*": ["./docs/*"]
  • vitepress dev docs 启动以后
    • *.data.js是属于nodejs服务端,使用alias, 无效
    • 在 package.json 中 "dev": "vitepress dev docs",./docs目录下就是根目录
    • *.data.js中引用其他模块,可采用绝对路径,tsconfig.json paths配置 "/*": ["./docs/*"]配合绝对路径
    • *.data.jsimport name from '/utils/**.mts',/utils就是docs根目录下文件夹

vite press 增加标签

vitepress 插件