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

如何实现Express根端点返回并渲染README.md文件?

解决Express渲染README.md为GitHub风格页面的问题

为什么你的代码报错?

require('../README.md') 会让Node.js把MD文件当作JS模块解析,但MD的语法(比如开头的#)不是合法的JS语法,所以直接抛出语法错误。Node.js默认只支持JS、JSON等模块类型,不能直接require MD文件。

实现步骤

1. 安装必要依赖

需要用marked解析Markdown为HTML,highlight.js实现代码高亮:

npm install marked highlight.js

2. 编写Express路由代码

用Node.js内置的fs模块读取README.md内容,再用marked转换为HTML,最后返回带GitHub风格样式的页面:

const express = require('express');
const fs = require('fs');
const path = require('path');
const marked = require('marked');
const hljs = require('highlight.js');

const app = express();

// 配置marked,启用代码高亮,匹配GitHub风格语法
marked.setOptions({
  highlight: function(code, lang) {
    const language = hljs.getLanguage(lang) ? lang : 'plaintext';
    return hljs.highlight(code, { language }).value;
  },
  breaks: true, // 支持换行
  gfm: true // 支持GitHub Flavored Markdown
});

app.get('/', (req, res) => {
  // 确定README.md的绝对路径
  const readmePath = path.join(__dirname, '../README.md');
  try {
    // 同步读取文件内容
    const readmeContent = fs.readFileSync(readmePath, 'utf8');
    // 将Markdown转换为HTML
    const htmlContent = marked(readmeContent);
    // 构造完整HTML页面,内嵌GitHub风格样式
    const fullHtml = `
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>README</title>
        <style>
          body {
            max-width: 800px;
            margin: 2rem auto;
            padding: 0 1rem;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
            line-height: 1.5;
          }
          h1, h2, h3, h4, h5, h6 {
            margin-top: 2rem;
            margin-bottom: 1rem;
            font-weight: 600;
          }
          pre {
            background-color: #f6f8fa;
            border-radius: 6px;
            padding: 1rem;
            overflow-x: auto;
          }
          code {
            background-color: #f6f8fa;
            padding: 0.2rem 0.4rem;
            border-radius: 3px;
          }
          blockquote {
            border-left: 4px solid #dfe2e5;
            padding-left: 1rem;
            color: #6a737d;
            margin: 0;
          }
          /* 代码高亮样式(模拟GitHub) */
          .hljs {
            color: #24292e;
            background: #f6f8fa;
          }
          .hljs-doctag, .hljs-keyword, .hljs-meta .hljs-keyword, .hljs-template-tag, .hljs-template-variable, .hljs-type, .hljs-variable.language_ {
            color: #d73a49;
          }
          .hljs-title, .hljs-title.class_, .hljs-title.class_.inherited__, .hljs-title.function_ {
            color: #6f42c1;
          }
          .hljs-attr, .hljs-attribute, .hljs-literal, .hljs-meta, .hljs-number, .hljs-operator, .hljs-selector-attr, .hljs-selector-class, .hljs-selector-id, .hljs-variable {
            color: #005cc5;
          }
          .hljs-meta .hljs-string, .hljs-regexp, .hljs-string {
            color: #032f62;
          }
          .hljs-built_in, .hljs-symbol {
            color: #e36209;
          }
          .hljs-code, .hljs-comment, .hljs-formula {
            color: #6a737d;
          }
          .hljs-name, .hljs-quote, .hljs-selector-pseudo, .hljs-selector-tag {
            color: #22863a;
          }
          .hljs-subst {
            color: #24292e;
          }
          .hljs-section {
            color: #005cc5;
            font-weight: 700;
          }
          .hljs-bullet {
            color: #735c0f;
          }
          .hljs-emphasis {
            color: #24292e;
            font-style: italic;
          }
          .hljs-strong {
            color: #24292e;
            font-weight: 700;
          }
          .hljs-addition {
            color: #22863a;
            background-color: #f0fff4;
          }
          .hljs-deletion {
            color: #b31d28;
            background-color: #ffeef0;
          }
        </style>
      </head>
      <body>
        ${htmlContent}
      </body>
      </html>
    `;
    res.send(fullHtml);
  } catch (err) {
    res.status(500).send('无法加载README.md文件');
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

代码说明

  • fs.readFileSync:同步读取README.md内容,也可以用异步的fs.promises.readFile配合async/await,避免阻塞服务器事件循环:
    app.get('/', async (req, res) => {
      const readmePath = path.join(__dirname, '../README.md');
      try {
        const readmeContent = await fs.promises.readFile(readmePath, 'utf8');
        const htmlContent = marked(readmeContent);
        // 构造fullHtml...
        res.send(fullHtml);
      } catch (err) {
        res.status(500).send('无法加载README.md文件');
      }
    });
    
  • marked.setOptions:配置解析规则,启用代码高亮和GFM语法,让渲染效果更贴近GitHub。
  • 内嵌样式:模拟GitHub的页面布局和代码高亮样式,无需依赖外部资源。
  • 错误处理:捕获文件读取失败的情况,返回友好的错误提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:45:56