【问题标题】:How to use environment variables in package.json如何在 package.json 中使用环境变量
【发布时间】:2016-04-11 13:41:36
【问题描述】:

因为我们不希望项目代码中包含敏感数据,包括 package.json 文件,所以我认为使用环境变量是一个合乎逻辑的选择。

示例 package.json:

  "dependencies": {
    "accounting": "~0.4.0",
    "async": "~1.4.2",
    "my-private-module":"git+https://${BB_USER}:${BB_PASS}@bitbucket.org/foo/bar.git"

这可能吗?

问题是不是如果这是明智不好,只是如果可能。 p>

【问题讨论】:

    标签: node.js heroku npm package.json


    【解决方案1】:

    如果您使用.env 文件,让我们使用grepeval 从 .env 文件中获取值环境变量。

    按照@Paul 的建议更新了start2

    "scripts": {
        "start": "NODE_ENV=$(grep NODE_ENV .env | cut -d '=' -f2) some_script",
        "start2": "eval $(grep '^NODE_ENV' .env) && some_script"
    }
    

    【讨论】:

    • 这应该是置顶评论,因为它完美地解决了这个问题。
    • 我一直在使用它,但是当您开始在多个地方使用它时,它会变得非常冗长。有没有图书馆可以缩短这个时间?
    • 这太棒了,谢谢。它适用于“脚本”。不幸的是,它在“配置”中不起作用,这将非常有用。知道为什么吗?
    • 您也可以将其缩短为eval $(grep '^NODE_ENV' .env) && some_script
    • 这有两个问题。 1:问题是关于依赖关系,而不是脚本。脚本在 shell 中运行,因此在脚本中使用环境变量与在常规 package.json 值中使用环境变量非常不同。 2:(也许我在这里遗漏了一些东西,但是)通过 grep 获取环境变量的值似乎只是做$NODE_ENV 的一种复杂方法。此外,如果NODE_ENV 已经定义为环境变量,则不需要重新定义。似乎它只是让您免于执行 source .env (您可以使用 direnv 之类的东西自动为您执行此操作)。
    【解决方案2】:

    我有类似但不同的要求。对我来说,我想在脚本中使用环境变量。

    我没有直接在 package.json 中使用环境变量,而是这样做:

    "some-script": "./scripts/some-script.sh",
    

    在 some-script.sh 中:

    #!/bin/sh
    
    npm run some-other-script -- --prop=$SOME_ENV_VAR
    

    【讨论】:

    • 你能告诉你如何在some-other-script中访问prop吗?
    • 已经有一段时间了。你能在这里按照投票最高的答案来看看这是否有效吗? stackoverflow.com/questions/5499472/…
    【解决方案3】:

    不,这是不可能的。您应该使用git+ssh 访问repo,并将私钥存储在~/.ssh

    然后你的行看起来像:

    "my-private-module":"git+ssh://git@bitbucket.org/foo/bar.git"
    

    其中不包含任何敏感内容。

    【讨论】:

    • 此外,您甚至可以为此目的使用不同的 ssh 密钥和 ssh 配置,而不是通常的 id_rsa。
    • 是的,我建议这样做。 (我的意思是用“存储 a 私钥”,但可能更清楚。)
    • 谢谢!是的,它是 Heroku :-S。所以我猜应该是一个自定义构建包。我认为 Docker 最终将成为终极环境。需要这样做!问候!
    • 这个 .npmrc 能够解释环境变量!但无法结合,我认为无法将其用于这些目的......
    【解决方案4】:

    以下是我设法解决package.json 以实现相同目的的方法。它使用从package.json 的自定义部分读取URL 模块的脚本,在其中插入环境变量,并使用npm install --no-save 安装它们(--no-save 可以省略,具体取决于用例)。

    作为奖励:它尝试从 .env.json 读取 env 变量,这可以是 gitignore 的,对开发非常有用。

    1. 创建将从package.json 的自定义部分读取的脚本

    env-dependencies.js

    const execSync = require('child_process').execSync
    const pkg = require('./package.json')
    
    if (!pkg.envDependencies) {
      return process.exit(0)
    }
    
    let env = Object.assign({}, process.env)
    
    if (typeof pkg.envDependencies.localJSON === 'string') {
      try {
        Object.assign(env, require(pkg.envDependencies.localJSON))
      } catch (err) {
        console.log(`Could not read or parse pkg.envDependencies.localJSON. Processing with env only.`)
      }
    }
    
    if (typeof pkg.envDependencies.urls === 'undefined') {
      console.log(`pkg.envDependencies.urls not found or empty. Passing.`)
      process.exit(0)
    }
    
    if (
      !Array.isArray(pkg.envDependencies.urls) ||
      !(pkg.envDependencies.urls.every(url => typeof url === 'string'))
    ) {
      throw new Error(`pkg.envDependencies.urls should have a signature of String[]`)
    }
    
    const parsed = pkg.envDependencies.urls
      .map(url => url.replace(/\${([0-9a-zA-Z_]*)}/g, (_, varName) => {
        if (typeof env[varName] === 'string') {
          return env[varName]
        } else {
          throw new Error(`Could not read env variable ${varName} in url ${url}`)
        }
      }))
      .join(' ')
    
    try {
      execSync('npm install --no-save ' + parsed, { stdio: [0, 1, 2] })
      process.exit(0)
    } catch (err) {
      throw new Error('Could not install pkg.envDependencies. Are you sure the remote URLs all have a package.json?')
    }
    
    1. "postinstall": "node env-dependencies.js" 添加到您的package.json,这样它将在每个npm install 上运行

    2. 使用您想要的 URL 将您的私有 git 存储库添加到 package.json(注意:它们都必须在根目录中有一个 package.json!):

    "envDependencies": {
      "localJSON": "./.env.json",
      "urls": [
        "git+https://${GITHUB_PERSONAL_ACCESS_TOKEN}@github.com/user/repo#semver:^2.0.0"
      ]
    },
    

    (semver 说明符 #semver:^2.0.0 可以省略,但指的是一个 git 标签,这非常有用,因为它使您的 git 服务器成为一个成熟的包管理器)

    1. npm install

    【讨论】:

      【解决方案5】:

      不,这是不可能的,因为 npm 不会将任何字符串值视为任何类型的模板。

      最好将git+ssh(如果您的提供商支持)与 ssh 代理一起使用。

      【讨论】:

      • 任何使用 docker 进行部署的人都不应该使用这种方法
      • @monothorn - 有什么更好的方法呢?你有什么建议吗……我还在想如果我们不使用 ssh,有什么更好的方法。
      • @Ashmah HTTPS 是可行的方法,但您必须再次限制对您生成的令牌的访问,并确保存储库是私有的。除此之外,您还必须了解是否还有其他安全问题。
      【解决方案6】:

      您可以像这样使用环境值注入您的 package.json:

      任何以 npm_config_ 开头的环境变量都将被解释为配置参数。例如,将 npm_config_foo=bar 放入您的环境中会将 foo 配置参数设置为 bar。任何没有给定值的环境配置都将被赋予真值。配置值不区分大小写,因此 NPM_CONFIG_FOO=bar 的工作方式相同。

      https://docs.npmjs.com/misc/config#environment-variables

      【讨论】:

      • 这用于设置 npm 脚本使用的变量 - 类似于 package.json 中的配置部分。 package.json 无法读取这些变量
      【解决方案7】:

      我也有同样的需求,我的解决方案基于@Long Nguyen 的response。这样,我只能依赖 .env 文件中定义的内容。

      .env

      ...
      SKIP_PREFLIGHT_CHECK=true
      ...
      

      package.json

      ...
      "scripts": {
        "test": "yarn cross-env $(grep SKIP_PREFLIGHT_CHECK ../../.env) react-app-rewired test --watchAll=false"
      }
      ...
      

      【讨论】:

        【解决方案8】:

        非常简单直接的解决方案...

        1. 在 package.json 所在的同一目录级别创建 .env 文件。
        2. 在 .env 文件中提及 PERSONAL_ACCESS_TOKEN=************************************
        3. 不要忘记将 '.env' 添加到 .gitingore 列表中,这将防止在将 git 提交到仓库时将密钥暴露给外部世界。
        4. 现在您可以在 package.json 中添加您的依赖项,如下所示,

        包.json

        “依赖”:{ ... "my-private-github-repo": "git+https://${ENV.PERSONAL_ACCESS_TOKEN}@github.com/USER/abcd-repo-3.4.0.git", ... }

        还有其他使用“DOTENV”npm 包的方法,但是当我们试图解决“Github”包依赖时,它并不能做太多事情。以上似乎是直接的解决方案。

        【讨论】:

        • 这不会添加 env var,只是存储它
        • 这不起作用
        猜你喜欢
        • 2018-03-18
        • 1970-01-01
        • 2019-05-27
        • 2020-06-10
        • 1970-01-01
        • 1970-01-01
        • 2016-01-03
        • 2022-06-18
        • 2017-04-09
        相关资源
        最近更新 更多