You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React SSR开发中document未定义错误的解决方法咨询

解决React SSR中"document is not defined"错误

问题根源

你遇到的错误来自style-loader——这个loader的作用是在浏览器环境下将CSS插入到document的<style>标签中,但Node服务端环境不存在document对象,因此执行时抛出错误。

解决方案

1. 替换服务端的CSS处理Loader

修改webpack.server.js中的CSS规则,移除依赖浏览器环境的style-loader,改用服务端兼容的处理方式:

方案A:使用css-loader/locals(适合CSS Modules场景)

将原CSS规则替换为:

{
  test: /\.css$/,
  use: ['css-loader/locals']
}

该方式会将CSS转换为模块化的类名映射,不涉及DOM操作,适合服务端打包。

方案B:使用mini-css-extract-plugin提取独立CSS文件

这种方式会将CSS提取为单独的文件,服务端渲染时可以将CSS链接插入到HTML模板的<head>中,既避免DOM操作,又能保证样式正常加载。

  • 首先安装插件:
npm install mini-css-extract-plugin --save-dev
  • 修改webpack.server.js:
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 引入插件

module.exports = {
    entry: './server/index.js',
    target: 'node',
    externals: [nodeExternals()],
    output: {
      path: path.resolve('server-build'),
      filename: '[name].js',
      chunkFilename: '[id].[chunkhash].js'
    },
    plugins: [ // 添加插件配置
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash].css'
        })
    ],
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader'] // 替换style-loader为插件的loader
            },
            {
                test: /\.(jpg|png|gif|woff|woff2|eot|ttf|svg)$/,
                use: {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]'
                    }
                }
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.jsx', '*']
    },
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test: /node_modules/,
                    name: 'vendor',
                    chunks: 'initial',
                    enforce: true
                }
            }
        }
    }
};
  • 在服务端渲染的HTML模板中,添加生成的CSS文件链接:
    比如你的服务端渲染代码中,生成HTML时可以加入:
<link rel="stylesheet" href="/server-build/main.[contenthash].css">

2. 排查组件中的直接DOM操作

如果你的React组件中直接使用了document(比如在组件初始化时操作DOM),需要添加环境判断,确保只在浏览器环境执行:

import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // useEffect仅在浏览器环境执行,这里可以安全使用document
    const element = document.getElementById('some-id');
    if (element) {
      // 执行DOM操作
    }
  }, []);

  // 或者直接判断环境
  if (typeof document !== 'undefined') {
    // 浏览器环境下的操作
  }

  return <div>...</div>;
}

内容的提问来源于stack exchange,提问作者user19434921

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:50:45