简体   繁体   English

读取环境变量,然后在使用gulp构建prod或dev代码时在客户端JS中替换它们

[英]Read environment variables and then replace them in client-side JS when using gulp for building prod or dev code

So lets say I have some code in js 所以可以说我在js中有一些代码

const myApiKey = 'id_0001'

But instead of harcoding it I want to put it in some bash script with other env vars and read from it and then replace it in the JS 但是我不想将其编码,而是将其与其他env vars放在一些bash脚本中,并从中读取,然后将其替换为JS。

So lets say for prod I would read from prod-env.sh or for dev I would read them from dev-env.sh and then gulp or some other tool does the magic and replaces MY_API_KEY based on whatever is established inside of prod-env.sh or dev-env.sh . 所以可以说,对于prod我将从prod-env.sh读取,对于dev我将从dev-env.sh读取,然后dev-env.sh或其他工具发挥作用,并根据prod-env.sh内部建立的内容替换MY_API_KEY prod-env.shdev-env.sh

const myApiKey = MY_API_KEY

Update: I want to add I only care about unix OS, not concerned about windows. 更新:我想补充一点,我只关心UNIX操作系统,而不关心Windows。 In golang there is way to read for example envVars.get('MY_API_KEY'), I'm looking for something similar but for JS in the client side. 在golang中,有一种方法可以读取例如envVars.get('MY_API_KEY'),我正在寻找类似的东西,但在客户端使用JS。

If you're using gulp, it sounds like you could use any gulp string replacer, like gulp-replace . 如果您使用的是gulp,听起来您可以使用任何gulp字符串替换程序 ,例如gulp-replace

As for writing the gulp task(s). 至于编写gulp任务。 If you are willing to import the environment into your shell first, before running node, you can access the environment via process.env 如果您愿意先将环境导入外壳程序中,则在运行节点之前,可以通过process.env访问环境process.env

gulp.task('build', function(){
  gulp.src(['example.js'])
    .pipe(replace('MY_API_KEY', process.env.MY_API_KEY))
    .pipe(gulp.dest('build/'));
});

If you don't want to import the environment files before running node, you can use a library like env2 to read shell environment files. 如果您不想在运行节点之前导入环境文件,则可以使用env2之类的库来读取Shell环境文件。

Another option would be to use js/json to define those environment files, and load them with require. 另一种选择是使用js / json定义那些环境文件,并使用require加载它们。

prod-env.js PROD-env.js

{
  "MY_API_KEY": "api_key"
}

gulpfile.js gulpfile.js

const myEnv = require('./prod-env')

gulp.task('build', function(){
  gulp.src(['example.js'])
    .pipe(replace('MY_API_KEY', myEnv.MY_API_KEY))
    .pipe(gulp.dest('build/'));
});

Also, for a more generic, loopy version of the replace you can do: 此外,对于更通用的循环替换版本,您可以执行以下操作:

gulp.task('build', function () {
  stream = gulp.src(['example.js']);

  for (const key in process.env) {
    stream.pipe('${' + key + '}', process.env[key]); 
  }

  stream.pipe(gulp.dest('build/'));
});

In that last example I added ${} around the environment variable name to make it less prone to accidents. 在最后一个示例中,我在环境变量名称周围添加了${} ,以减少发生事故的可能性。 So the source file becomes: 因此,源文件变为:

const myApiKey = ${MY_API_KEY}

This answer is an easy way to do this for someone who doesn't want to touch the code they are managing. 对于不想接触他们正在管理的代码的人来说,此答案是一种简便的方法。 For example you are on the ops team but not the dev team and need to do what you are describing. 例如,您是操作团队的成员,而不是开发人员的团队的成员,则需要按照您的描述进行操作。

The environment variable NODE_OPTIONS can control many things about the node.js runtime - see https://nodejs.org/api/cli.html#cli_node_options_options 环境变量NODE_OPTIONS可以控制关​​于node.js运行时的许多事情-请参阅https://nodejs.org/api/cli.html#cli_node_options_options

One such option we can set is --require which allows us to run code before anything else is even loaded. 我们可以设置的一个这样的选项是--require ,它允许我们在加载其他任何东西之前运行代码。

So using this you can create a overwrite.js file to perform this replacement on any non-node_modules script files: 因此,您可以使用此文件创建overwrite.js文件,以对所有非node_modules脚本文件执行此替换:

const fs = require('fs');
const original = fs.readFileSync;

// set some custom env variables
// API_KEY_ENV_VAR - the value to set
// API_KEY_TEMPLATE_TOKEN - the token to replace with the value

if (!process.env.API_KEY_TEMPLATE_TOKEN) {
  console.error('Please set API_KEY_TEMPLATE_TOKEN');
  process.exit(1);
}

if (!process.env.API_KEY_ENV_VAR) {
  console.error('Please set API_KEY_ENV_VAR');
  process.exit(1);
}

fs.readFileSync = (file, ...args) => {
  if (file.includes('node_modules')) {
    return original(file, ...args);
  }
  const fileContents = original(file, ...args).toString(
    /* set encoding here, or let it default to utf-8 */
  );
  return fileContents
    .split(process.env.API_KEY_TEMPLATE_TOKEN)
    .join(process.env.API_KEY_ENV_VAR);
};

Then use it with a command like this: 然后将其与以下命令一起使用:

export API_KEY_ENV_VAR=123;
export API_KEY_TEMPLATE_TOKEN=TOKEN;
NODE_OPTIONS="--require ./overwrite.js" node target.js

Supposing you had a script target.js 假设您有一个脚本target.js

console.log('TOKEN');

It would log 123. You can use this pretty much universally with node, so it should work fine with gulp, grunt, or any others. 它将记录为123。您可以在node上将其普遍使用,因此它可以与gulp,grunt或其他任何设备一起正常使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM