How to send environment variables to Jest CLI? - javascript

I have a script that runs a Jest test for me, and I want to set an environment variable before running it, something like this:
my_test_script.sh
IMPORTANT_ENV_VAR=value_that_matters
./node_modules/.bin/jest --useStderr ./__tests__/my.test.js
However, inside "my.test.js" the IMPORTANT_ENV_VAR is not set when I run my test like this.
How do I pass the environment variable into the Jest CLI ?

What i do to solve the problem is ugly, but works.
I'm searching for a better solution (Simply set a Environment Variable by cli), not able to find it.
i create a js file that set the environment variable and i load that file passing it to the setupFile cli command. for example
jest --setupFile=setter.js
and setter.js contains
process.env.A = "B"
so, before running each test, i can read the process.env.A variable.

Use cross-env:
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
},
"devDependencies": {
"cross-env": "7.0.3",
}
}
Its purpose is exactly to pass environment variables to an npm script in a cross-platform way.

Going off of #Andrea Bisello's answer, you can load the environment variables from a plain JavaScript file. This is the key take-away.
So, in my environment, I already had a jest.config.ts. Since I was already using a .env file for defining my environment variables (located at the root of my project), I just needed a way to load them when running jest from a CLI at the root of my project.
Doing that is very simple; just add this to the jest.config.ts or jest.config.js:
// jest.config.{ts,js}
const { config } = require('dotenv');
config();
Then, from the root of your repo, you can do something like:
npx jest

Because it's hard to set environment variables in a platform-independent way under npm/package.json, and because jest --setupFiles, while in the usage, isn't in the docs and doesn't seem to work (24.9), jest REALLY DOES need a --envVar option to support environmental overrides external to package.json (like dev/production).

Whoops!
Not a Jest problem, I just needed to export in the shell script :
export IMPORTANT_ENV_VAR=value_that_matters
./node_modules/.bin/jest --useStderr ./__tests__/my.test.js

If you are using npm, you can add this to your package.json to define environment variables in the testing env.
"jest": {
"globals": {
"ENVVAR1": true,
"ENVVAR2": "value"
}
}

Related

Paramatrization of npm package.json scripts

What is alternative for npm6 .npmrc $npm_config_* vars in npm7 (config vars were deprecated).
Example of usage in the script:
"package": "sam package --profile $npm_config_awsProfile --template-file template.yaml --s3-bucket $npm_config_s3BucketName --output-template-file template-out.yaml",
Example of .npmrc
awsProfile = "au"
s3BucketName = "production-tmp-bucket-ap-southeast-2"
### OPTION 1:
Don't use the Npm environment, use it only as a stepping stone to JavaScript. Pass any parameters you need through Npm to your Javascript.
e.g.
In your package.json scripts section:
"scripts": {
"build": "cross-var node env/build.js"
}
build script defined to run javascript under node - optional use of the cross-var package to help it work on windows
(https://www.npmjs.com/package/cross-var)
To invoke on the command line:
npm run build -- <YourFirstArgHere>
Note space after --
To access in your javascript:
let firstParm = process.argv[2]
### OPTION 2:
Use standard environment variables to capture "Start state" mentioned above (Jun21).
(NOTE: I have not tried this technique, and am not sure if the environment variable value will persist between preScript - Script and postScript npm executions - assuming folks know about this: https://docs.npmjs.com/cli/v7/using-npm/scripts/)
Details on Setting these environment variables here:
How to set environment variables from within package.json?
Of particular interest is comment 14:
if you want to use the env var inside the script itself you need to prepend $, for example if you run mode=prod npm run print and you have a script in your package.json called print "print": "echo environment '$mode'" it will print environment 'prod' – Jonathan Morales Vélez

typescript : trigger "organizeImports" from command line

VSCode has an editor feature, which allows to clean and order imports in javascript and typescript files on saving ( "source.organizeImports": true ).
Question
How can I call this action on a file from the command line ?
something like :
tslint --fix [apply ordered-imports rule] file1 file2
but it seems tslint has its own implementation for "ordered-imports"
What I gathered so far
From what I understood, this feature triggers a call to the organizeImports function in typescript's codebase.
This functionnality is part of typescript's Language Service, but I don't know how to start a language service daemon, and how to interact with it.
Since the code is written in that function, there also probably is a way to call it synchronously from a ts script, but I couldn't find an example of how to setup the objects and variables from scratch to feed them to this function.
The organize-imports-cli package does what you want:
https://www.npmjs.com/package/organize-imports-cli
You can try to use Husky for this.
We've setup pre-commit hooks for this like so
"husky": {
"hooks": {
"pre-commit": "tslint -p tsconfig.json"
}
}
You can use set such rules on all git hooks

Node Js Environment Specific Variables Dev/Testing/UAT

I am new to Node js, started developing the Angular application using Angular 1.2 and Node js. As of now, I have hardcoded the REST API(Java) endpoints in the node services.js. Now I want to load the base endpoint URI specific to the environment. I have tried few ways by setting a new key value for the process.env, a env file and load it. Can anyone please help me.
I have tried below approach.
Created devEnv.env file under root folder.
Added 3 key-value pairs
hostname = xyz
apikey = 123
devUrl = xyz/xyz/xyz.com/
Then in terminal, I am trying to add it to the source.
$ source denEnv.env
I am getting source not found.
Another way I have added the script in package.json file
{
"start-dev": "source devEnv.env; node server.js"
}
In terminal I executed
$ npm start-dev
It's also failing. Can anyone please let me know what mistake I am doing and what is the correct approach.
Thanks in advance.
There are three methods known to me:
1) .env file
You need to install dotenv package using npm install/yarn add and on top of your main file (e.g. index.js) put require('dotenv').config(). That should load your variables to node.
2) passed on a start
If you want pass a small amount of environmental variables you can try something like this in your package.json:
{
"start-dev": "hostname=xyz apikey=123 devUrl=xyz/xyz/xyz.com node server.js"
}
Advice: environmental variables should look like HOSTNAME, API_KEY or DEV_URL.
3) system environmental variables
Solution: Set environment variables from file
Your variables are most likely not being exported to the shell. To be able to source your devEnv.env script, try to modify it as follows:
#!/bin/bash
export hostname=xyz
export apikey=123
export devUrl=xyz/xyz/xyz.com/
You most likely need to give it executable rights:
chmod +x devEnv.env
And then source it by running:
. devEnv.env
Another example can be found here: Set environment variables from file

