跳到正文
astro-join-line
English

移除 Astro 的中文空格

在 CJK 文本中,这个问题看起来就像是标点后多出的细小间隙。它的成因很容易被忽略:HTML 的常规空白处理会把源码中的换行折叠成空格。

空格从哪里来

这不是 Astro、React 或任何前端框架造成的问题。源文件或 Markdown 解析结果中的软换行,最终会进入 HTML 文本节点,浏览器再按 white-space: normal 的默认规则将其折叠成普通空格。这条规则并不针对中文,但中文通常不需要词间空格,因此问题会格外明显。

源代码

article.mdx

带标点

1 第一行; LF ↵
2 第二行。

不带标点

1 第一行 LF ↵
2 第二行。

浏览器输出

white-space: normal

带标点

第一行; 第二行。

不带标点

第一行 第二行。

工作原理

安装 astro-join-line 后,你可以在受支持的 CJK 标点后安全换行。插件只会移除这类符合条件的软换行,让下一行文本在输出中紧接标点。普通字符后的换行不会被修改,仍会按浏览器默认规则渲染成空格,因此连续中文文本仍不能随意换行。

插件已启用

符合条件的软换行会在输出前被移除。

源代码

article.mdx
1 第一行; LF ↵
2 第二行。

浏览器输出

无多余空格

第一行;第二行。

只有受支持标点后的软换行会被移除,有意保留的空白不会被改变;scriptstyleprecodetextarea 等敏感元素中的内容也会保持原样。

安装与配置

终端
pnpm add astro-join-line

Astro 模板

将默认集成添加到 Astro 配置中。

astro.config.mjs
import { defineConfig } from 'astro/config'
import joinLine from 'astro-join-line'

export default defineConfig({
  integrations: [joinLine()],
})

Markdown 和 MDX

在 Astro 的 Markdown 处理器中使用 Remark 入口;@astrojs/mdx 会继承同一个处理器。

astro.config.mjs
import { unified } from '@astrojs/markdown-remark'
import mdx from '@astrojs/mdx'
import remarkJoinLine from 'astro-join-line/remark'
import { defineConfig } from 'astro/config'

export default defineConfig({
  markdown: {
    processor: unified({
      remarkPlugins: [remarkJoinLine],
    }),
  },
  integrations: [mdx()],
})