Установите переменную среды узла в динамическое значение в скрипте npm - PullRequest
0 голосов
/ 05 сентября 2018

Я бы хотел динамически установить переменную окружения в скрипте npm.

Я использую cross-env, так как я разрабатываю для Windows, а сервер работает на 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? Или это невозможно?

Ответы [ 4 ]

0 голосов
/ 21 марта 2019

Я использую простой скрипт узла для передачи переменных окружения в вызываемый скрипт. Он использует 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"}
0 голосов
/ 05 сентября 2018

Я бы создал собственный сценарий 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 для заполнения переменных окружения им (с ) документация ):

// 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
});
0 голосов
/ 05 сентября 2018

Только для записи, я сейчас использую следующий подход: записать текущую дату в пользовательское свойство в package.json и прочитать это значение в приложении, импортировав package.json

package.json

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

ДОПОЛНЕНО 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 для предотвращения локальных изменений каждый раз.

0 голосов
/ 05 сентября 2018

В этом конкретном случае вам лучше использовать команду оболочки вместо JavaScript, поэтому она должна выглядеть примерно так:

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