Next.js中使用RecordRTC报错:无法设置仅含getter的navigator属性
问题原因
错误源于RecordRTC库的RecordRTC.js第1586行尝试直接赋值global.navigator,但在Next.js的Node.js服务器环境中,global.navigator是只读属性(仅包含getter),无法直接覆盖。即便你的组件是客户端渲染,若库在服务端渲染阶段被导入执行,这段代码仍会触发错误。
解决方案
方案1:动态导入RecordRTC并禁用SSR
通过Next.js的动态导入功能,确保RecordRTC仅在客户端加载,避免服务端执行修改navigator的代码。
方法A:在useEffect中动态导入
在组件内部使用useEffect(仅客户端执行)导入RecordRTC:
import { useEffect, useState } from 'react'; function YourComponent() { const [RecordRTC, setRecordRTC] = useState(null); const [recordRtcInstance, setRecordRtc] = useState(null); useEffect(() => { // 仅在客户端加载RecordRTC const loadRecordRTC = async () => { const module = await import('recordrtc'); setRecordRTC(module.default); }; loadRecordRTC(); }, []); const startRecording = async () => { if (!RecordRTC) return; const mediaConstraints = { video: false, audio: true }; const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints); const options = { mimeType: "audio/wav", numberOfAudioChannels: 1, }; const record = new RecordRTC(stream, options); record.startRecording(); setRecordRtc(record); }; return ( <button onClick={startRecording} disabled={!RecordRTC}>开始录音</button> ); } export default YourComponent;
方法B:动态导入使用RecordRTC的组件
将使用RecordRTC的组件单独拆分,通过next/dynamic禁用SSR:
// pages/record-page.js import dynamic from 'next/dynamic'; const RecordComponent = dynamic(() => import('../components/RecordComponent'), { ssr: false, loading: () => <p>加载中...</p> }); export default function RecordPage() { return <RecordComponent />; }
方案2:修改RecordRTC库代码
直接修改node_modules/recordrtc/RecordRTC.js第1586行的代码,避免直接赋值只读的global.navigator:
将原代码:
global.navigator = { userAgent: browserFakeUserAgent, getUserMedia: function() {} };
替换为:
// 仅在非浏览器环境且navigator存在时,修改其属性而非覆盖整个对象 if (typeof window === 'undefined' && typeof global.navigator !== 'undefined') { Object.defineProperty(global.navigator, 'userAgent', { value: browserFakeUserAgent, writable: true }); Object.defineProperty(global.navigator, 'getUserMedia', { value: function() {}, writable: true }); }
注意:这种修改会在依赖重新安装后失效,建议使用patch-package工具将修改保存为补丁,以便后续安装时自动应用。
内容的提问来源于stack exchange,提问作者Yatin Choudhary
相关产品推荐
相关产品推荐

