如何在package.json中使用环境变量

kaa*_*ude 29 heroku node.js npm

因为我们不希望项目代码中包含敏感数据,包括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"
Run Code Online (Sandbox Code Playgroud)

这可能吗?

(问题在于这是否明智不好,只要它是可能的)

问候!

一世.

Lon*_*yen 27

让我们使用 grep 从 .env 文件中获取值环境变量。

"scripts": {
    "start": "NODE_ENV=$(grep NODE_ENV .env | cut -d '=' -f2) some_script"
}
Run Code Online (Sandbox Code Playgroud)

  • 有两个问题。1:问题是关于依赖关系,而不是脚本。脚本在 shell 中运行,因此在脚本中使用环境变量与在常规 package.json 值中使用环境变量有很大不同。2:(也许我在这里遗漏了一些东西,但是)通过 grep 获取环境变量的值似乎是执行 `$NODE_ENV` 的复杂方法。此外,如果“NODE_ENV”已经定义为环境变量,则不需要重新定义它。看起来它只是让您免于执行“source .env”(您可以使用 direnv 之类的东西自动为您执行此操作)。 (18认同)
  • 令人震惊的是,这有这么多的赞成票。使用“eval”执行文件中的内容是一个可怕的想法。希望你有时间在一些恶意行为者注入他们的`mysql -e“DROP DATABASE prod;”之前找到一份新工作;NODE_ENV="123"` `.env` 文件放入您公司的构建管道中。 (2认同)

Ste*_*ett 7

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

你的行看起来像:

"my-private-module":"git+ssh://git@bitbucket.org/foo/bar.git"
Run Code Online (Sandbox Code Playgroud)

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


Chr*_*ois 7

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

作为奖励:它尝试从 中读取 env 变量.env.json,它可以被 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?')
}
Run Code Online (Sandbox Code Playgroud)
  1. 添加一个"postinstall": "node env-dependencies.js"到您的package.json,这样它将在每个npm install

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

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

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

  1. npm install


tec*_*000 6

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

我不是直接在package.json中使用环境变量,而是:

"some-script": "./scripts/some-script.sh",
Run Code Online (Sandbox Code Playgroud)

在some-script.sh中:

#!/bin/sh

npm run some-other-script -- --prop=$SOME_ENV_VAR
Run Code Online (Sandbox Code Playgroud)

  • 你能告诉我如何访问“some-other-script”中的“prop”吗? (3认同)

msc*_*dex 5

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

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