关于creat-react-app中的环境变量

    使用场景:在使用creat-react-app中开发项目中,项目中接口会分为两种情况一种是开发中的测试接口,一种是打包上线后的正式接口。那么怎么判断是开发模式还是线上模式(打包后的项目也就是npm run build)。

    如果自己封装一个函数分别在 react-script中的start.js跟build.js中调用,传不同的两个参数回来,要么就是人性化的的方法每次打包的时候去手动改参数也是可以的,但是这样太麻烦。

    时至今日看creat-react-app官方文档的时候发现人家官方是有这个环节变量的。是不是很蛋疼。官方文档是这样说的

以下部分是官方文档里原文

环境变量是在构建时嵌入的由于Create React App会生成静态HTML / CSS / JS包,因此无法在运行时读取它们。要在运行时读取它们,您需要将HTML加载到服务器的内存中,并在运行时替换占位符,就像这里所述或者,您可以随时在服务器上重建应用程序,以便更改它们。

注意:您必须创建自定义的环境变量REACT_APP_任何其他变量NODE_ENV将被忽略,以避免意外暴露机器上可能具有相同名称的私钥更改任何环境变量将需要您在运行时重新启动开发服务器。

这些环境变量将为您定义process.env例如,拥有一个名为的环境变量REACT_APP_SECRET_CODE将暴露在你的JS中process.env.REACT_APP_SECRET_CODE

还有一个特殊的内置环境变量叫做NODE_ENV你可以阅读它process.env.NODE_ENV当你运行时npm start,它总是等于'development',当你运行npm test它总是等于'test',并且当你运行npm run build生产捆绑时,它总是等于'production'您无法NODE_ENV手动覆盖这可以防止开发人员意外地将缓慢的开发构建部署到生产环境中。

这些环境变量可以用于根据项目的部署位置或使用超出版本控制的敏感数据来有条件地显示信息。

首先,你需要定义环境变量。例如,假设您想要消费在环境中定义的秘密<form>

render(){
   return
    < div >
      < small >您正在< b > { process中运行此应用程序env NODE_ENV } </ b >模式。</ small >
      < form >
        < input  type =  hidden   defaultValue = { process env REACT_APP_SECRET_CODE } />
      </ form >
    </ div >
  );
}

在构建期间,process.env.REACT_APP_SECRET_CODE将被替换为REACT_APP_SECRET_CODE环境变量的当前值请记住,该NODE_ENV变量将自动为您设置。

没错就是 process.env.NODE_ENV 当项目是npm start的时候 process.env.NODE_ENV等于development,当项目npm run build的时等于production当

还有其他的几种模式,比如test等。

那么有了这个环境变量还需要去手动改吗?


如果还不能满足则把下面代码贴进node_modules->react-scripts->config->env.js

// @remove-on-eject-begin
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
// @remove-on-eject-end
'use strict';

const fs = require('fs');
const path = require('path');
const paths = require('./paths');

// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];

const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
  throw new Error(
    'The NODE_ENV environment variable is required but was not specified.'
  );
}

// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
var dotenvFiles = [
  `${paths.dotenv}.${NODE_ENV}.local`,
  `${paths.dotenv}.${NODE_ENV}`,
  // Don't include `.env.local` for `test` environment
  // since normally you expect tests to produce the same
  // results for everyone
  NODE_ENV !== 'test' && `${paths.dotenv}.local`,
  paths.dotenv,
].filter(Boolean);

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
dotenvFiles.forEach(dotenvFile => {
  if (fs.existsSync(dotenvFile)) {
    require('dotenv').config({
      path: dotenvFile,
    });
  }
});

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
const REACT_APP = /^REACT_APP_/i;
const args = process.argv.slice(2);
function getClientEnvironment(publicUrl) {
  const raw = Object.keys(process.env)
    .filter(key => REACT_APP.test(key))
    .reduce(
      (env, key) => {
        const args = process.argv.slice(2);
        process.env.test= args[1]
        env[key] = process.env[key];
        return env;
      },
      {
        // Useful for determining whether we’re running in production mode.
        // Most importantly, it switches React into the correct mode.
        NODE_ENV: process.env.NODE_ENV || 'development',
        Text:args,
        // Useful for resolving the correct path to static assets in `public`.
        // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
        // This should only be used as an escape hatch. Normally you would put
        // images into the `src` and `import` them in code to get their paths.
        PUBLIC_URL: publicUrl,
      }
    );
  // Stringify all values so we can feed into Webpack DefinePlugin
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
       env[key] = JSON.stringify(raw[key]);
      return env;
    }, {
      NODE_ENV: process.env.NODE_ENV || 'production',
      Text:args,
      // Useful for resolving the correct path to static assets in `public`.
      // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
      // This should only be used as an escape hatch. Normally you would put
      // images into the `src` and `import` them in code to get their paths.
      PUBLIC_URL: publicUrl,
    }),
  };

  return { raw, stringified };
}

module.exports = getClientEnvironment;

根目录package.json中的scripts加入新的指令

 "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "startN": "react-scripts start normal",
    "buildN": "react-scripts build normal",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "flow": "flow; test ? -eq 0 -o ? -eq 2"
  },

在你的前端逻辑代码中

console.log(process.env)
分别运行前四个命令,npm start,npm run build,npm run startN,npm run buildN,就会发现通过process.env.NODE_ENV跟 process.env.Text两个值就可以判断出四种模式

开发模式中的测试接口情况,开发模式中的正式接口模式,打包模式下的测试接口模式,打包模式下的正式接口模式。
这样你就可以在你的逻辑代码中去通过判断去知道上述的四种情况


ok完工了不用手动改代码了,只需要在命令行的时候运行不同的指令就ok了








猜你喜欢

转载自blog.csdn.net/weixin_38267121/article/details/80333642
今日推荐