npm脚本:读取.env文件

Dav*_*ber 9 npm npm-scripts

我有一个简单的要求:在我的npm脚本package.json文件中,有以下一行:

{
    "scripts": {
        "example": "some-lib --argument --domain \"https://tld.com\""
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我想排除“域”。

首先尝试使用$npm_package_config,它可以工作:

{
    "config": {
        "domain": "https://tld.com"
    },
    "scripts": {
        "example": "some-lib --argument --domain \"$npm_package_config_domain\""
    }
}
Run Code Online (Sandbox Code Playgroud)

但我想从本地.env文件加载域。

我没有找到任何解决方案来在命令行上的npm脚本中读取env文件的内容。

有人可以给我提示解决此问题的方法吗?

L.M*_*L.M 21

假设您有一个.env这样的文件:

DOMAIN="https://tld.com"
Run Code Online (Sandbox Code Playgroud)

然后,您可以source在命令中使用,如下所示:

{
    // ...
    "scripts": {
        "example": "source .env && some-lib --argument --domain $DOMAIN"
    }
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,这在 Windows 中不起作用,但如果您安装了 Git Bash,那么您可以配置 npm 以使用它来运行命令,例如(从此处):

npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"
Run Code Online (Sandbox Code Playgroud)

  • 我必须将 env 文件的路径指定为 `./.env`,否则我会收到 **文件未找到** 错误。附带说明一下,如果您需要将这些变量保留到节点进程子 shell 中,您可以在“source”命令之前添加“set -a &&”,以自动导出它包含的所有变量。 (4认同)
  • 在 npm 脚本中使用 `source` 会返回 `sh: 1: source: not find`。我在Ubuntu上。 (2认同)
  • 我相信“source”可以简单地替换为“.”。@Fred,试试这个:-) (2认同)

sar*_*ink 8

一个更简单的解决方案是仅使用 bash 内联解析 env 文件并提取所需的变量:

假设您的.env文件如下所示:

DOMAIN=https://tld.com
Run Code Online (Sandbox Code Playgroud)
"scripts": {
  "example": "some-lib --argument --domain $(grep DOMAIN .env | cut -d '=' -f2)"
} 
Run Code Online (Sandbox Code Playgroud)

  • 然而,当需要跨平台时,这就不那么酷了,因为这在非 bash shell 中会失败 - 特别是 Windows cmd.exe (3认同)

Jac*_*phy 7

有一个库可以完全满足您想要遵循的 12factor 应用程序最佳实践:来自 npmjs.org 的 dotenv 包

https://www.npmjs.com/package/dotenv

自由贸易协定:

$ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/your/env/vars
Run Code Online (Sandbox Code Playgroud)


Rob*_*obC 6

简短的回答:按照第二个引用该$npm_package_config变量的示例,没有简单的方法可以实现跨平台工作。

对于跨平台的解决方案,即在* nix和Windows平台上都可以成功运行的解决方案-npm脚本使用的默认shell是shcmd分别是,则需要执行命令(即,当前在Windows中定义的命令)。您的npm脚本)通过nodejs帮助脚本。本质上,您的nodejs脚本将需要:

然后可以通过您的npm-script调用nodejs帮助脚本。

下面介绍如何实现跨平台运行的解决方案。


1. .env文件

首先,假设我们在项目目录的根目录中有一个.env文件。该.env文件包含以下条目:

DOMAIN=https://tld.com
Run Code Online (Sandbox Code Playgroud)

2.安装

以下nodejs脚本利用dotenv包从.env文件中加载环境变量。我们需要安装它。为此,请cd在您的项目目录中运行以下命令:

npm i -D dotenv
Run Code Online (Sandbox Code Playgroud)

3. Node.js脚本(some-lib-cmd.js

接下来,如下创建一个nodejs脚本。让我们将文件命名为some-lib-cmd.js并将其保存在项目目录的根目录中:

// Requirements...
require('dotenv').config();
const execSync = require('child_process').execSync;
const path = require("path");

/**
 * Creates a path to an executable in the node_modules/.bin directory. Each
 * path segment is joined with the appropriate platform-specific separator as
 * a delimiter.
 * @param {String} cmd The name of the executable.
 * @returns {String} The path to the executable.
 */
function getBinFile(cmd) {
  return path.join('node_modules', '.bin', cmd);
}

// Execute the command...
execSync(`${getBinFile('some-lib')} --argument --domain ${process.env.DOMAIN}`, { stdio: [0, 1, 2] });
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 如果您的.env文件不与some-lib-cmd.js一起位于我们项目目录的根目录中,则可以利用dotenv的 path选项来定义.env文件位置的自定义路径。例如:

    require('dotenv').config({ path: 'path/to/another/folder/' })
    
    Run Code Online (Sandbox Code Playgroud)
  • 为了DOMAIN从nodejs脚本中引用变量,我们利用process.env,即process.env.DOMAIN

4. package.json

package.jsonscripts部分中,定义以下脚本:

"scripts": {
  "example": "node some-lib-cmd"
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您选择将some-lib-cmd.js保存在其他位置,即不在项目目录的根目录中,请example根据需要在脚本中重新定义路径。例如:

"scripts": {
  "example": "node path/to/some/folder/some-lib-cmd"
}
Run Code Online (Sandbox Code Playgroud)

  • @DavidVielhuber https://github.com/toddbluhm/env-cmd/ 这样做已经有一段时间了? (2认同)