Vite配置SSR时如何正确处理客户端和服务器端的模块分离?

端木蕴轩 阅读 38

我在用 Vite 搭建 SSR 项目时,发现有些模块只能在客户端运行(比如用到 window 对象),但构建时服务端也会尝试打包这些代码,导致报错。我试过用 import.meta.env.SSR 判断环境,但似乎在构建阶段就出错了。

比如下面这段代码,在服务端渲染时就会报 ReferenceError: window is not defined

export function useClientOnlyHook() {
  if (import.meta.env.SSR) return;
  const width = window.innerWidth; // 服务端没有 window
  return width;
}
我来解答 赞 9 收藏
二维码
手机扫码查看
1 条解答
Good“春光
用动态import把依赖window的代码抽离出来,Vite会自动把它放到客户端chunk里,服务端构建时根本不会碰到:

// 懒人方案
export async function useClientOnlyHook() {
if (import.meta.env.SSR) return null;

// 这行代码只在客户端执行,服务端构建时直接跳过
const { getWidth } = await import('./client-only-util');
return getWidth();
}


或者更简单——用Vue/React的话,把这类逻辑放 onMounteduseEffect 里,SSR自动不会执行:

import { ref, onMounted } from 'vue'

export function useClientOnlyHook() {
const width = ref(0)

onMounted(() => {
width.value = window.innerWidth
})

return width
}


根本原因就是Vite构建时会把所有import都打包进去,你得让那些"危险import"变成运行时才加载的动态import,build阶段就找不到window了。
点赞
2026-03-16 23:19