【问题标题】:NodeJS: Use environment variables in front end scriptsNodeJS:在前端脚本中使用环境变量
【发布时间】:2013-07-09 02:38:19
【问题描述】:

我正在编写一个 socket.io 应用程序,每次我从

推送到 heroku 时,我都不得不在前端的 scripts.js 文件中添加一行,这让我很恼火
var socket = io.connect('http://localhost');

var socket = io.connect('http://ersatz-elephant-1337.herokuapp.com/');

我知道我可以使用process.env.VAR 在后端访问这些变量,但我想知道是否有任何方法可以以编程方式确定在我的前端脚本中使用哪个变量?除此之外,我宁愿将脚本保留为静态,但也许这是不可能的?

编辑:我并不是真的在后端寻找解决方案......我正在寻找一种方法,我的 /public/scripts.js 文件可以连接到正确的东西。我想也许唯一的方法是在 server.js 中为前端脚本文件指定一些特殊的东西,而不是静态地提供它,但如果是这样,那么这就是我正在寻找的指令,而不是如何实际访问服务器上的环境变量。如有任何混淆,请见谅!

【问题讨论】:

  • 您的问题尚不清楚何时确定要推送到哪个,无论是在执行期间还是在执行前。您是在脚本运行时决定哪条路径还是事先知道?
  • 嗯,预执行。就像它是一个静态文件一样,它只需要在 heroku 上与本地不同。
  • 我个人建议在这种情况下使用运行时参数。我不喜欢使用环境变量,它总是很乱。如果您使用运行时参数,那么您可以随时使用 shell 脚本来利用环境变量。不过,这更像是个人品味。

标签: node.js heroku socket.io localhost environment-variables


【解决方案1】:

很有可能。要么使用foreman,要么使用像这样的配置脚本:

var url = require('url');
var config = {};
var dbUrl;

if (typeof(process.env.DATABASE_URL) !== 'undefined') {
    dbUrl = url.parse(process.env.DATABASE_URL);
}
else {
    dbUrl = url.parse('tcp://postgres:postgres@127.0.0.1:5432/db');
}

config.dialect = 'postgres';
config.protocol = dbUrl.protocol.substr(0, dbUrl.protocol.length - 1); // Remove trailing ':'
config.username = dbUrl.auth.split(':')[0];
config.password = dbUrl.auth.split(':')[1];
config.host = dbUrl.hostname;
config.port = dbUrl.port;
config.database = dbUrl.path.substring(1);

console.log('Using database ' + config.database);
module.exports = config;

【讨论】:

  • 但是 process.env.DATABASE_URL 是在哪里设置的?
  • 在开发中使用 foreman 设置 DATABASE_URL,并通过其他方式在您的生产和 CI 主机上设置。例如,请参阅devcenter.heroku.com/articles/config-vars
【解决方案2】:

我知道您要求使用环境变量的解决方案,但我认为使用运行时参数是更好的解决方案,因为它提供了更好的灵活性。

如上所述,如果您愿意,您可以随时使用 shell 脚本(根据您使用的操作系统)根据环境变量设置运行时参数。

要使用 args,请使用 process.argv。您可以对此执行forEach 并遍历参数(请参阅node.js manual process argv)。我个人会使用一个模块。我喜欢的叫opt。它有很多不错的特性,并且使处理命令行参数变得非常简单。您可以指定默认值,为每个参数定义帮助消息等。它甚至支持配置文件。我想你可能会觉得这很有吸引力。

但是,如果您喜欢 KISS 方法,那么我建议您使用 process.argv

如果您准备在脚本中使用环境变量,那么您始终可以使用process.env.MY_ENV_VARIABLE,其中MY_ENV_VARIABLE 是环境变量(请参阅how to read environment variable in node js)。

【讨论】:

    【解决方案3】:

    我在 2.5 年后才发现这个问题,因为 SO 告诉我它的浏览量达到了 1k。我想我现在解决这个问题的方法是说类似

    var isLocal = ~location.href.indexOf('://localhost');
    

    然后以我的其他变量为基础。它实际上并没有给我环境变量,但它解决了我遇到的问题,即自动知道要使用哪个路径。 (在这种情况下,可能只是说 io.connect('/') 就足够了。)

    【讨论】:

      【解决方案4】:

      一种方法是使用依赖于机器的 conf.js 文件和 env.js 文件。

      .gitignore

      # it depends on the environement
      env.js
      

      conf.js

      import ENV from './env.js'
      const conf = {
        "dev": {
           url: '/'
        },
        "prod": {
           url: 'www.example.com'
        },
        "test": {
           url: 'www.example-test.com'
        }
      }
      export default conf[ENV]
      

      env.js

      // dev
      export default "dev"
      

      env.js

      // prod
      export default "prod"
      

      就是这样。 现在你可以随心所欲地使用它了。

      index.js

      import conf from './conf'
      console.log("my env url is ", conf.url)
      

      你还可以使用 grunt.js 让一切变得更加自动化

      Gruntfile.js

      module.exports = function(grunt) {
        grunt.initConfig({});
        grunt.registerTask("env", function(envValue = 'dev') {
          grunt.file.write(
              "env.js",
              `/* AUTO GENERATED FILE FROM GRUNT */\n
      
              export default envValue;
              `
          );
      });
      
      }
      

      现在您必须更改 package.json 中的脚本

      {
        ...
        "scripts": {
           "build": "node scripts/build.js",
           "buildProd": "npm run grunt env:prod && npm run build",
            "buildTest": "npm run grunt env:test && npm run build"
        }
        ...
      }
      

      然后在命令行运行

      npm run buildProd
      

      【讨论】:

        猜你喜欢
        • 2013-09-14
        • 1970-01-01
        • 1970-01-01
        • 2020-04-05
        • 2017-10-26
        • 1970-01-01
        • 2018-08-03
        • 2019-01-20
        • 2021-06-20
        相关资源
        最近更新 更多