How to use environment variables in package.json

后端 未结 6 1760
有刺的猬
有刺的猬 2020-12-30 19:01

Because we don\'t want sensitive data in the project code, including the package.json file, using environment variables would be a logical choice in my opinion.

Exam

相关标签:
6条回答
  • 2020-12-30 19:17

    Here's how I managed to work around package.json to achieve the same purpose. It uses a script that reads from a custom section of package.json for URL modules, interpolates environment variables in them, and installs them with npm install --no-save (the --no-save could be omitted, depending on the usecase).

    As a bonus: it tries to read the env variable from .env.json, which can be gitignore'd, and very useful for development.

    1. Create a script that will read from a custom section of 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. Add a "postinstall": "node env-dependencies.js" to your package.json, that way it will be run on every npm install

    2. Add your private git repos to package.json using the URLs you want (note: they all must have a package.json at root!):

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

    (the semver specifier #semver:^2.0.0 can be omitted, but refers to a git tag, which can be very useful, as it makes your git server a fully-fledge package manager)

    1. npm install
    0 讨论(0)
  • 2020-12-30 19:23

    I have similar but different requirement. For me, I want to use environment variables in the scripts.

    Instead of using the environment variables directly in package.json, I do:

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

    And in some-script.sh:

    #!/bin/sh
    
    npm run some-other-script -- --prop=$SOME_ENV_VAR
    
    0 讨论(0)
  • 2020-12-30 19:29

    No it isn't possible as npm does not treat any string values as any kind of templates.

    It may be better to just use git+ssh (if your provider supports it) with an ssh agent.

    0 讨论(0)
  • 2020-12-30 19:37

    You can use environment values to inject in your package.json like this:

    Any environment variables that start with npm_config_ will be interpreted as a configuration parameter. For example, putting npm_config_foo=bar in your environment will set the foo configuration parameter to bar. Any environment configurations that are not given a value will be given the value of true. Config values are case-insensitive, so NPM_CONFIG_FOO=bar will work the same.

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

    0 讨论(0)
  • 2020-12-30 19:38

    No, it's not possible. You should access the repo using git+ssh, and store a private key in ~/.ssh.

    Your line then looks like:

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

    Which doesn't contain anything sensitive.

    0 讨论(0)
  • 2020-12-30 19:41

    Let's use grep to get a value environment variable from the .env file.

    "scripts": {
        "start": "NODE_ENV=$(grep NODE_ENV .env | cut -d '=' -f2) some_script"
    }
    
    0 讨论(0)
提交回复
热议问题