node.js on heroku: Error: Cannot find module 'csv' - node.js

I'm using a common node package 'csv' to do CSV parsing. It works great on my local mac, but not on heroku. In the "heroku log", I get Cannot find module 'csv'.
Yes, I have it in my package json file:
{
"name":"rimes",
"version":"0.0.1",
"dependencies":{
"sys":"",
"url":"",
"http":"",
"querystring":"",
"oauth":"0.9.10",
"fs":"",
"csv":"0.3.0",
"request":"",
"node-cache":"",
"underscore":""
}
}
and I require it in my app.js
var sys = require('sys'),
http = require('http'),
url = require('url'),
qs = require('querystring'),
OAuth= require('oauth').OAuth,
fs = require('fs'),
csv = require('csv'),
myreq = require('request'),
NodeCache = require('node-cache'),
us = require('underscore');
What can I do to fix this on heroku?
Thank you,
~Todd

So when you require packages on node, you also need to install them in your node_modules folder. They must be in the node_modules folder as well as "required" in your code. They can only be declared in your "package.json."
If you go into your project directory (the file where package.json is located) and run:
npm install
it should install your missing dependencies into your 'node_modules' folder.
Then if you re-deploy your app to heroku it should work.

Related

How to get the root of project which installed my npm module?

I am developing an NPM package. Now I want to know the easiest way to get the root of the project which utilizes my custom package.
Within my package itself it is pretty easy to get the root in node.js like so:
__dirname
This points to the root of my package itself though. I would like to get the root of the project which actually performed the npm install of my package though.
Obviously, I could simply go up from the node_modules directory and assume that the root directory is there but this sounds really bad.
Is there a standard way to achieve this?
you could use app-root-path which is an npm module and its pretty neat.
npm i -S app-root-path
after that just do
var reqlib = require('app-root-path').require;
var myModule = reqlib('/lib/my-module.js');
You can use the info from: require.main
The Module object representing the entry script loaded when the
Node.js process launched. See "Accessing the main module".
const path = require('path');
console.log(path.dirname(require.main.filename));
Having this folder structure:
/app
entry.js
node_modules/
my-package/
index.js
app/entry.js
const myPackage = require('my-package');
app/node_modules/my-package/index.js
const path = require('path');
console.log(path.dirname(require.main.filename));
And when you call: node entry.js
You will get: /app printed to stdout.
KISS
const fullPath = path.dirname(require.main.filename);
const regexResp = /^(.*?)node_modules/.exec(fullPath);
const appRoot = regexResp ? regexResp[1] : fullPath;
console.log(appRoot); // outputs the directory which is the root of this project

"Module not found: Error: Can't resolve" using Local Paths

I'm trying to use npm's "local paths" feature but I'm getting the error:
ERROR in ./src/pixi-environment/src/pixi-environment.js Module not
found: Error: Can't resolve 'pixi.js' in
'/Users/michaelosofsky/Developer/develop/locuslabs-js-sdk/src/pixi-environment/src'
I think I've set it all up correctly by following https://stackoverflow.com/a/14387210/2848676 and https://stackoverflow.com/a/42430086/2848676:
The local path relative to my project is ../../pixi.js_prerelease
From my project directory I installed with the command npm install --save ~/Developer/pixi.js_prerelease
My project's package.json got automatically updated with a dependency "pixi.js": "file:../../pixi.js_prerelease",
My project's node_modules directory automatically got a subdirectory called pixi.js created and it contains the files from ~/Developer/pixi.js_prerelease
The file that imports pixi.js does it like this:
const PIXI = require('pixi.js')
I also tried these approaches:
const PIXI = require('./node_modules/pixi.js/pixi.js')
const PIXI = require('./node_modules/pixi.js')
const PIXI = require('../../../node_modules/pixi.js/pixi.js')
const PIXI = require('../../../node_modules/pixi.js')
const PIXI = require('~/Developer/pixi.js_prerelease/pixi.js')
const PIXI = require('~/Developer/pixi.js_prerelease')
const PIXI = require('/Users/michaelosofsky/Developer/pixi.js_prerelease/pixi.js')
const PIXI = require('/Users/michaelosofsky/Developer/pixi.js_prerelease')
However, when I do npm test in my project's directory I get the error above.

How get path to folder "node_modules" in js file?

Node.js - 8.2.1
I my index.js I hard code path to node_modules:
'use strict';
var NPM_NODE_MODULES_BASE_DIR = 'd:\\Programs\\nodejs\\node_modules\\npm\\node_modules\\'
var express = require(NPM_NODE_MODULES_BASE_DIR + '\express'),
bodyParser = require(NPM_NODE_MODULES_BASE_DIR +'body-parser');
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
But it's not very good, because code is not portable. How I can get path to folder node_modules of Node.js ?
Instead of installing npm modules globally you could install them in your src folder, whenever you are in the src folder and do an npm install it should be installed in the local npm modules folder in the src file making it portable, you could use --save to add it to your dependencies so you can get it while initialising your node project
Here is an excerpt from the nodejs current master branch source documentation [doc/api/modules.md]...
...high-level algorithm in pseudocode of what require.resolve() does:
require(X) from module at path Y
If X is a core module,
a. return the core module
b. STOP
If X begins with '/'
a. set Y to be the filesystem root
If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
LOAD_NODE_MODULES(X, dirname(Y))
THROW "not found"
Please note that you can have more than one node_modules (see https://docs.npmjs.com/files/folders).
Most of the times, the node_modules you want is the parent path of the directory your current module lives in:
const path = require('path').resolve(__dirname, '..');

fs doesn't get file if i publish module to npm

I'm facing a problem when i publish my module to npm.
Here's the file structure:
- node_modules
- lib
-- file.txt
- index.js
- package.json
I use it like that:
var a = fs.readFileSync('./lib/file.txt');
It works in local development. But when i publish my module to npm, it says:
Error: ENOENT, no such file or directory './lib/file.txt'
This error comes from fs, it doesn't get file. Is it about nested node_modules folder?
I mean when i want to test my module in clear folder, i install module:
npm install <my-module-name>
Creating a test.js file and puting that codes inside it:
var myModuleName = require('my-module-name');
var a = myModuleName();
console.log(a);
So new structure become:
- node_modules
-- my-module-name
-- node_modules
-- lib
-- file.txt
-- index.js
-- package.json
- test.js
Any idea?
This is because fs.readFileSync is looking for the file relative to the current working directory. Try using __dirname:
var path = require('path');
var a = fs.readFileSync(path.join(__dirname, 'lib', 'file.txt'));

How to pass config options to a global node package?

I have a CLI (using Commander) node module with the following directory structure
|--myProject
| |--lib
| |--config.js
| |--main.js
The config file takes the form
var config = {};
config.host = 'localhost';
config.user = 'admin';
config.password = 'password';
config.database = 'doge';
module.exports = config;
and then in main.js I require the config file and set things up accordingly.
It works great for me locally but I'd love to publish it to npm, having never published a package (and I think it would eventually be useful for others). I just don't know how I would then set the config variables.
Since it's a CLI, I set the following in package.json so that ideally it can be run from anywhere by just using myProject --whateverOptions
"preferGlobal": "true",
"bin": {
"myProject" : "lib/main.js"
}
Say I publish it, and then someone comes along and runs npm install -g myProject. They could go to their global node_modules directory, into myProject/lib and add their own config.js.
I have two issues with this approach though
It seems overly messy for anyone that wants to use my package
If I update the package, and they then npm update will their config.js be erased?

Resources