React中的语法高亮指南

2,170 阅读8分钟

简介

软件开发人员阅读的代码和他们写的一样多。因此,为了提高代码的可读性,你不仅要努力写出可读的代码,还要应用适当的代码格式化和语法高亮。

有几种编程和非编程的计算机语言,开发人员每天都在使用。每种语言都有其语法,因此也有语法高亮的需求。为了在浏览器环境中应用语法高亮,存在Prism、Highlight和React语法高亮器等库。

这些库都有其优势和劣势。其中一些库是为使用普通的JavaScript而开发的,而其他库也支持React等前端框架。

本文将全面介绍Prism等流行的语法高亮库,以及如何在React中使用它们。我们还将强调它们的优势和劣势。

目录

介绍一下prism.js

Prism是JavaScript中最受欢迎的语法高亮库之一,在GitHub上有超过10,000颗星。你可以将它用于普通的JavaScript和框架,如React。它支持多种语言,并有一个丰富的主题和插件的生态系统,你可以用它来扩展其核心功能。

为了体验Prism,你可以通过CDN快速加载它,或下载源代码,并使用script 标签将其添加到你的标记中。你还可以下载对特定语言、主题和插件的支持。

核心的Prism库有一个小的足迹。它的压缩和gzipped包的大小大约是2kB。尽管你为扩展Prism的功能而下载的额外主题和插件可能会增加包的大小,但你可以完全控制你可以下载哪些插件或主题。

此外,与一些语法高亮器不同的是,Prism迫使你使用语义的HTML来展示代码。这种可定制性,以及其他一些特性,使Prism成为语法高亮的热门选择。

Babel-plugin-prismjs是一个方便的软件包,用于将Prism与Babel和webpack一起使用。在下一节中,我们将看看如何在React应用程序中使用这个插件。

如何在React中使用Prism进行语法突出显示

如上一节所述,使用Prism的最简单和最快的方法是使用CDN。虽然CDN可能很方便,但在使用React这样的框架时,几乎不可能使用它。因此,你需要从NPM安装它。

sh
# using npm
npm install prismjs
# using yarn
yarn add prismjs

如果你想在React应用程序中使用Prism进行语法高亮,babel-plugin-prismjs Babel插件就会很方便。你可以用它来配置与Prism捆绑的语言、主题和插件。你可以把它作为开发依赖项从NPM安装。

sh
# using npm
npm i -D babel-plugin-prismjs
# using yarn
yarn add -D babel-plugin-prismjs

你需要像这样在你的Babel配置文件中注册这个插件。

{
  "plugins": [
    ["prismjs", {
        "languages": ["javascript", "css", "markup"],
        "plugins": ["line-numbers"],
        "theme": "twilight",
        "css": true
    }]
  ]
}

你可以在配置文件中包括你的项目需要的语言、插件和主题。查看Prism文档,了解支持的语言以及你可以使用的可用主题和插件的完整列表。

如果你想使用babel-plugin-prismjs 插件,设置一个自定义的react应用程序。然而,要用CreateReactApp来使用它,你需要弹出 - 我认为这样做违背了使用Create React App的目的。

此外,有几个React语法高亮包在引擎盖下使用Prism。我们将在下面的章节中探讨其中一些。如果你的项目不是基于定制的React应用程序,你可以考虑使用其中之一。

完成上述设置后,将Prism导入你的React组件,并像这样调用useEffect 钩子中的highlightAll 方法。

import React, { useEffect } from "react";
import Prism from "prismjs";

function App() {
  useEffect(() => {
    Prism.highlightAll();
  });
  return (
    <div>
      <p>
        You can declare a variable in JavaScript using the
        `const`, `let` or `var` keyword. </p> </div> ); } export default App;

当使用Prism时,你需要将内联代码包裹在code HTML标签中,并根据你所强调的语言,对其应用适当的类。类的名称应该采取lang-xxxxlanguage-xxxx 的形式。

xxxx 是语言的一个占位符。在上面的例子中,我们把lang-javascript 类添加到code 元素中,因为我们要高亮显示JavaScript代码。

正如上一节所指出的,Prism强迫你在添加代码到你的标记时使用语义的HTML。因此,在高亮显示代码块时,你必须用pre 元素来包装你的代码。

在渲染代码块时,将你的功能提取到一个单独的组件中,以便于重用,就像下面的例子一样,这很方便。你可以把代码块和语言作为道具传递。

import React, { useEffect } from "react";
import Prism from "prismjs";

const CodeBlock = ({ code, language }) => {
  useEffect(() => {
    Prism.highlightAll();
  }, []);
  return (
    <pre>
      <code children={code} className={`language-${language}`} />
    </pre>
  );
};

export default CodeBlock;

如何使用Prism-react-renderer

你也可以使用prism-react-renderer来突出React应用程序中的代码,而不是像我们在上一节所做的那样将Prism与React应用程序一起使用。

prism-react-renderer与修改过的Prism版本捆绑在一起,它默认提供对一些常用语言和主题的支持。

你需要从NPM安装prism-react-renderer才能使用它。

sh
# install with npm
npm i prism-react-renderer

# install with yarn
yarn add prism-react-renderer

Prism react renderer将Highlight 作为其主要组件,并导出一些默认道具,你可以将这些道具传递给Highlight 。你需要将一个render 的道具传递给Highlight 组件,如下例所示。

import React from "react";
import Highlight, { defaultProps } from "prism-react-renderer";

