1
- import { useEffect , useState } from 'react' ;
1
+ 'use server' ;
2
+
2
3
import { createHighlighter , Highlighter } from 'shiki' ;
4
+ import { FC } from 'react' ;
3
5
4
6
interface ShikiHighlighterProps {
5
7
lang : string ;
@@ -19,36 +21,30 @@ const allowLanguages = [
19
21
'typescript' ,
20
22
] ;
21
23
22
- export const ShikiHighlighter : React . FC < ShikiHighlighterProps > = ( { lang, content } ) => {
23
- const [ highlightedCode , setHighlightedCode ] = useState < string | null > ( null ) ;
24
-
25
- useEffect ( ( ) => {
26
- let highlighter : Highlighter ;
27
-
28
- const loadHighlighter = async ( ) => {
29
- highlighter = await createHighlighter ( {
30
- themes : [ 'min-light' , 'nord' ] ,
31
- langs : [ ...allowLanguages ] ,
32
- } ) ;
33
-
34
- const code = highlighter . codeToHtml ( content , {
35
- lang : allowLanguages . includes ( lang ) ? lang : 'javascript' ,
36
- themes : {
37
- light : 'min-light' ,
38
- dark : 'nord' ,
39
- } ,
40
- } ) ;
41
- setHighlightedCode ( code ) ;
42
- } ;
43
-
44
- loadHighlighter ( ) ;
45
-
46
- return ( ) => {
47
- highlighter = null as any ;
48
- } ;
49
- } , [ lang , content ] ) ;
50
-
51
- return highlightedCode ? (
52
- < div className = "code-card" dangerouslySetInnerHTML = { { __html : highlightedCode } } />
53
- ) : null ;
24
+ let highlighter : Highlighter | null = null ;
25
+
26
+ // 初始化 Shiki highlighter
27
+ const getHighlighter = async ( ) => {
28
+ if ( ! highlighter ) {
29
+ highlighter = await createHighlighter ( {
30
+ themes : [ 'min-light' , 'nord' ] ,
31
+ langs : [ ...allowLanguages ] ,
32
+ } ) ;
33
+ }
34
+
35
+ return highlighter ;
36
+ } ;
37
+
38
+ export const ShikiHighlighter : FC < ShikiHighlighterProps > = async ( { lang, content } ) => {
39
+ const highlighter = await getHighlighter ( ) ;
40
+
41
+ const highlightedCode = highlighter . codeToHtml ( content , {
42
+ lang : allowLanguages . includes ( lang ) ? lang : 'javascript' ,
43
+ themes : {
44
+ light : 'min-light' ,
45
+ dark : 'nord' ,
46
+ } ,
47
+ } ) ;
48
+
49
+ return < div className = "code-card" dangerouslySetInnerHTML = { { __html : highlightedCode } } /> ;
54
50
} ;
0 commit comments