如何处理 SSR 环境下的全局变量?
探讨服务器端渲染中如何管理全局变量如 window,涉及环境检测、变量注入和统一机制。
在服务器端渲染(SSR)环境下处理全局变量如 window
,主要面临服务端与客户端环境的差异。服务端如 Node.js 没有浏览器专属的全局对象(如 window
),直接访问会导致 ReferenceError
错误。常见的解决方案如下:
- 环境检测:使用类型检查机制来避免直接访问未定义对象,确保代码兼容性。
if (typeof window !== 'undefined') { window.globalVar = 'some value'; // 仅在客户端设置 } else { // 服务端备用逻辑,例如使用模拟对象或默认值 }
- 全局变量注入:在前端框架中通过上下文集对象传递全局变量,而不要硬依赖
window
。例如在 Next.js 中:// 在 getInitialProps 或 getServerSideProps 中设置 export async function getServerSideProps(context) { const globalVar = 'server-side value'; return { props: { globalVar } }; } // 前端组件通过 props 访问 const MyComponent = ({ globalVar }) => { return <div>{globalVar}</div>; };
- 统一机制(如 Hooks 或库):
- 对像 React 的框架,使用自定义 Hook(如下所述)动态加载全局功能:
function useWindow() { if (typeof window === 'undefined') return { scrollY: 0 }; return window; }
- 使用 libraries,比如
jsdom
在服务端模拟window
对象。
- 对像 React 的框架,使用自定义 Hook(如下所述)动态加载全局功能:
原因分析:SSR 中的全局变量管理需区分运行时逻辑,服务端数据通过 props 传递;当访问第三方库依赖 window
时,推荐用 Conditional Imports 懒加载逻辑:
if (typeof window !== 'undefined') {
import('library').then((lib) => lib.init());
}
关键原则是永远避免在服务端运行的代码中出现直接的 window
引用。