To illustrate this, let’s take the simple example of an npm script from the last post which utilized http-server. Next to having that simple HTTP server, we use cypress to run a few tests on this site the server is delivering.
{
"scripts": {
"start": "http-server build -p 8080",
"test": "cypress run --env host=http://localhost:8080"
}
}
You may be looking for a way how to move that duplicated port 8080
definition into some kind of central place so you only have to maintain it in a single place.
Both the npm CLI and Yarn allow to create custom properties in your package.json
and expose all of those properties/options (even nested ones) as environment variables prefixed with npm_package_
to your custom scripts.
This lets you set any value in package.json
which can be picked up and accessed as environment variables in your scripts of that same package.json
file.
{
"scripts": {
"start": "http-server build -p $npm_package_appConfig_port",
"test": "cypress run --env host=http://localhost:$npm_package_appConfig_port"
},
"appConfig": {
"port": 8080
}
}
Please note that this is not limited to custom properties—all properties are available as environment variables, like the following examples demonstrate.
$npm_package_name
$npm_package_scripts_start
$npm_package_appConfig_port
Due to the fact that those variables are »real« environment variables, you can also access these values within your Node.js application via process.env
(e.g. process.env.npm_package_name
)—but, of course, only when being executed via a script in your package.json
(e.g. npm start
).
Get a list of all environment variables
The commands npm run env
and yarn run env
print all variables present in a package and available to the scripts at runtime. As this also contains the package properties prefixed with npm_package_
, running e.g. npm run env | grep "npm_package_"
gives you a list of all environment variables generated from your package.json
properties.
Pitfalls
As aforementioned examples demonstrate, nesting levels in package.json
are represented by underscores (_
) in the environment variable names. As underscores are common in key names of JSON properties, this opens up the risk to overlapping variable names resulting of different input structures. Let’s have a look at the following example.
{
"scripts": {
"start": "echo $npm_package_config_app_name"
},
"config": {
"app": {
"name": "Test"
}
},
"config_app": {
"name": "Demo"
}
}
What would you expect $npm_package_config_app_name
(i.e. running npm start
or yarn start
) to be? You may have guessed it: while npm prints Demo
(i.e. the last definition), Yarn prints Test
(i.e. the first definition). To prevent confusion between developers using different tools, you should make sure to prevent such overlapping names at any cost.