Cannot access NPM environment variables - node.js

In my package.json I have set a config variable called "foo" to "bar", and I am calling that variable with an NPM script.
"config": {
"foo": "bar"
},
"scripts": {
"test": "echo $npm_package_config_foo"
}
Running npm run test should output bar, but it doesn't.
I suspect that I have a general issue accessing environmental variables. As an example, I can use uglifyjs from NPM scripts but not from the command line.
Running printenv from the command line doesn't show up any of the NPM variables that one would expect.
Setup: OSX 10.11.6, NPM 2.15.11, Node 6.2.0.

What you are trying is wrong: node environment variables are only accessible using process global variable in a node process, not system-wide. So to achieve what you want you have to do is make following changes.
package.json
"config": {
"foo": "bar"
},
"scripts": {
"test": "node ./app.js"
}
app.js
console.log(process.env.npm_package_config_foo);
you can find more information here

My solution:
Set foo using npm config set foo bar
Removed the config object from my package.json.
Change $npm_package_config_foo to $npm_config_foo in the NPM scripts properties

Related

Declaring global commands inside a NPM package

I'm try to understand how to declare a command inside a NPM package accessible through the main application.
For instance, I released a project inside the NPM registry, with a couple of commands inside the package.json like:
"scripts": {
"somestuff": "node index.js"
},
Let say now I want to use this command somestuff inside the main app. When I try to run this I receive: missing script: somestuff.
Because is not defined inside the package.json of the main app but it's inside the package.json of the module inside the node_modules folder.
How can I declare a command inside a node module accessible from the main app?
I haven't tried it myself, but I think you can do something like this. In your package.json:
{
"name": "my-package",
...
"main": "index.js",
"bin": "index.js",
...
}
Then invoke it from wherever you installed it as a dependency:
npx my-package
You would probably want to install my-package with --save-dev.
Also, have a look at npx-run project, it looks exactly as what you want.

'NODE_OPTIONS' is not recognized as an internal or external command

I'm on a windows 10 machine trying to run a build script from the git bash terminal.
On my terminal node is recognized just fine, for example I get the version when I run node --version.
But running the build script fails with the following error:
'NODE_OPTIONS' is not recognized as an internal or external command,
operable program or batch file.
I'm guessing I need to add something to my PATH variables to get this to work, but what?
Use cross-env package which easily sets environment variables.
Step 1:
Install cross-env from npm
npm i cross-env
In your package.json file (In this example your need is to run 'start' command which has 'NODE_OPTIONS')
{
"name": "your-app",
"version": "0.0.0",
"scripts": {
...
"start": "NODE_OPTIONS=<your options> <commands>",
}
}
Step 2
Add 'cross-env' in the script which you need to run NODE_OPTIONS. (In this case 'start' script)
{
"name": "your-app",
"version": "0.0.0",
"scripts": {
...
"start": "cross-env NODE_OPTIONS=<your options> <commands>",
}
}
For me installing the below mentioned package solved the problem
npm install -g win-node-env
Not a PATH issue, NODE_OPTIONS is an ENVIRONMENT VARIABLE that needs to be set before starting your build. To set en environment variable in Windows 10 you need to use the set command in a terminal mode. See this article on SUPERUSER forum to learn more.
In your case, just add set before NODE_OPTIONS and that will fix your issue.
Here's how to integrate it in package.json:
...
"scripts": {
...
"build": "set NODE_OPTIONS=--max_old_space_size=4096 && next build"
...
}
...
A way to launch both the node process and the debugger via F5, which does not require wrestling with env vars.
Make sure .vscode/launch.json is deleted.
1. Open the Run & Debug pane
2. Click on Node.js
3. DO NOT click on "Run script: dev" directly, instead click on the cog next to it
4. Your launch.json should look similar to:
{
"configurations": [
{
"type": "node-terminal",
"name": "Run Script: dev",
"request": "launch",
"command": "yarn run dev",
"cwd": "${workspaceFolder}"
}
]
}

Find the package.json file from within an npm script that runs on preinstall

