npm 脚本:读取 .env 文件

npm scripts: read .env file

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

{
    "scripts": {
        "example": "some-lib --argument --domain \"https://tld.com\""
    }
}

现在我要分解 "domain"。

首先尝试使用 $npm_package_config,它有效:

{
    "config": {
        "domain": "https://tld.com"
    },
    "scripts": {
        "example": "some-lib --argument --domain \"$npm_package_config_domain\""
    }
}

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

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

有人可以给我提示这个问题的可能解决方案吗?

简短回答:没有简洁的方法可以跨平台实现此目的,根据引用 $npm_package_config 变量的第二个示例。

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

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

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


解决方案

1。 .env 文件

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

DOMAIN=https://tld.com

2。安装

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

npm i -D dotenv

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] });

备注:

  • 如果你的 .env 文件不在我们项目目录的根目录下 some-lib-cmd.js,那么您可以利用 dotenv 的 path 选项来定义 .env 文件所在位置的自定义路径。例如:

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

4。 package.json

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

"scripts": {
  "example": "node some-lib-cmd"
}

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

"scripts": {
  "example": "node path/to/some/folder/some-lib-cmd"
}

一个更简单的解决方案是只使用 bash 在线解析 env 文件并提取您想要的变量:

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

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

有一个库可以完全按照 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

令人惊讶的是没有人提到'ol 尝试和真正的 DirEnv 来自动设置当前工作目录的环境。这样 env 对您的本地机器是私有的,并且可用于您的所有脚本,包括代码库内部。对于默认情况下不会查看 .env 文件的东西,它会派上用场。

我在我的所有机器上都使用它,而不仅仅是在开发中 项目。

绝对值得一试! Direnv

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

DOMAIN="https://tld.com"

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

{
    // ...
    "scripts": {
        "example": "source .env && some-lib --argument --domain $DOMAIN"
    }
}

默认情况下,这在 Windows 中不起作用,但如果您安装了 Git Bash,则可以配置 npm 以将其用于 运行 命令与例如(来自 here):

npm config set script-shell "C:\Program Files\git\bin\bash.exe"