Bug 1125870

Summary: NODE_PATH is not set, and node won't find modules installed systemwide by yum/rpm
Product: [Fedora] Fedora EPEL Reporter: Jan Kundrát <jkt>
Component: nodejsAssignee: T.C. Hollingsworth <tchollingsworth>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: el6CC: jamielinux, mrunge, sgallagh, tchollingsworth, thrcka
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-08-01 20:43:23 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Jan Kundrát 2014-08-01 09:33:28 UTC
Description of problem:

I have a 3rd party application written in Node.js which I want to deploy on SL6.5 using Node.js from EPEL. Here's how the app looks like:

[orion@mrsa src]$ cat adapter 
#!/usr/bin/env node
require('./').main();
[orion@mrsa src]$ head -n 50 lib/adapter.js 
/*
 * Copyright 2013 Telefónica I+D
 * All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */


/**
 * Module that implements a HTTP asynchronous server processing requests for
 * adaptation from raw monitoring data into NGSI format, then using the results
 * to invoke Context Broker.
 *
 * @module adapter
 */


'use strict';


var http   = require('http'),
    url    = require('url'),
    retry  = require('retry'),
    logger = require('../config/logger'),
    opts   = require('../config/options'),
    parser = require('./parsers/common/factory');


Unless I'm terribly mistaken, I should be able to run this out-of-box as long as I have these modules installed, which I do. However, it fails:

[orion@mrsa src]$ ./adapter --brokerUrl http://127.0.0.1:1026/

module.js:340
    throw err;
          ^
Error: Cannot find module 'retry'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/tmp/ngsi_adapter/src/lib/adapter.js:33:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)

...while it works just fine if I pass the appropriate environment variable:

[orion@mrsa src]$ NODE_PATH=/usr/lib/node_modules ./adapter --brokerUrl http://127.0.0.1:1026/
info: Server running at http://127.0.0.1:1337/

nodejs-retry-0.6.0-5.el6.noarch is installed. I suspect that either the nodejs package should be patched to make sure that it looks for the modules in that systemwide path, or an appropriate env variable should be set somewhere in /etc. A quick grep has shown nothing which contains either NODE_ or node_ in there.

Comment 1 T.C. Hollingsworth 2014-08-01 20:43:23 UTC
This is a deliberate design decision by node and npm upstream which
Fedora respects.  For more information on why, see:
https://www.npmjs.org/doc/faq.html#I-installed-something-globally-but-I-can-t-require-it

Our packaging guidelines are intended to ensure that RPM-provided
modules work exactly like ones installed by `npm install -g`, and can
be used in local modules easily using `npm link`.  You can also set
NODE_PATH=/usr/lib/node_modules in your environment to make npm and
rpm installed modules available universally.

This is also documented here:
https://fedoraproject.org/wiki/Node.js#Using_modules_installed_via_yum

Your third-party module likely ships a package.json file in the root of the module that expresses its dependencies.  You can simply invoke `npm install` in that directory and npm will read the dependencies from that file and create a node_modules directory and install all dependencies inside it.

This is the reccomended way to get dependencies for third-party applications since we cannot guarantee that the versions of packages provided as RPMs match the dependency set of your third-party application.  (Especially in EPEL, where many nodejs packages are relatively outdated due to EPEL's stablility and lifetime guarantees.)

Comment 2 Jan Kundrát 2014-08-02 10:04:49 UTC
Oops, I wasn't aware of the upstream's decision -- that comes as a surprise to me. I was googling for stuff like "node won't find system-wide modules", but I hadn't included the keyword "npm" in there. I also landed on Fedora's feature page about a proposal to package Node.js IIRC, but not on that present status page (or I missed it, don't know anymore).

Either way, sorry for wasting your time, and thanks for an excellent response.

Comment 3 T.C. Hollingsworth 2014-08-02 21:42:43 UTC
(In reply to Jan Kundrát from comment #2)
> Oops, I wasn't aware of the upstream's decision -- that comes as a surprise
> to me. I was googling for stuff like "node won't find system-wide modules",
> but I hadn't included the keyword "npm" in there. I also landed on Fedora's
> feature page about a proposal to package Node.js IIRC, but not on that
> present status page (or I missed it, don't know anymore).

Yeah, I think that feature page has more Google juice because marketing materials and news organizations linked to it quite a bit during the Fedora 19 release cycle where we first introducted Node.js to Fedora.  :-(

I just added a little note to the top of that old page now directing people to the new one with more up-to-date information.  Hopefully that will help people in the future.

> Either way, sorry for wasting your time, and thanks for an excellent
> response.

No trouble at all.  :-)