使用MDSvex在Svelte 4中渲染Git仓库Markdown代码块异常
问题:Svelte 4 + mdsvex 代码块渲染异常
在Svelte 4博客应用中,使用mdsvex渲染从Git仓库拉取的Markdown文章时,大部分内容显示正常,但```格式的代码块出现异常,被包裹在{@html }`文本中,无法还原Obsidian编写的原始代码块样式。
相关代码文件
package.json
{ "name": "planet-oxy", "version": "0.0.1", "private": true, "scripts": { "dev": "vite dev --port 8008", "launch": "vite dev --port 8008 --open", "build": "vite build", "preview": "vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "eslint .", "init:houdini": "npx houdini@latest init", "generate:houdini": "npx houdini generate", "pull:houdini": "npx houdini pull-schema" }, "devDependencies": { "@sveltejs/adapter-auto": "^3.3.1", "@sveltejs/adapter-netlify": "^4.3.1", "@sveltejs/kit": "^2.5.27", "@sveltejs/vite-plugin-svelte": "^4.0.0", "@types/eslint": "^8.56.7", "autoprefixer": "^10.4.19", "eslint": "^9.0.0", "eslint-plugin-svelte": "^2.45.1", "globals": "^15.0.0", "houdini": "^1.5.4", "houdini-svelte": "^2.1.8", "mdsvex": "^0.12.6", "prettier": "^3.6.2", "prettier-plugin-svelte": "^3.4.0", "prettier-plugin-tailwindcss": "^0.6.14", "svelte": "^5.0.0", "svelte-check": "^4.0.0", "tailwindcss": "^4.0.6", "tslib": "^2.4.1", "typescript": "^5.5.0", "typescript-eslint": "^8.0.0-alpha.20", "vite": "^5.4.4" }, "type": "module", "dependencies": { "@sanity/client": "^6.22.4", "@tailwindcss/vite": "^4.0.6" } }
svelte.config.js
import { mdsvex } from 'mdsvex'; import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const msdsvexOpt = { extensions: ['.md'] } /** @type {import('@sveltejs/kit').Config} */ const config = { extensions: ['.svelte', '.svx','.md'], preprocess: [vitePreprocess(), mdsvex(msdsvexOpt)], kit: { adapter: adapter({ edge: false, split: false }), alias: { $houdini: ".houdini/" } }, }; export default config;
+page.ts
import { PUBLIC_BLOG_URL } from '$env/static/public'; import type { TPostMeta } from '$lib/types/post/TPost.type.js'; import { error } from '@sveltejs/kit'; import { compile } from 'mdsvex'; export async function load({ params }) { try { const url = `${PUBLIC_BLOG_URL}/refs/heads/master/${params.article}.md` const res = await fetch(url); const post = await res.text(); const response = await compile(post, { extensions: ['.md'], filename: `${params.article}.md` }) if (!response) { throw new Error(`Could not fetch ${params.article}`); } const content = response.code const meta = (response.data as any).fm; return { metadata: meta satisfies TPostMeta, content, map: response.map } } catch (e) { error(404, `Could not find ${params.article}`) } }
+page.svelte
<section class="container m-auto px-48"> {#if data.content && data.metadata} <article> <hgroup class="flex flex-col relative bottom-7 md:bottom-12 lg:bottom-8 gap-y-1" > <h1 class="bg-dh-black w-fit font-hanuman font-extrabold text-dh-orange text-[1.5em] md:text-6xl text-wrap lg:text-nowrap p-4 pb-0" > {data.metadata.title} </h1> <p>{new Date(data.metadata.date).toISOString().split("T")[0]}</p> <div class="tags flex letter--spacing--md font-quirkyrobot text-dh-orange text-[.9em] !gap-x-3" > {#each data.metadata.tags as tag} <span class="surface-4">#{tag}</span> {/each} </div> </hgroup> <div class="prose flex flex-col gap-y-6"> {@html data.content} </div> </article> {/if} </section>
源Markdown内容
## Usage To add a task: ```bash python tasktracker.py add "Write blog post"
To view tasks:
python tasktracker.py list
## 渲染异常截图  --- # 解决方案 ### 1. 核心问题分析 当前使用`compile`方法生成的是**Svelte组件代码**,而非纯HTML,直接用`{@html}`渲染会把Svelte的语法(如`{@html ...}`)当成文本输出,导致代码块显示异常。 ### 2. 修改代码:改用`render`生成纯HTML 将`+page.ts`中的`compile`替换为`mdsvex`的`render`方法,直接生成可渲染的HTML内容: ```ts // +page.ts import { PUBLIC_BLOG_URL } from '$env/static/public'; import type { TPostMeta } from '$lib/types/post/TPost.type.js'; import { error } from '@sveltejs/kit'; // 替换compile为render import { render } from 'mdsvex'; export async function load({ params }) { try { const url = `${PUBLIC_BLOG_URL}/refs/heads/master/${params.article}.md`; const res = await fetch(url); const post = await res.text(); // 使用render生成纯HTML和元数据 const { html, data } = await render(post, { extensions: ['.md'], filename: `${params.article}.md` }); if (!html) { throw new Error(`Could not render ${params.article}`); } const meta = data.fm; return { metadata: meta satisfies TPostMeta, content: html }; } catch (e) { error(404, `Could not find ${params.article}`); } }
3. (可选)添加代码高亮
如果需要代码高亮效果,安装prismjs并引入样式:
- 安装依赖:
npm install prismjs
- 在根布局
+layout.svelte中引入样式:
<script> import 'prismjs/themes/prism-tomorrow.css'; </script>
4. 验证效果
重新运行项目,代码块会被渲染为标准的<pre><code>结构,还原Obsidian中的原始样式。
内容的提问来源于stack exchange,提问作者skywizard
相关产品推荐
相关产品推荐

