reactjs GraphQL仅在同时运行localhost且Apollo客户端设置为localhost only时才能在生产环境中工作

lx0bsm1f  于 2023-02-22  发布在  React
关注(0)|答案(1)|浏览(137)

我在前端使用react,在apollo/client和graphql上运行一个应用程序,它在本地主机上运行得很好,但是当我部署到heroku上时,只有当我在本地主机上运行这个应用程序时,它才能运行。

const client = new ApolloClient({
  uri: 'http://localhost:5000/graphql',
  cache: new InMemoryCache(),
});

我尝试设置uri localhost,然后如果在生产中将其设置为heroku:

let uri = http://localhost:5000/graphql
if (process.env.NODE_ENV === 'production') {
   uri = https://denver-judo.herokuapp.com/graphql
}

我还尝试了uri = https://denver-judo.herokuapp.com/${PORT}/graphql,但没有任何效果。
这是我的app.js文件

import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import { useState } from 'react';
import {
  Route,
  Routes,
  BrowserRouter as Router,
  Outlet,
} from 'react-router-dom';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import HomeScreen from './screens/HomeScreen';
import Container from 'react-bootstrap/Container';
import Navbar from 'react-bootstrap/Navbar';
import Nav from 'react-bootstrap/Nav';
import { LinkContainer } from 'react-router-bootstrap';
import Button from 'react-bootstrap/Button';
import AboutScreen from './screens/AboutScreen';
import AdminScreen from './screens/AdminScreen';

// Construct main GraphQL API endpoint
let uri = 'http://localhost:5000/graphql';
if (process.env.NODE_ENV === 'production') {
  uri = `https://denver-judo.herokuapp.com/api/graphql`;
}
console.log(process.env.NODE_ENV);
console.log(uri);
const client = new ApolloClient({
  uri: uri,
  cache: new InMemoryCache(),
});
function App() {
  const location = window.location.pathname;
  const [sidebarIsOpen, setSidebarIsOpen] = useState(false);

  return (
    <ApolloProvider client={client}>
      <Router>
        <div
          className={
            sidebarIsOpen
              ? 'site-container active-cont d-flex flex-column'
              : 'site-container d-flex flex-column'
          }
        >
          <ToastContainer position="top-center" limit={1} />
          <header>
            <Navbar
              expand="lg"
              className={`navbar navbar-dark ${
                location === '/' ? 'navbar-custom' : 'navbar-custom-light'
              }`}
            >
              <Container>
                <LinkContainer to="/">
                  <Navbar.Brand>
                    <img
                      className="ms-4"
                      src={
                        location === '/'
                          ? 'assets/img/DJ-logo-black.png'
                          : 'assets/img/DJ-logo-white.png'
                      }
                      alt="Denver Judo"
                      style={{ width: '60px' }}
                    />{' '}
                  </Navbar.Brand>
                </LinkContainer>
                <h1
                  className={
                    location === '/'
                      ? 'navTitle-dark text-center'
                      : 'navTitle text-center'
                  }
                >
                  Denver Judo
                </h1>

                <Button
                  style={{
                    backgroundColor: location === '/' ? '#d9d9d9' : '#262626',
                  }}
                  onClick={() => setSidebarIsOpen(!sidebarIsOpen)}
                  className="me-4"
                >
                  <i
                    className="fa fa-bars fa-lg"
                    style={{
                      color: location === '/' ? '#262626' : '#d9d9d9',
                    }}
                  ></i>
                </Button>
              </Container>
            </Navbar>
          </header>
          <div
            className={
              sidebarIsOpen
                ? 'active-nav side-navbar d-flex justify-content-between flex-wrap flex-column'
                : 'side-navbar d-flex justify-content-between flex-wrap flex-column'
            }
          >
            <Nav className="flex-column text-white w-100 p-2">
              <Nav.Item>
                <strong>Denver Judo</strong>
              </Nav.Item>
              <LinkContainer to="/" onClick={() => (this.expand = '')}>
                <Nav.Link
                  className={
                    location === '/' ? 'nav-text nav-text-bold' : 'nav-text'
                  }
                >
                  Home
                </Nav.Link>
              </LinkContainer>
              <LinkContainer to="/schedule" onClick={() => (this.expand = '')}>
                <Nav.Link
                  className={
                    location === '/schedule'
                      ? 'nav-text nav-text-bold'
                      : 'nav-text'
                  }
                >
                  Schedule
                </Nav.Link>
              </LinkContainer>
              <LinkContainer to="/about" onClick={() => (this.expand = '')}>
                <Nav.Link
                  className={
                    location === '/about'
                      ? 'nav-text nav-text-bold'
                      : 'nav-text'
                  }
                >
                  About
                </Nav.Link>
              </LinkContainer>
            </Nav>
            <Outlet />
          </div>
          <main>
            <Routes>
              <Route index element={<HomeScreen />} />
              <Route path="/about" element={<AboutScreen />} />
              <Route path="_admin/*" element={<AdminScreen />} />
            </Routes>
          </main>
          <footer>
            <div className="text-center">
              Denver Judo
              <br />
              All rights reserved
            </div>
          </footer>
        </div>
      </Router>
    </ApolloProvider>
  );
}

export default App;

下面是来自后端的server.js:

const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const path = require('path');
const dotenv = require('dotenv');
const { typeDefs, resolvers } = require('./schemas');
const db = require('./config/connection');
require('dotenv');

dotenv.config();

const PORT = process.env.PORT || 5000;
const app = express();

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

console.log(process.env.NODE_ENV);
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, '../client/build')));

  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../client/build/index.html'));
  });
}

// Create a new instance of an Apollo server with the GraphQL schema
const startApolloServer = async (typeDefs, resolvers) => {
  await server.start();
  server.applyMiddleware({ app });

  db.once('open', () => {
    app.listen(PORT, () => {
      console.log(`API server running on port ${PORT}!`);
      console.log(
        `Use GraphQL at http://localhost:${PORT}${server.graphqlPath}`
      );
    });
  });
};

// Call the async function to start the server
startApolloServer(typeDefs, resolvers);
pengsaosao

pengsaosao1#

看起来你正在尝试访问但是没有设置/api/graphql路径。另外apollo-server-express库已经过时了。我建议你遵循迁移到Apollo Server 4指南,该指南强调了如何使用app.use设置graphql路径。否则默认的graphql路径在v3中是/。在v4中是/graphql
在v4中,它是这样设置的:

app.use(
  '/graphql',
  cors<cors.CorsRequest>(),
  json(),
  expressMiddleware(server, {
    context: async ({ req }) => ({ token: req.headers.token }),
  }),
);

相关问题