You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS中react-highlight组件开发正常生产模式失效求助

NextJS中react-highlight生产模式无代码高亮的解决方案

问题背景

在NextJS项目中使用react-highlight的Highlight组件时,开发模式下能正常渲染带格式的代码高亮,但生产模式仅显示纯文本,无预期格式化效果。已尝试动态导入、修改拆分CSS等操作,无效,怀疑和静态渲染有关。

相关代码:

Header.tsx

'use client'
import "./Header.scss";
import { CodeBlock } from '../CodeBlock/CodeBlock';
import { codeSnipetsHeader, codeSnipetsHeader2 } from "./data";
import { useEffect, useRef } from "react";
import { motion } from "framer-motion";
import { usePathname } from 'next/navigation';

export function Header(): JSX.Element {
    const pathname: string = usePathname();
    const ref = useRef<number>(0);
    
    useEffect(() => {
        ref.current++;
    }, [pathname]);

    let codeSnipetstoShow = codeSnipetsHeader2;
    if (pathname.length < 2) { codeSnipetstoShow = codeSnipetsHeader; }

    return (
        <header>
            <motion.div key={ref.current} className="group" exit={{ opacity: 0 }} transition={{ duration: 1 }}>
                {codeSnipetstoShow.map((value, index): JSX.Element => (
                    <motion.div key={index}
                        initial={{ opacity: 0 }}
                        animate={{ opacity: 1 - (index * 0.2) }}
                        transition={{ duration: index + 1 }}
                    >
                        <CodeBlock language="typescript" text={value.text} fontSize={value.fontSize} margin={value.margin} />
                    </motion.div>
                ))}
            </motion.div>
        </header>
    );
}

CodeBlock.tsx

import { CSSProperties } from "react";
import Highlight from 'react-highlight';
import { motion } from 'framer-motion';
import './CodeBlock.scss';

interface CodeBlockProps {
    text: string;
    margin?: string;
    fontSize: number;
    language: "typescript" | "javascript" | "java" | "php";
}

export function CodeBlock(props: CodeBlockProps): JSX.Element {
    const marginStyle: CSSProperties = props.margin ? { margin: props.margin } : {};
    const finalStyle: CSSProperties = { ...marginStyle, fontSize: props.fontSize };

    return (
        <motion.div className='codeblock' style={finalStyle}>
            <Highlight language={props.language}>
                {props.text}
            </Highlight>
        </motion.div>
    );
}

原因分析

  1. 组件渲染环境不匹配:CodeBlock未标记'use client',NextJS默认将其视为服务器组件。react-highlight依赖浏览器DOM操作完成高亮逻辑,服务器渲染阶段无法执行该逻辑,生产模式静态渲染会直接输出未处理的纯文本。
  2. highlight.js语言包被Tree-Shaking移除:react-highlight依赖highlight.js的语言定义包,生产构建时若未显式导入这些包,NextJS的优化会将未被引用的模块移除,导致无法识别代码语法进行高亮。

解决方案

1. 标记CodeBlock为客户端组件

在CodeBlock.tsx顶部添加'use client',确保组件在浏览器端执行,同时显式导入所需的highlight.js语言包:

'use client'
import { CSSProperties, useEffect } from "react";
import Highlight from 'react-highlight';
import { motion } from 'framer-motion';
import hljs from 'highlight.js';
import './CodeBlock.scss';
// 导入高亮样式(可替换为你喜欢的主题)
import 'highlight.js/styles/github.css';
// 显式导入所需语言包,防止被Tree-Shaking移除
import 'highlight.js/lib/languages/typescript';
import 'highlight.js/lib/languages/javascript';
import 'highlight.js/lib/languages/java';
import 'highlight.js/lib/languages/php';

interface CodeBlockProps {
    text: string;
    margin?: string;
    fontSize: number;
    language: "typescript" | "javascript" | "java" | "php";
}

export function CodeBlock(props: CodeBlockProps): JSX.Element {
    const marginStyle: CSSProperties = props.margin ? { margin: props.margin } : {};
    const finalStyle: CSSProperties = { ...marginStyle, fontSize: props.fontSize };

    // 手动触发高亮,确保内容更新时重新渲染
    useEffect(() => {
        hljs.highlightAll();
    }, [props.text]);

    return (
        <motion.div className='codeblock' style={finalStyle}>
            <Highlight language={props.language}>
                {props.text}
            </Highlight>
        </motion.div>
    );
}

2. 验证静态渲染兼容

由于Header组件已使用usePathname(客户端钩子),本身已是客户端组件,其子组件CodeBlock必须同为客户端组件才能保证渲染逻辑一致,避免生产模式下的渲染冲突。

内容的提问来源于stack exchange,提问作者Jérôme MARICHEZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:23:16