在npm脚本中将节点环境变量设置为动态值

时间:2018-09-04 21:31:16

标签: node.js npm create-react-app npm-scripts

我想在npm脚本中动态设置环境变量。

在Windows上开发时,我正在使用cross-env,并且服务器是基于Unix的。我想用当前日期(new Date())初始化一个环境变量,以便可以在我的create-react-app中访问和呈现它:

这有效(硬编码字符串):

"scripts": {
  "start": "cross-env-shell REACT_APP_BUILD_DATE=\"currentDate\" react-scripts-ts start",
}

很显然,currentDate不应是字符串,而应是以下表达式的结果:new Date()

我该如何实现?换句话说:如何评估一些常规JavaScript并将其结果用于npm脚本?还是不可能?

5 个答案:

答案 0 :(得分:0)

在这种特殊情况下,最好使用shell命令而不是JavaScript,因此应该类似于以下内容:

"scripts": {
  "start": "cross-env-shell REACT_APP_BUILD_DATE=$(date '+%F %H:%M:%S') react-scripts-ts start",
}

答案 1 :(得分:0)

我会为您创建一个自定义的javascript脚本:

execute.js

var spawn = require('child_process').spawn;

// because first arg will actually be something like "./execute.js"
// this is the "regular javascript" you want to evaluate
var arg1 = process.argv[1];
// so lets eval it
var res = eval(arg1);
// this is the remaining args, that is the command you want to run (and its args)
var command = process.argv[2];
var commandArgs = process.argv.slice(3);
// if arg1 evaluation resulted in a value, append this value to the list of args
if (res) {
    commandArgs.push(res);
}
// execute the command
var prc = spawn(command, commandArgs);

,您的脚本定义将变为:

"scripts": {
    "start": "cross-env-shell ./execute.js \"process.env.REACT_APP_BUILD_DATE = new Date();\" react-scripts-ts start",
}

或类似的东西。

这未经测试,但是应该让您开始使用“ 评估一些常规JavaScript并将其结果用作npm脚本

的解决方案。

但是,如果只想在env变量中设置日期,则@bredikhin的解决方案会更好。

处理环境变量的替代解决方案

如果您有能力(手动或以编程方式)写入项目根目录下的.env文件,则可以使用dotenv来填充环境变量(来自{{3 }}文档):

// Usage
// As early as possible in your application, require and configure dotenv.

require('dotenv').config()
/* Create a .env file in the root directory of your project. Add environment-specific variables on new lines in the form of NAME=VALUE. For example:

DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
That's it.

process.env now has the keys and values you defined in your .env file.
*/
const db = require('db');
db.connect({
    host: process.env.DB_HOST,
    username: process.env.DB_USER,
    password: process.env.DB_PASS
});

答案 2 :(得分:0)

仅作记录,我现在使用以下方法:将当前日期写入package.json中的自定义属性,并通过导入package.json

在应用程序中读取该值

package.json

"scripts": {
  "start": "react-scripts-ts start",
  "build": "node ./update-packagejson.js && react-scripts-ts build"
}

update-packagejson.js

const fs = require("fs");
const filePath = "./package.json";

const packageJson = JSON.parse(fs.readFileSync(filePath).toString());
packageJson.ngrvd.buildDate = new Date().toUTCString();

fs.writeFileSync(filePath, JSON.stringify(packageJson, null, 2));

组件

import { ngrvd, version } from "../../package.json";

// ... 

private static getAppInfo(): string {
  const buildDate = process.env.NODE_ENV === "development" ? new Date() : ngrvd.buildDate;
  return "Version " + version + "  - Built " + moment(buildDate).fromNow();
}

这适用于任何环境,简单易懂,可以扩展为还包含其他信息。在开发人员模式下,我不会写package.json来防止每次都进行本地更改。

答案 3 :(得分:0)

我正在使用简单的节点脚本将环境变量传递到称为脚本的脚本中。它使用child_process.execSync。

// File name: ./build.js
/* eslint-env node */
const execSync = require('child_process').execSync;
const env = Object.create(process.env);

env.REACT_APP_BUILD_DATE= Date.now();

console.log('Used env variables: ' + JSON.stringify(env));
console.log('Run command: react-scripts start');
execSync('react-scripts-ts start', { env: env, stdio: 'inherit' });

在package.json脚本中更新启动命令。像这样:

"scripts": {"start": "node ./build.js"}

答案 4 :(得分:0)

例如,您想将构建时间用于 reactjs 应用程序。像这样编辑 package.json

"scripts": {
    "start": "REACT_APP_BUILD_TIME=$(date +%s) react-app-rewired start",
    "build": "REACT_APP_BUILD_TIME=$(date +%s) react-app-rewired build"
}

您可以在 REACT_APP_BUILD_TIME 文件中使用 public/index.html 变量。例如:

<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico?%REACT_APP_BUILD_TIME%" />

您必须用 % 字符包装 env 变量。还有另一个规则:您必须将 REACT_APP_ 添加到您的 env 变量中。您不能添加其他环境变量来响应应用程序。

如何将所有 .env 变量添加到 reactjs 应用程序中?

您可以为此使用 env-cmd 包。

yarn add env-cmd

"scripts": {
    "start": "REACT_APP_BUILD_TIME=$(date +%s) ./node_modules/.bin/env-cmd react-app-rewired start",
    "build": "REACT_APP_BUILD_TIME=$(date +%s) ./node_modules/.bin/env-cmd react-app-rewired build"
}

示例 .env 内容:

REACT_APP_NAME="My React App"
REACT_APP_API_ENDPOINT=https://127.0.0.1:8080/api
REACT_APP_SOCKETIO_ENDPOINT=http://127.0.0.1:3333

之后,您可以将这些变量添加到您的 public/index.html 文件中,如下所示:

<script>
  window.env.REACT_APP_NAME = "%REACT_APP_NAME%";
  window.env.REACT_APP_API_ENDPOINT = "%REACT_APP_API_ENDPOINT%";
  window.env.REACT_APP_SOCKETIO_ENDPOINT = "%REACT_APP_SOCKETIO_ENDPOINT%";
</script>

在 reactjs 方面,您可以像这样使用这些变量:

alert(window.env.REACT_APP_SOCKETIO_ENDPOINT);

仅此而已。

编辑:通常没有这个属性:window.env,但我们现在设置它以便于使用。您可以将环境变量分配到 index.html 文件中的任何位置。