export const CodeBlock = ({ code, language }) =&gt; {
  return (
    &lt;Highlight {...defaultProps} code={code} language={language}&gt;
      {({ className, style, tokens, getLineProps, getTokenProps }) =&gt; {
        return (
          &lt;pre className={className} style={style}&gt;
            <code>
                  {tokens.map((line, idx) => {
                    return (
                      <div {...getLineProps({ line, key: `line-${idx}` })}>
                        {line.map((token, i) => {
                          return (
                            <span
                              {...getTokenProps({ token, key: `token-${i}` })}
                            />
                          );
                        })}
                      </div>
                    );
                  })}
                </code>
          &lt;/pre&gt;
        );
      }}
    &lt;/Highlight&gt;
  );
};
</code></pre>

上面的代码块说明了你如何用prism-react-renderer包突出一个简单的代码块。Highlight 组件向渲染道具传递了几个参数。你可以像上面的例子一样使用这些道具来渲染你的代码块。

你可以导入我们上面写的CodeBlock 组件,并在渲染代码块时传入codelanguage 道具。这样做使该组件可重复使用。

import { CodeBlock } from "./CodeBlock";

const code = `
  const add = (a, b) => {
    return a + b;
  }
`;

function MyComponent() {
  return (
    <div className="App">
      <CodeBlock code={code} language="javascript" />
    </div>
  );
}

react-syntax-highlighter 介绍

react-syntax-highlighter是一个React组件,用于React的语法高亮。它在内部使用Prism和Highlight进行语法高亮。Prism和Highlight是浏览器环境下流行的语法高亮器之一。

你从NPM安装它,并传入必要的props就可以开始使用react-syntax-highlighter。

sh
# using npm
npm i react-syntax-highlighter

# using yarn
yarn add react-syntax-highlighter

与前几节描述的一些包不同,你不需要额外的配置就能让它工作。让我们在下面的章节中看看如何在React中使用它进行语法高亮。

如何使用 react-syntax-highlighter

安装完react-syntax-highlighter后,你可以导入并渲染必要的组件。正如上一节提到的,你可以选择使用Highlight或Prism进行高亮。

然而,react-syntax-highlighter默认导出一个使用Highlight的组件。你需要在渲染它的时候像这样把配置选项作为props传递。

import SyntaxHighlighter from "react-syntax-highlighter";
import { dracula } from "react-syntax-highlighter/dist/esm/styles/hljs";

const code = `
console.log("hello world");
`;

function App() {
  return (
      <SyntaxHighlighter children={code} language="javascript" style={dracula} />
  );
}

如上面的例子所示,你把你要高亮的代码和格式化语言作为字符串道具传递。除了children,language, 和style 这些道具外,还有一些其他的格式化选项,如行号的显示和样式。请查看文档,了解可用选项的完整列表。

正如介绍中所指出的,react-syntax-highlighter与Highlight和Prism都捆绑在一起。在上面的例子中,你可以不使用Highlight,而是使用Prism。当使用Prism时,你还需要导入你想使用的Prism主题,就像下面的例子:

import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/esm/styles/prism';

尽管上面描述的使用方法在开箱后就加载了几个功能,但它的占用空间很大。因此,react-syntax-highlighter有一个轻量级构建,只加载和捆绑你需要的功能。

然而,要注意的是,轻量级构建并不带有默认的样式。因此,你需要自己导入主题。此外,使用registerLanguage 功能导入和注册语言,如下面的例子:

import { Light as SyntaxHighlighter } from "react-syntax-highlighter";

import typescript from "react-syntax-highlighter/dist/esm/languages/hljs/typescript";
import a11yDark from "react-syntax-highlighter/dist/esm/styles/hljs/a11y-dark";

SyntaxHighlighter.registerLanguage('typescript', typescript);

上面的例子中,light build默认使用Highlight。你也可以类似地使用Prism。导入PrismLight ,而不是Light ,如下面的例子:

import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter";

import typescript from "react-syntax-highlighter/dist/esm/languages/prism/typescript";
import a11yDark from "react-syntax-highlighter/dist/esm/styles/prism/a11y-dark";

SyntaxHighlighter.registerLanguage('typescript', typescript);

查看文档,了解 react-syntax-highlighter 包的更多功能和限制。

Rainbow的介绍

上面提到的语法高亮库是最流行和最容易使用的React。

然而,它们并不是唯一的语法高亮库。Rainbow是另一个简单和轻量级的语法高亮包。它值得探索,特别是当你没有使用React这样的框架时。

结论

在发布包含内联代码片段或代码块的内容时,语法高亮是不可避免的,以增加可读性。在浏览器环境中突出显示代码时,有几个库可以选择。语法高亮库中最受欢迎的是Prism和Highlight。

如上所述,你可以将一些语法高亮库用于普通的JavaScript,另一些则用于React等框架。babel-plugin-prismjs Babel插件可以让你在webpack等捆绑器中使用Prism。然而,你也可以使用React包,如Prism-react-renderer或react-syntax-highlighter,它们捆绑了Prism的修改版本。

如果考虑到核心库,Prism有一个小的足迹。然而,当你用额外的主题和插件来扩展其核心功能时,它就变得相当大了。

尽管我们在这篇文章中的重点是可用于React的语法高亮器,但其他几个语法高亮库如Rainbow也值得探索。如果你没有使用React这样的前端框架,Rainbow是一个值得考虑的语法高亮库。