如何处理 SSR 环境下的全局变量?

探讨服务器端渲染中如何管理全局变量如 window,涉及环境检测、变量注入和统一机制。

服务端渲染 困难 SSR 全局变量 服务端

在服务器端渲染(SSR)环境下处理全局变量如 window,主要面临服务端与客户端环境的差异。服务端如 Node.js 没有浏览器专属的全局对象(如 window),直接访问会导致 ReferenceError 错误。常见的解决方案如下:

  1. 环境检测:使用类型检查机制来避免直接访问未定义对象,确保代码兼容性。
    if (typeof window !== 'undefined') {
      window.globalVar = 'some value'; // 仅在客户端设置
    } else {
      // 服务端备用逻辑,例如使用模拟对象或默认值
    }
    
  2. 全局变量注入:在前端框架中通过上下文集对象传递全局变量,而不要硬依赖 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>;
    };
    
  3. 统一机制(如 Hooks 或库)
    • 对像 React 的框架,使用自定义 Hook(如下所述)动态加载全局功能:
      function useWindow() {
        if (typeof window === 'undefined') return { scrollY: 0 };
        return window;
      }
      
    • 使用 libraries,比如 jsdom 在服务端模拟 window 对象。

原因分析:SSR 中的全局变量管理需区分运行时逻辑,服务端数据通过 props 传递;当访问第三方库依赖 window 时,推荐用 Conditional Imports 懒加载逻辑:

if (typeof window !== 'undefined') {
  import('library').then((lib) => lib.init());
}

关键原则是永远避免在服务端运行的代码中出现直接的 window 引用。