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

React 16.3.2集成Fly软件时遇window未定义错误求助

解决React与Fly集成时的window is not defined错误

嘿,我来帮你拆解这个问题!首先得搞清楚为什么会出现这个错误:

错误原因

Fly的运行环境是Node.js/边缘计算服务端环境,这里没有浏览器特有的window、document这些全局对象。而你原来的代码(不管是直接运行ReactDOM.render还是把它放到fly.http.respondWith里),都是在Fly的服务端上下文执行的——这就相当于在服务器上试图调用浏览器才有的API,自然会报错。

React的ReactDOM.render是专门用来在客户端浏览器里渲染组件的,它依赖浏览器提供的DOM环境;而Fly的脚本是用来处理HTTP请求、返回响应的服务端逻辑,两者的运行环境完全不同。


解决方案:分两种场景处理

场景1:把React应用作为静态资源托管(适合新手,简单直接)

这种方式下,Fly只负责托管你的React静态文件(HTML、打包后的JS/CSS),React代码在用户的浏览器里运行,和普通的静态网站一样。

步骤1:调整Webpack配置
修改你的webpack.fly.config.js,确保输出路径和publicPath正确:

const path = require("path"); 
const webpack = require("webpack"); 
const bundlePath = path.resolve(__dirname, "dist/"); 

module.exports = {
  entry: "./src/index.js",
  module: {
    rules: [
      { 
        test: /\.(js|jsx)$/, 
        exclude: /(node_modules|bower_components)/, 
        loader: 'babel-loader', 
        query: { presets: ['react']} 
      }, 
      { 
        test: /\.css$/, 
        use: [ 'style-loader', 'css-loader' ] 
      } 
    ] 
  },
  resolve: { extensions: ['*', '.js', '.jsx'] },
  output: {
    path: bundlePath, // 新增:指定打包文件输出到dist目录
    publicPath: '/dist/', // 修改为绝对路径,方便HTML引用
    filename: "bundle.js" 
  },
  // devServer是本地开发用的,Fly部署时不需要,可以注释掉
  // devServer: { 
  //   contentBase: path.join(__dirname,'public'), 
  //   port: 3000, 
  //   publicPath: "http://localhost:3000/dist" 
  // },
  plugins: [ new webpack.HotModuleReplacementPlugin() ] 
};

步骤2:修正HTML的脚本引用
修改public/index.html里的script标签,用绝对路径引用打包后的JS:

<script src="/dist/bundle.js"></script>

步骤3:编写Fly的服务端脚本(新建一个fly.js作为入口)
这个脚本的作用是处理HTTP请求,返回对应的静态文件:

fly.http.respondWith(async (req) => {
  const url = new URL(req.url);
  
  // 根路径返回index.html
  if (url.pathname === "/") {
    try {
      const htmlContent = await fly.filesystem.read("public/index.html");
      return new Response(htmlContent, {
        headers: { "Content-Type": "text/html; charset=utf-8" }
      });
    } catch (err) {
      return new Response("无法加载首页", { status: 500 });
    }
  }

  // dist目录下的静态资源(JS/CSS)
  if (url.pathname.startsWith("/dist/")) {
    const filePath = url.pathname.slice(1); // 去掉开头的/,变成dist/bundle.js
    try {
      const fileContent = await fly.filesystem.read(filePath);
      // 根据文件后缀设置Content-Type
      let contentType = "text/plain";
      if (filePath.endsWith(".js")) contentType = "application/javascript";
      if (filePath.endsWith(".css")) contentType = "text/css";
      
      return new Response(fileContent, {
        headers: { "Content-Type": contentType }
      });
    } catch (err) {
      return new Response("资源不存在", { status: 404 });
    }
  }

  // 其他路径返回404
  return new Response("页面不存在", { status: 404 });
});

步骤4:打包并部署

  1. 运行webpack --config webpack.fly.config.js打包React代码到dist目录
  2. 确保你的Fly项目目录包含:public/、dist/、fly.js、package.json
  3. 用fly deploy部署即可

场景2:服务端渲染(SSR,进阶用法)

如果想要在Fly的服务端渲染React组件,再把HTML返回给客户端,可以用ReactDOMServer的renderToString方法,同时客户端做hydrate(复用服务端渲染的DOM)。

示例Fly脚本(fly.js):

import React from 'react';
import ReactDOMServer from 'react-dom/server';

// 服务端渲染组件
const App = () => <h1>Hello, world!</h1>;

fly.http.respondWith(async (req) => {
  // 生成组件的HTML字符串
  const appHtml = ReactDOMServer.renderToString(<App />);
  
  // 拼接完整的HTML页面
  const fullHtml = `
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>React SSR on Fly</title>
      </head>
      <body>
        <div id="root">${appHtml}</div>
        <script src="/dist/bundle.js"></script>
      </body>
    </html>
  `;
  
  return new Response(fullHtml, {
    headers: { "Content-Type": "text/html; charset=utf-8" }
  });
});

客户端React代码(src/index.js):

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => <h1>Hello, world!</h1>;

// 用hydrate替代render,复用服务端渲染的DOM
ReactDOM.hydrate(
  <App />,
  document.getElementById('root')
);

这种方式需要确保Fly环境安装了React和ReactDOM依赖,同时Webpack打包客户端代码的配置正确。


总结

作为React和Webpack新手,推荐先从**场景1(静态资源托管)**入手,这种方式更简单,符合你对React应用的常规认知。等你熟悉了React和Fly的运行机制后,再尝试SSR的进阶用法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:49:27