import.meta本身不直接暴露“是否预渲染”标识,但可通过构建工具注入字段(如import.meta.prerender)、环境变量(import.meta.env.SSR)及执行环境特征(无window/document/location)组合判断,避免仅依赖typeof window === 'undefined'等单一信号。

import.meta 本身不直接暴露“是否预渲染”的标识,但可通过结合构建工具、运行时环境特征和约定的元数据来可靠判断。关键在于识别预渲染阶段特有的执行上下文(如无 DOM、无 window、服务端或静态生成器环境),并避免依赖客户端专属 API。
检查全局对象与执行环境特征
预渲染通常发生在无浏览器 DOM 的环境中(如 Vite 预渲染插件、Nuxt、Astro 或自定义 SSR 流程)。可检测以下典型信号:
- window 未定义或 document 为 null/undefined —— 表明不在真实浏览器中
- process?.env?.SSR === 'true' 或类似构建时注入的环境变量(如 import.meta.env.SSR)
- import.meta.env.PROD && !import.meta.env.DEV 配合其他线索,排除开发服务器热更新干扰
利用构建工具注入的元数据(推荐)
现代构建工具支持在预渲染阶段向 import.meta 注入自定义字段。例如:
- Vite 用户可配置 define 选项:
define: { 'import.meta.prerendering': 'true' },然后用 import.meta.prerendering === 'true' 判断 - Nuxt 3 中 import.meta.prerender 是内置布尔值(true 表示当前处于预渲染生命周期)
- Astro 组件内 import.meta.env.SSR 在预渲染时为 true
避免常见误判陷阱
仅靠 typeof window === 'undefined' 不够严谨——Node.js 服务端、Web Worker、甚至某些测试环境也满足该条件。应组合判断:
- 优先使用构建工具明确提供的标识(如 import.meta.prerender),它由框架语义保证
- 若需手动探测,建议同时验证:
– !window?.navigator(无 UA、无 devicePixelRatio)
– !document?.body(DOM 未挂载)
– typeof location === 'undefined'(无浏览器导航上下文) - 不要在模块顶层直接调用 fetch 或访问 localStorage,而应在判断后按需延迟执行
根据环境调整模块行为的实用模式
典型做法是导出一个工厂函数或条件初始化逻辑:
- 数据获取:预渲染时用 fetch(Node 兼容),客户端用 useAsyncData 或 Suspense
- 副作用控制:仅在客户端挂载后初始化第三方 SDK(如 analytics、chat widget)
- 样式/资源:预渲染时跳过动态 insertRule 或 createScript,改用静态 /<script></script> 标签










