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

如何在TSX的JSX标签内保留换行符?

解决TSX中Markdown渲染丢失换行的问题

1. 能否直接阻止TSX编译器去除换行?

做不到。TSX遵循JSX规范,会自动将文本节点中的连续空白(换行、多空格等)合并为单个空格,这是内置的文本处理逻辑,没有编译选项可以直接关闭该行为。

2. 使用TypeScript Transformers替换换行符

可以通过自定义Transformer在编译阶段修改AST,给换行符添加标记,后续渲染Markdown时再还原换行。

实现步骤:

  • 编写Transformer遍历AST,定位JSXText节点,将节点内的\n替换为__NL__\n(自定义标记)
  • Markdown渲染前,移除标记恢复原始换行

示例Transformer代码:

import * as ts from 'typescript';

export function preserveNewlinesTransformer(): ts.TransformerFactory<ts.SourceFile> {
  return (context) => {
    const visitor: ts.Visitor = (node) => {
      if (ts.isJSXText(node)) {
        const newText = node.text.replace(/\n/g, '__NL__\n');
        return ts.factory.createJSXText(newText);
      }
      return ts.visitEachChild(node, visitor, context);
    };
    return (sourceFile) => ts.visitNode(sourceFile, visitor);
  };
}

启用Transformer:

默认tsc不支持自定义Transformer,需借助ts-patch扩展,在tsconfig.json中配置:

{
  "compilerOptions": {
    "plugins": [
      { "transform": "./path/to/your-transformer.ts" }
    ]
  }
}

渲染时还原换行:

function renderMarkdown(text: string) {
  const restoredText = text.replace(/__NL__/g, '');
  return yourMarkdownRenderer(restoredText);
}

3. Bun.js下的自定义实现

Bun支持自定义加载器和编译插件,可在TSX文件加载阶段直接处理换行:

示例Bun插件:

import { plugin } from 'bun';

plugin({
  name: 'preserve-tsx-newlines',
  setup(build) {
    build.onLoad({ filter: /\.tsx$/ }, async (args) => {
      const source = await Bun.file(args.path).text();
      // 匹配JSX标签内的文本并替换换行(复杂场景建议用AST解析)
      const modifiedSource = source.replace(/(?<=>{1})[^<>]*?(?=<)/g, (match) => {
        return match.replace(/\n/g, '__NL__\n');
      });
      return {
        contents: modifiedSource,
        loader: 'tsx',
      };
    });
  },
});

若需要更严谨的处理,可复用前面的AST遍历逻辑,借助Bun内置的TypeScript API操作源码AST。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:45:09