Next.js构建时HTML与JS文件用不同模块导致Hydration问题
解决Next.js中CJS/ESM组件库的Hydration不匹配问题
问题根源
Next.js服务端(SSR/SSG阶段)用require加载模块,触发组件库的require条件导出,拉取CJS版本;客户端打包时用import,触发import条件导出,加载ESM版本。你给两个版本的Button加了不同的渲染文本,导致服务端生成的HTML和客户端 hydrated 的DOM内容不一致,直接引发Hydration错误。
解决方案
1. 统一组件库两端的输出内容
这是最核心的解决办法——CJS和ESM版本只是编译格式差异,组件的渲染结果必须完全一致。把你调试加的“CJS”“MJS”标识去掉,确保两个版本的Button渲染相同的DOM结构和文本。
2. 强制Next.js两端用同一种模块格式
如果只是临时调试,或者组件库暂时没法统一输出,可以通过配置强制两端用同一版本:
强制用ESM版本
在项目的next.config.js里加以下配置,让服务端也能加载ESM依赖:
/** @type {import('next').NextConfig} */ const nextConfig = { experimental: { esmExternals: 'loose' } } module.exports = nextConfig
强制用CJS版本
临时修改组件库package.json的exports,直接指定单一入口(调试完记得改回去):
"exports": { ".": "./lib/cjs/index.js" }
3. 检查组件库的编译流程
确保CJS和ESM版本是从同一源码编译出来的,用Rollup、webpack这类工具时,要保证两端的编译配置(babel插件、代码转换规则)完全一致,避免编译过程中产生逻辑差异。
内容的提问来源于stack exchange,提问作者singularity
相关产品推荐
相关产品推荐

