在运行时检测React的生产环境和开发环境

202

在运行时是否可能检测当前版本的React是开发版还是生产版? 我想做这样的事情:

if (React.isDevelopment) {
  // Development thing
} else {
  // Real thing
}
6个回答

317

最好的方法是使用构建工具webpack、browserify来模拟Node的方式,通过暴露process.env.NODE_ENV。通常情况下,在生产环境中它被设置为"production",在开发环境中被设置为"development"(或未定义)。

因此,您的代码应该是:

```javascript if(process.env.NODE_ENV === 'production'){ // 生产环境下的代码 } else { // 开发环境下的代码(或者未定义) } ```
if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
    // dev code
} else {
    // production code
}

如何设置,请参见envify在webpack中传递依赖于环境的变量


16
客户端出现“process is not defined”错误。 - trusktr
6
你需要使用像webpack这样的构建工具。 - David L. Walsh
30
如果你正在使用 create-react-app,那么在开发模式下 process.env.NODE_ENV 的值将为 "development"。 - Joseph238
6
补充 @Joseph238 的评论 - 使用 create-react-app 时,process.env.NODE_ENV 会为您定义,并且您可以在应用程序的任何位置访问它。 详见 React 文档 - Shawn
1
@Joseph238 @ShaungCheng 我刚刚使用最新的脚本使用 create-react-app 创建了一个全新的应用程序,但是 process.env 没有一个名为 NODE_ENV 的变量。 - Can Poyrazoğlu
显示剩余3条评论

29
我使用一个帮助文件(使用TypeScript):

我使用一个助手文件(在TypeScript中):

import process from "process";

const development: boolean = !process.env.NODE_ENV || process.env.NODE_ENV === 'development';

export default function isDev(): boolean
{
    return development;
}

然后在其他地方我会这样使用它:

import isDev from "./helpers/DevDetect";

if (isDev())
{
    ...
}

4
更懒的方法:export const isDev = () => !process.env.NODE_ENV || process.env.NODE_ENV === 'development'; 意思为:判断当前是否处于开发环境,如果不是则返回false,否则返回true。 - Mahdi Hosseini

6

import.meta.env应该是你所需要的一切!

import.meta对象向JavaScript模块公开上下文特定的元数据 了解更多信息

据我所见,这与较新的esmodules导入/导出语法保持一致,因此是读取JS(和Typescript)中环境变量的最新标准。

但是,如果import.meta不可用,则可以在process.env中使用env变量(即老式的commonJS方式)。

console.log(import.meta.env) // ...or process.env

/* dev */
{
  "MODE": "development",
  "DEV": true,
  "PROD": false,

}
/* prod */
{
  "MODE": "production",
  "DEV": false,
  "PROD": true,
}

这意味着你应该可以做类似于以下的事情:

 import.meta.env.MODE;
 // or process.env.MODE;

注意:env对象内的值取决于你使用哪种构建工具来运行你的应用程序。

// create-react-app
{
  "NODE_ENV": "development",
  "PUBLIC_URL": "",
  "FAST_REFRESH": true
}

// vite-app
{
  "BASE_URL": "/",
  "MODE": "development",
  "DEV": true,
  "PROD": false,
  "SSR": false
}

// I haven't tested but I'm sure nextJS has it's own env setup

似乎这不是标准的,只是 vite 实现的一种方式。https://github.com/webpack/webpack/issues/15833 - undefined

5

3

如果您在生产环境中有多个环境,例如测试(测试分支)、预发布(预发布分支)和生产(主分支),并使用CICD进行处理。

在这种情况下,process.env.NODE_ENV将在所有3个环境中返回“production”

因此,如果您的情况是这样的,我建议在.env文件中添加一个变量。

.env.production

REACT_APP_ENV = "prod"

.env.staging

REACT_APP_ENV = "staging"

.env.development

REACT_APP_ENV = "development"

为了让您能够在您的工具文件中创建一个函数。
export const isProdMode = (): boolean => {
  if (process.env.REACT_APP_ENV === 'prod') {
    return true;
  }
  return false;
}

1

您无需更改webpack配置 - 只需检查是否已启用js代码的缩小,这只会在生产环境中发生。例如,我使用了这个简单的技巧来禁用日志记录。元素类型名称将被缩小重命名。

    const MyElement = ({isProduction}) => (<div>Environment: {isProduction?'Production':'Development'}</div>);

    const MyElementEl = React.createElement(MyElement);
    const isProduction = (MyElementEl.type.name !== 'MyElement');

    if(isProduction) //will be true when your js sources are minified 
        console = { ...console, logX: console.log, log: () =>{ } };
        
    ReactDOM.render(<MyElement isProduction={isProduction}/>, document.getElementById("app"));
   

 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <body>
    <div id="app" />
    </body>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接