So I need to read the package.json before installing a new package via npm.
Why reading package.json in the first place?
I am using npm for CSS components that are individually versioned and can have inter dependencies. (No javascript is delivered)
Looking for version conflicts for a bunch of dependencies I need to detect when package A requires package C#1.0.0 and package B requires package C#2.0.0 and deal with it.
Npm (as of version 3) deals with these issues by nesting a conflicting module deeper inside the tree. You now end up with both versions of the same module. CSS has a global namespace and a mixin (in Sasss case) would then overwrite each other and break your CSS.
This flat dependency issue is perfectly outlined in the npm blog: http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging
Even not considering our specific use case it strikes me as odd that you don't have access to the package.json in preinstall and postinstall scripts. They seem to be just for that use case.
What I tried
My package.json of the package I'm installing looks like this:
{
"name": "testmodule",
"version": "0.3.6",
"description": "TODO",
"scripts": {
"preinstall": "npm i some-script && some-script",
},
"author": "TODO",
"license": "MIT"
}
Inside that some-script package I run:
console.log( process.cwd() );
console.log( __dirname );
I then run:
~/path/to/folder $ npm i testmodule
This will result in:
$ npm i testmodule
> testmodule#0.3.6 preinstall /path/to/folder/node_modules/.staging/testmodule-5cc9d333
> some-script
/path/to/folder/node_modules/.staging/test-module-5cc9d333
/path/to/folder/node_modules/.staging/test-module-5cc9d333/node_modules/some-script
Now I totally get that I can't really access the root of where npm i was ran because my script was run by a subprocess of npm and has an entirely different root.
I then thought npm root should keep track where the actual root was for me and passed that as a parameter to my script from inside the testmodule package.json:
{
"name": "testmodule",
"version": "0.3.6",
"description": "TODO",
"scripts": {
"preinstall": "npm i some-script && some-script \"$(npm root)\"",
},
"author": "TODO",
"license": "MIT"
}
Unfortunately that also defaults back to a staging path:
/path/to/folder/node_modules/.staging/testmodule-5cc9d333/node_modules
I filed an issue with the registry but not holding my hopes up for them to get to that in time. Also my script needs to work on older npm installations.
In the meantime I came up with something like that inside my some-script:
let pgkPath = process.cwd().split('/node_modules/')[0];
That will return /path/to/folder/ which is correct but it makes the assumption no-one runs an npm i inside a folder incidentally named node_modules... Seems hacky.
Question
How can I access the path to the package.json from inside an npm script that is run via preinstall? To me that seems like something not too outrageous to ask for?
I don't understand your use-case entirely, but to answer your specific question of finding a parent package.json from a preinstall script:
Pass $(cd .. && npm prefix) as an argument to your script, then load ./package.json.
npm prefix will return the closest parent directory to contain a package.json file, which when invoked from the .. directory, should return the parent npm package's path.
{
"name": "testmodule",
"version": "0.3.6",
"description": "TODO",
"scripts": {
"preinstall": "npm i some-script && some-script \"$(cd .. && npm prefix)\"",
},
"author": "TODO",
"license": "MIT"
}

Force node to use git bash on windows

I have a package.json file that looks like:
{
"name": "APP",
"version": "3.0.0",
"private": true,
"scripts": {
"start": "node app.js",
"test": "./test/dbLoad && env db=test test=1 jasmine"
}
}
When I run npm test, I get an error:
'.' is not recognized as an internal or external command
I'm guessing this is because node is using windows cmd.exe. The command works fine if i preface it with bash. Can I change a configuration setting of some kind in node so that it automatically uses bash?
Set NPM's script-shell to point to Git Bash (note the newer path):
npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"
This tells NPM to run scripts defined in your package.json (such as start or test) using the specified shell instead of the default, which on Windows is cmd.exe. See https://docs.npmjs.com/misc/config#script-shell.
Yes you can!
Before running npm run you should do:
set comspec=your_bash.exe_folder
The NPM package, check the comspec enviroment, and run it on win32.
By default ComSpec=C:\windows\system32\cmd.exe
For more info you can see the source code of NPM: lifecycle.js (Line 219)
if (process.platform === 'win32') {
sh = process.env.comspec || 'cmd'
shFlag = '/d /s /c'
conf.windowsVerbatimArguments = true
}
You can set the environment comspec, to your bash by default by using the registry. If you need any help, please comment.

NODE_PATH not recognized

Here is my package.json script:
"scripts": {
"start": "NODE_PATH=$NODE_PATH:./shared node",
"dev": "npm run start & webpack-dev-server --progress --color"
},
When I run npm start in Windows 8 it shows the below error:
node_path is not recognized as a internal or external command, operable program or batch file
I had the same problem when I wanted to set the environment variable in a browserify script:
"scripts": {
"build:symlinked": "NODE_PATH=./node_modules browserify src/index.js > dist/build.js"
}
To be able to use linked node modules that are requiring peer-dependencies.
As mentioned above, you can try to set the environment variable manually or by script where it seems you have to use different commands depending on what command line tool you use.
For not having to do this every time, I found that npm package: cross-env.
By installing it and applying the script like this
"scripts": {
"build:symlinked": "cross-env NODE_PATH=./node_modules browserify src/index.js > dist/build.js"
}
I was able to solve that problem. This is mainly useful, if you work in a team with mixed MAC/Linux and Windows users, so you don't have to to take care about applying the Environment variables in such scripts anymore.
You don't need to define environment variable in package.json just use this
{
"scripts" : "node server.js"
}
or define what you want, here is the reference link.

Resources