1. 場景描述
在博客, 文檔, 論壇這些性質的網站經常存在着需要顯示代碼的需求; 對於這種要求要求, 我們可以直接使用textarea 標簽顯示:
但是這種顯示方案非常不美觀, 不但沒有高亮代碼, 而且也沒有顯示行號, 這對於代碼的閱讀是非常不友好的;
而一般的網站, 對於代碼的顯示都會做高亮處理, 如antd Design 文檔:
這種方案的原理是先設計一套CSS 顯示方案, 例如規定好關鍵字, 符號, 屬性等內容的顯示方案; 然后寫一套CSS parser, 將代碼解析成為特定的字段, 然后將這些字段處理成特定的元素(這些元素為class 帶上css 解決方案); 該原理和json parser 很類似
Json Parser 原理: Json Parser 原理
不過在業務場景, 並不推薦自己寫一套解析器, 雖然個人感覺實現一套特定規則的代碼高亮方案並不會很難, 但是實用性並不強, 因此我們使用現有的解決方案;
而這里介紹的解決方案為 prosmjs, 由於網上論壇(CSDN, 博客園, 掘金) 並沒有找到關於React 應用demo, 所以這里記錄的是React 使用Prism Demo
2. React Prism
如果你需要在React 應用中使用Prismjs, 那么你需要使用到如下內容:
2.1 prismjs 庫
prism 庫, 里面包含着prism 的基本內容, 包括js 文件, css文件, 插件, 主題等內容
yarn add prismjs
2.2 babel-plugin-prismjs 插件
webpack 對於prism 打包需要使用到的插件
安裝:
yarn add babel-plugin-prismjs
.babelrc 配置:
"plugins": [
["prismjs", {
"languages": ["javascript", "css", "markup"],
"plugins": ["line-numbers"],
"theme": "okaidia",
"css": true
}]
]
3. demo
項目地址: PrismReactDemo
import React from 'react'
import Prism from 'prismjs';
const log = console.log.bind(console)
class PrismjsDemo extends React.Component{
constructor(props) {
super(props)
this.state = {}
}
render() {
const code = `const listMaxValue = (list) => {
let max = list[0]
for(let i = 1, len = list.length; i < len; i++) {
if(max > list[i]) {
max = list[i]
}
}
return max
}`
log(Prism)
let codeHtml = {
// Prism.highlight(text, grammar, language)
// text: 需要格式化的代碼
// grammar: 需要格式化代碼的語法
// language: 需要格式化代碼表示的語言
__html: Prism.highlight(code, Prism.languages.javascript, 'javascript')
}
return (
<>
<pre className="language-javascript line-numbers">
<code dangerouslySetInnerHTML={codeHtml}></code>
</pre>
</>
)
}
}
export default PrismjsDemo
運行結果:
4. 注意點
- 在React 框架匯中, 使用Prism 的格式為: 必須存在pre code 標簽, 如果不按照這個格式, 那么代碼將不會換行
<pre className="language-javascript line-numbers">
<code dangerouslySetInnerHTML={codeHtml}></code>
</pre>
- 如果需要顯示主體, 需要顯示行號, 必須添加相關的css 類名
<>
{/* 如果不添加language-, 將不會顯示主體('language-' + 語言名稱) */}
{/*如果不添加line-numbers, 將不會顯示行號*/}
<pre className="language-javascript line-numbers">
<code dangerouslySetInnerHTML={codeHtml}></code>
</pre>
</>
- 在個人項目中, 顯示行號的插件失效了, 具體原因暫時未知(使用antd design UI 框架, 不知道是不是這個原因)