Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

npm scripts: read .env file

Tags:

I have a simple requirement: In my npm scripts package.json file I have the line:

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

Now I want the "domain" to be factored out.

First try is to use $npm_package_config, which works:

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

But I want the domain loaded from an local .env file.

I did not find any solution out there to read the contents of an env file inside npm scripts on the command line.

Can somebody give me a hint to a possible solution for this problem?

like image 767
David Vielhuber Avatar asked Jan 01 '19 20:01

David Vielhuber


People also ask

Can I use env in package json?

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.

What is .env file in node?

The dotenv package for handling environment variables is the most popular option in the Node. js community. You can create an. env file in the application's root directory that contains key/value pairs defining the project's required environment variables.

What is .env file Javascript?

Its environment variables file. In simple term, it is a variable text file. In this file we set a variable with value and that you wouldn't want to share with anyone, purpose of file is keep as secret and secure because in . env file we store our database password, username, API key etc…


Video Answer


2 Answers

Short answer: There's no terse way to achieve this that works cross-platform, as per your second example which references the $npm_package_config variable.

For a cross-platform solution, i.e. one that works successfully on both *nix and Windows platforms - whereby the default shell utilized by npm scripts is either sh or cmd respectively, you'll need to execute your command (i.e. the one which is currently defined in your npm-script) via a nodejs helper script. Essentially, your nodejs script will need to:

  • Utilize the dotenv package to load the .env file.
  • Execute the command using the nodejs built-in module; child_process.exec() or child_process.execSync().

The nodejs helper script can then be invoked via your npm-script.

The following describes how to achieve a solution that runs cross-platform.


Solution

1. The .env file

Firstly, lets assume we have a .env file residing in the root of our project directory. The .env file contains the following entry:

DOMAIN=https://tld.com 

2. Install

The following nodejs script utilizes the dotenv package to load the environment variable(s) from the .env file. We'll need to install it. To do this cd to your project directory and run the following command:

npm i -D dotenv 

3. The Node.js script (some-lib-cmd.js)

Next create a nodejs script as follows. Let's name the file some-lib-cmd.js and save it in the root of the project directory:

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

Notes:

  • If your .env file does not reside in the root of our project directory along with some-lib-cmd.js, then you can utilize dotenv's path option to define a custom path to the location of your .env file instead. For example:

    require('dotenv').config({ path: 'path/to/another/folder/' }) 
  • To reference the DOMAIN variable from within the nodejs script we utilize process.env, i.e. process.env.DOMAIN.

4. package.json

In the scripts section of your package.json define the following script:

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

Note: If you have chosen to save some-lib-cmd.js elsewhere, i.e. not in the in the root of your project directory, then redefine the path in your example script as necessary. For instance:

"scripts": {   "example": "node path/to/some/folder/some-lib-cmd" } 
like image 84
RobC Avatar answered Sep 19 '22 05:09

RobC


A much easier solution is to just use bash to parse the env file in-line and extract the variable you want:

Assuming your .env file looks like:

DOMAIN=https://tld.com 
"scripts": {   "example": "some-lib --argument --domain $(grep DOMAIN .env | cut -d '=' -f2)" }  
like image 37
Kabir Sarin Avatar answered Sep 19 '22 05:09

Kabir Sarin