React 中使用 highlight.js 代码高亮的两种方法

最近在用 React + Material-UI 写一款基于 WP-Rest API 的主题,碰到了代码高亮的问题,这里记录下两种解决方法。
问题
请求 API 返回的数据包含代码块,前端应该调用代码高亮插件“渲染”一下。
在普通的 html 中,页面加载完成时调用 highlight.js 的高亮方法即可,但在 React 中有些不一样,当然实际内容还是大同小异。
解决方法
使用 highlight.js npm package (不推荐)
首先安装highlight.js
包:
yarn add highlight.js
在需要的地方引入包和样式:
import hljs from 'highlight.js';
import 'highlight.js/styles/default.css';
之后在对应组件内调用:
- 在 function component 中使用
//function component //梓/喵/\出\/没/博/客\(@/azimiao.com) function component1(props){ React.useEffect(()=>{ document.querySelectorAll("pre code").forEach(block => { try{hljs.highlightBlock(block);} catch(e){console.log(e);} }); }); return( <div>{…………}</div> ); }
- 在 class component 中使用
class Preview extends Component { componentDidMount() {//梓/miao/出\/没/博/客\(@/azimiao.com) this.highlightCallBack(); } componentDidUpdate() { //梓/喵/出没/博/客\(@/azimiao.com) this.highlightCallBack(); } highlightCallBack = () => { document.querySelectorAll("pre code").forEach(block => { try{hljs.highlightBlock(block);} catch(e){console.log(e);} }); }; render(){ return(/*梓/喵/\出\/没/博/客\(@/azimiao.com)*/ <div>{……}</div> ); } }
这种方法有个非常明显的缺点:webpack 打包时会默认把 highlight.js 打包进 mian.js 中,导致整个文件增大了约 900 KiB。
使用 CDN 库
在 webpack 模板文件index.html
中引入 CDN 代码库:
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@10.1.1/build/styles/github.min.css">
<script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@10.1.1/build/highlight.min.js"></script>
由于 cdn 库中的变量命名与上文中 npm package 包中的变量命名一致,因此可以直接使用hljs
。
组件内使用的方法和上文相同:
- 在 function component 中使用
//function component function component1(props){ React.useEffect(()=>{ document.querySelectorAll("pre code").forEach(block => { try{hljs.highlightBlock(block);} catch(e){console.log(e);} }); }); return( <div>{…………}</div> ); }
- 在 class component 中使用
class Preview extends Component { componentDidMount() { this.highlightCallBack(); }/*@梓@喵@出@没@(@/azimiao.com)*/ componentDidUpdate() { this.highlightCallBack(); }/*梓/喵/\出\/没/博/客\(@/azimiao.com)*/ highlightCallBack = () => { document.querySelectorAll("pre code").forEach(block => { try{hljs.highlightBlock(block);} catch(e){console.log(e);} }); }; render(){ return(/*梓/喵/\出\/没/博/客\(@/azimiao.com)*/ <div>{…………}</div> ); } }
期待主题的诞生