首页 > 解决方案 > 在开发期间从 Create React App 中的本地主机服务器获取与在生产期间从部署获取

问题描述

这是我正在使用 nodemailer 在其中实现联系表单的个人投资组合页面。

nodemailer 的东西都是从服务器端设置的。我只需要一些关于将客户端发布请求指向开发和部署的正确位置的建议。

我想为生产与开发设置环境变量并基于此进行获取。现在我只是想知道如何去寻找我要放入生产中的任何东西。

会不会只是指向我自己的应用程序: fetch(www.mydomain.com/send-email, data) ...

我在 Heroku 文档中试图解决这个问题。

基本上,我有一个巨大的盲点,它来自 Create React App 的服务器 API,它不是在 localhost:3000 上独立启动的。我还没有从我的客户端访问未在本地主机上本地提供的服务器路由。当我将它推送到 Heroku 时,我需要有正确的路由或配置,我需要一些关于如何执行此操作的建议。

我对代理有所了解。只是想知道在部署期间从部署在 Heroku 上的客户端/服务器而不是 localhost:3000 正确访问我的服务器路由的步骤是什么。

当我在开发中时,我几乎总是 axios.post 一个我在 localhost:3000 上启动的服务器,然后我从我的客户那里得到了这样的东西。

axios.post('localhost:3000/send-email', data)
      .then( () => {
        setSent(true) 
      })
      .then(() => {
        resetForm()
      })
      .catch((err)=> {
        console.log('Message not sent', err)
      })
  }

...然后由在 localhost:3000 上侦听的 express 服务器上的端点处理,这看起来有点像我在下面粘贴的内容。

const express = 
  require('express'), 
  bodyParser = require('body-parser'), 
  nodemailer = require('nodemailer'), 
  cors = require('cors'), path = require('path'), 
  port = process.env.PORT || 3000, publicPath = path.join(__dirname, '..', 'build');
require('dotenv').config();
const app = express();

app.use(cors());
app.use(express.static(publicPath));

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

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

app.post('/send-email', (req, res) => {
  console.log('request: ', req.body)
  let data = req.body;
  let transporter = nodemailer.createTransport({
    service: 'gmail',
    port: 465,
    auth: {
      user: process.env.EMAIL,
      pass: process.env.PASSWORD
    }
  });

  let mailOptions = {
    from: data.email,
    to: process.env.EMAIL,
    subject: `${data.subject}`,
    html: `<p>${data.name}</p>
            <p>${data.email}</p> 
            <p>${data.message}</p>`
  };

  transporter.sendMail(mailOptions,
  (err, res) => {
    if(err) {
      res.send(err)
    } else {
      res.send('Success')
    }
    transporter.close();
  });
})

app.listen(port, () => {
  console.log(`Server is up on port ${port}!`);
});

文件夹结构是这样的:

main
 |-server
  |-server.js
 |-src
  |-components
    |-Contact.js

标签: reactjsexpressfetchcreate-react-appnodemailer

解决方案


使用process.env.NODE_ENV变量来区分环境。

当你运行时npm start,它总是等于'development',当你运行时npm test它总是等于'test',当你运行npm run build来制作一个生产包时,它总是等于'production'您不能NODE_ENV手动覆盖。

因此,您可以创建和导出一个函数,如

export function apiDomain() {
    const production = process.env.NODE_ENV === 'production'
    return production ? 'anotherDoman' : 'localhost:3000'
}

或者,根据您的要求

export function apiDomain() {
    const { protocol, hostname, origin } = window.location
    return hostname === 'localhost' ? `${protocol}//${hostname}` : origin
}

有关更多详细信息,请查看https://create-react-app.dev/docs/adding-custom-environment-variables/


推荐阅读