How does Node set its environment variable?

When running a Node application, how does Node know what environment it is running in?
I understand that the environment is defined within process.env.NODE_ENV, but how and where is that variable defined?
There multiple ways of setting node variables but most common
1. is to start your console with them enabled as following:
> NODE_ENV=prod node start.js
process.env.NODE_ENV // prod
But there are times when you can explicitly set the env before the start of the file:
process.env.NODE_ENV = 'test';
require('config') // then it will return me the test.json config
// I use this technique mostly for unit tests
2. export the envars in the package.json
"scripts": {
"start": "export NODE_ENV=dev && node server.js", // for linux
"start": "set NODE_ENV=dev && node server", // for windows
"test": "mocha"
},
When you run npm start the script will run the server in dev mode
3. use a npm package as dotenv and setup a .env file
Plugins for env management as dotenv the most common used one. Where you can create .env files with needed ENV variables
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
These usually are set in package.json commands or come from a .env file.
For example, NODE_ENV=development from a .env file can be accessed in process.env.NODE_ENV.
For loading .env files into process.env check out dotenv.
The variable isn't defined unless you define it.
I guess you are using a regular Windows machine.
On Windows you can simply do this.
create a random index file and put this in it: console.log(process.env.NODE_ENV)
and then run it with: set NODE_ENV=productionEnvironment && node index

Npm package how to run script programmatically

I am building a package that uses an external command tool named plop js. In my package.json I want to add a binary that references to an index.js file.
"scripts":{
"plop": "plop"
},
"bin": {
"my-command": "index.js"
},
There is a way to run the plop script from my package in the index.js file?
My goal is to run this script when the user writes my-command in the terminal. (and use the local plop, I want this to be transparent to the consumer)
The reason you can't directly require and use plop is that it is a CLI. As a CLI, it does not export anything but uses process.argv as its input. So all you really need to do is alter process.argv in your script before requireing plop.
process.argv.push('--version');
require('plop');
You could then use the built in --plopfile argument to point to a specific file that you'd like to run.
I just have the same issue and found this code work:
#!/usr/bin/env node
process.argv.push('--plopfile', __dirname + '/plopfile.js');
require('plop');
Since "plop": "^2.7.3",
I found the above not work any more and from https://github.com/plopjs/plop/issues/78
I saw the new solution
#!/usr/bin/env node
const args = process.argv.slice(2);
const {Plop, run} = require('plop');
const argv = require('minimist')(args);
Plop.launch({
cwd: argv.cwd,
configPath: argv.plopfile, // changed to `${process.cwd()}/plopfile.js` in my case
require: argv.require,
completion: argv.completion
}, run);
npm's scripts are (except of start) always being run like npm run plop.
Usually you define a start command which is normally run like npm start and is known by everyone. You can also chain commands there (if you need to run multiple).
Assuming that you want to run plop as first command: If you type npm start, it will execute plop and afterwards node index.js
"scripts":{
"start": "plop && node index.js"
},
If you want to run something just **once* after npm install, put it into "postinstall" : "plop"

Categories

Resources