You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SvelteKit中为数据库存储的Markdown添加语法高亮遇阻求助

问题

我正在开发一款带浏览器端Markdown编辑器的博客,用marked等解析器能正常渲染Markdown内容,但给代码块加语法高亮时碰到了问题。我用marked自定义了解析器,但getHighlighter没有从node_modules读取资源,反而去请求我的API路由,报404错误。

我试过highlight.js、prism等多款高亮工具,还有mark-it等同类型解析器,多数都没法实现语法高亮,不确定是SvelteKit的问题还是高亮工具的问题。

相关代码:

// utils.ts
import {Marked} from 'marked'
import {getHighlighter} from 'shiki'

export const marked = new Marked(
    markedHighlight({
        async: true,
        async highlight(code, lang) {
            const highlighter = await getHighlighter({
                theme: 'nord'
            });
            const html = highlighter.codeToHtml(code, { lang });
            return html;
        }
    })
);

// +page.ts
async function load({params}){
  ...
  return await marked.parse(txt)
}

报错信息:

SvelteKitError: Not found: /themes/nord.json
    at resolve (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:495:13)
    at resolve (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:295:5)
    at #options.hooks.handle (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\index.js:63:56)
    at Module.respond (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:292:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  status: 404,
  text: 'Not Found'
}
SvelteKitError: Not found: /dist/onig.wasm
    at resolve (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:495:13)
    at resolve (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:295:5)
    at #options.hooks.handle (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\index.js:63:56)
    at Module.respond (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:292:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  status: 404,
  text: 'Not Found'
}
SvelteKitError: Not found: /themes/nord.json
    at resolve (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:495:13)
    at resolve (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runruntime\server\respond.js:295:5)
    at #options.hooks.handle (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\index.js:63:56)
    at Module.respond (C:\Users\leung\OneDrive\Desktop\Programming\mdsvex\markdown-blog-mdsvex-ts\node_modules\@sveltejs\kit\src\runtime\server\respond.js:292:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  status: 404,
  text: 'Not Found'
}

解决方案

针对Shiki的问题

Shiki在浏览器环境默认会从CDN加载主题和语法文件,但SvelteKit的路由规则会把这些请求当成API路由处理,导致404。解决方法有两种:

1. 预加载主题和语法(推荐服务端渲染场景)

在服务端预加载所需的主题和语法,避免浏览器端请求资源。修改utils.ts:

import {Marked} from 'marked'
import {getHighlighter, loadTheme, loadLanguage} from 'shiki'

// 预加载主题和常用语言
const nordTheme = await loadTheme('node_modules/shiki/themes/nord.json');
const tsLanguage = await loadLanguage('typescript');
const jsLanguage = await loadLanguage('javascript');

export const marked = new Marked(
    markedHighlight({
        async: true,
        async highlight(code, lang) {
            const highlighter = await getHighlighter({
                themes: [nordTheme],
                languages: [tsLanguage, jsLanguage],
                defaultTheme: 'nord'
            });
            return highlighter.codeToHtml(code, { lang });
        }
    })
);

注意:这种方式要确保代码在服务端运行,如果是客户端组件,需要用load函数在服务端完成解析,或者把高亮逻辑放到服务端。

2. 配置Shiki的资源加载路径

如果要在客户端使用Shiki,需要把Shiki的资源文件(主题、onig.wasm)复制到SvelteKit的static目录,然后指定资源路径:

import {getHighlighter} from 'shiki'

const highlighter = await getHighlighter({
    theme: 'nord',
    paths: {
        // 假设把shiki的themes和dist目录复制到static/shiki下
        themes: '/shiki/themes/',
        wasm: '/shiki/dist/onig.wasm'
    }
});

改用更适配SvelteKit的方案

如果Shiki配置太麻烦,可以试试mdsvex(你项目里已经有相关目录),它内置了语法高亮支持,配合rehype-highlight或者rehype-shiki就能快速实现:

  1. 安装依赖:
npm install mdsvex rehype-highlight
  1. 在svelte.config.js里配置mdsvex:
import {mdsvex} from 'mdsvex';
import rehypeHighlight from 'rehype-highlight';

export default {
    extensions: ['.svelte', '.md'],
    preprocess: mdsvex({
        rehypePlugins: [rehypeHighlight]
    })
};

这样直接写Markdown文件就能自动高亮代码块,不用手动调用marked解析。

其他高亮工具的注意点

  • highlight.js:确保在客户端组件里初始化,或者在服务端渲染时直接生成带高亮类的HTML,然后引入对应的CSS文件。
  • Prism.js:需要在客户端引入Prism的JS和CSS,并且确保代码块在DOM加载完成后调用Prism.highlightAll()。

内容的提问来源于stack exchange,提问作者marcopopo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 11:34:53