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

问题描述 投票:0回答:11

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

这可能吗?

问题是如果这是明智不好,只是如果可能的话

node.js heroku npm package.json
11个回答
74
投票

如果您使用

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

按照@Paul的建议更新了

start2

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

26
投票

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

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

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

在 some-script.sh 中:

#!/bin/sh

source .env

npm run some-other-script -- --prop=$SOME_ENV_VAR

10
投票

以下是我如何设法解决

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

作为奖励:它尝试从

.env.json
读取环境变量,该变量可以被 gitignore 忽略,并且对于开发非常有用。

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

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. 上运行
  3. 使用您想要的 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

8
投票

不,这是不可能的。您应该使用

git+ssh
访问存储库,并将私钥存储在
~/.ssh
中。

你的线条看起来像:

"my-private-module":"git+ssh://[email protected]/foo/bar.git"

不含任何敏感内容。


5
投票

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

最好只使用

git+ssh
(如果您的提供商支持)与 ssh 代理。


3
投票

我有同样的需求,我的解决方案基于@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"
}
...

2
投票

您可以使用环境值注入 package.json,如下所示:

任何以 npm_config_ 开头的环境变量都将被解释为配置参数。例如,将 npm_config_foo=bar 放入您的环境中会将 foo 配置参数设置为 bar。任何未指定值的环境配置都将指定 true 值。配置值不区分大小写,因此 NPM_CONFIG_FOO=bar 的作用相同。

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


2
投票

您可以安装软件包https://www.npmjs.com/package/env-cmd 并且

.env
文件中的所有环境都将可见 即:

./.env:

ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH

Package.json:

"scripts": {
    "test": "env-cmd pact-broker can-i-deploy --broker-token=${ENV1}"
  }

或您问题中的另一个例子:

    "my-private-module":"env-cmd git+https://${BB_USER}:${BB_PASS}@bitbucket.org/foo/bar.git"

1
投票

如果您在 Docker 容器内运行节点

使用 Docker Compose 注入环境变量

app:
  environment:
    - NODE_ENV=staging

从 Dockerfile 运行 package.json 脚本

CMD [ "npm", "run", "start" ]

使用

echo
printenv

 "scripts": {
    "start": "node -r dotenv/config app.js dotenv_config_path=/run/secrets/$(echo $NODE_ENV)"
    "start": "node -r dotenv/config app.js dotenv_config_path=/run/secrets/$(printenv NODE_ENV)"
}

不要将其用于敏感的环境变量。这是指向 Docker 机密文件的非常好的方法(如本示例所示)。


0
投票

对于复杂的环境变量,可以使用 https://stedolan.github.io/jq/ 访问 JSON 文件(您的情况下的 env 文件) JSON 文件可能类似于

{
    "env" :
     {  
            "username" : "1345345",
            "Groups" :  [],
            "arraytest" : [
               {
                  "yes" : "1",
                  "no" : "0"
               }
             ]
     }
}

所以脚本可能是这样的来访问 yes 值

"scripts": {
    "yes": "jq [].arraytest[0].yes?"
}    

0
投票
  1. 安装这2个包(
    cross-var
    用于跨平台目的):
npm i cross-var dotenv-cli
  1. 鉴于您的环境变量在项目根目录中可用(如在
    .env
    文件中),请在
    $
    中添加前缀为
    package.json
    的变量,如下所示:
// .env

GOOGLE_API_KEY=mytoken
// package.json

"scripts": {
   "my-script": "dotenv -- cross-var <your command> $GOOGLE_API_KEY"
} 
© www.soinside.com 2019 - 2024. All rights reserved.