Manuel Manuel - 3 months ago 24
Node.js Question

npm global install not using node

I'm trying to create a package that can be installed globally. My package.json has:

{
"name": "my-new-package",
"version": "1.0.0",
"main": "index.js",
"preferGlobal": true,
"bin": {
"my-new-package": "index.js"
}
}


I can run it with "node index.js" and I can publish it to npm.

The problem is that when I install it globally
npm i -g my-new-package
, on Windows the file
my-new-package.cmd
is:

@"%~dp0\node_modules\my-new-package\index.js" %*


So when I execute
my-new-package
it opens the javascript file with the default editor.

In contrast, other global packages use
node.exe
. Here's the
cute-files.cmd
example:

@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\cute-files\cute-files.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\cute-files\cute-files.js" %*


btw, I get the same behavior when I install it on Linux.

So how can I configure my package to use node when it's installed globally?

Answer

Here is how to create a globally executable nodejs package

mkdir my-new-package
cd my-new-package

first create cat package.json

{
  "name": "my-new-package",
  "version": "1.0.0",
  "description": "global module my-new-package",
  "main": "./lib/index.js",
  "bin": {
    "my-executable-name": "./bin/test-module.js"
  },
  "author": "",
  "license": "ISC",
    "preferGlobal": "true"
}

now make these two dirs as children of dir my-new-package

mkdir bin
mkdir lib

here is the another file we need cat lib/index.js

var sayHello = function(name) {
 return 'Hello, ' + name;
};

// Allows us to call this function from outside of the library file
// Without this, the function would be private to this file

exports.sayHello = sayHello;

now create a file cat bin/test-module.js

#!/usr/bin/env node

var lib= require('../lib/index.js');
var greeting = lib.sayHello('hello everyone');

console.log(greeting);

now get into dir my-new-package where file package.json lives and issue the global install command

cd my-new-package

npm install -g .

notice the period in above install command

its output will be something like this

/home/stens/node-v6.5.0/bin/my-new-package -> /home/stens/node-v6.5.0/lib/node_modules/my-new-package/bin/test-module.js
/home/stens/node-v6.5.0/lib
└── my-new-package@1.0.0 

now that its globally installed you can issue this while in any directory

my-executable-name

and it will respond with

Hello, hello everyone

Interestingly our new executable lives in nodejs global bin directory as per

which my-executable-name

which responds with

/home/stens/node-v6.5.0/bin/my-executable-name