Node.js require local file throws an error - javascript

This is my project's filesystem.
root
index.js
package.json
...etc
commamds
- ping.js
- eval.js
- ...etc
This is a normal discord.js bot.
But when I try reloading the commands, I use the following code:
...etc
let pull = require(`./${file}`);
// file is command files from fs.readdirSync() and it can be 'ping.js', 'eval.js', ...
...etc
But it throws a referenceerror that the module can't be found. But when I try fs.readFile(), it works. What's the problem?

fs.readFile() defaults to the current working directory if there is no path or if there's a relative path on the filename.
require() has a completely separate set of rules for where it looks for files. For example, a filename with no path at all looks in the node_modules directory and in the global module location(s). A filename starting with ./ looks in the current module's home directory. And so on... It's a different set of rules than fs.readFile().
Since you don't show us what file actually is, it's hard to know precisely, but perhaps you need to combine the filename with the appropriate path so you are giving require() a full path name and it will go exactly there, not use the normal rules for where require() looks when given only a plain filename.

Related

Problem writing to file fs module, apparently the path is positioned at the root level

I'm practicing with typescript and I want to write a file using fs module but I don't know if is this a noob question or I'm doing something wrong but my project look like this:
root
-> dir (here are the js result from tsc)
-> src
--> data
---> data.json
--> service
---> service.ts
--> index.ts
-> package.json
-> tsconfig.json
And at service.ts apparently the path is:
let filePath = path.join('./','src','data','data.json') // this works
fs.writeFile(filePath, JSON.stringify(data,null,2), 'utf8', (err)=>{ if(err){ return console.log(err);}})
So I don't know why the path is positioned at the root level
If I try "../data/data.json" I get ENOENT ERROR no such file or directory
Is it ok?
Filesystem operations with relative paths always use the Current Working Directory - a concept explained here: https://en.m.wikipedia.org/wiki/Working_directory
When you run Node.js, you do so while being in a particular directory. For example, scripts such as npm start are usually executed in the root-level directory of a repository/project - this causes all relative paths to resolve starting from there. Note, however, that this may be different in production - it is possible for Docker, PM2, systemd, or any other tool to run your script while being in a different working directory (this can often be configured).
To inspect your current working directory in Node.js, use https://nodejs.org/api/process.html#processcwd
It is also possible to build paths relative to the directory of the JS file. This tutorial shows various examples on how to do that: https://www.digitalocean.com/community/tutorials/nodejs-how-to-use__dirname
It is important to remember that require() uses paths relative to __dirname, but fs resolves relative to CWD.

What is my correct path to file in file manager for start node js?

What is my correct path to file in file manager for start node js ?
in putty in tried to start node app.js
But still show
Cannot find module '/root/app.js'
i create app.js in file manager (filezilla client), that can access to this file by url example.com/app.js
So i tried to use this node srv/www/my ftp username/app.js
but still error?
I want to know full path for app.js for start node js, how can i do ?
(i use centos and vestacp)
What is my correct path to file in file manager for start node js ?
It's wherever you put it in the file system.
Cannot find module '/root/app.js'
Wherever you put it, it isn't in Root's home directory.
Don't run software as root!
that can access to this file by url example.com/app.js
Don't expose your serverside code to the public on your webserver!
So i tried to use this node srv/www/my ftp username/app.js but still error?
With what error?
Presumably, the srv directory isn't inside Root's home directory. You need to put the correct path to it. Possibly this would involve starting with /.
my ftp username has spaces in it, so if that is the real path (which seems unlikely), you would need to escape them.

How do I load a node module as if the current module were located somewhere else?

I have some nodejs code running in a module somewhere. From this module, I would like to load a module located in a completely different place in the file system -- for example, given the path "/another/dir" and the module name "foo", I would like Node to act as if a module running in /another/dir had called require("foo"), rather than my own module.
My code is running here
/some/folder/node_modules/mine/my_module.js
I have the path "/another/dir/", the string "foo",
and want to load this module
/another/dir/node_modules/foo/index.js
In other words, the module documentation refers to the process "require(X) from module at path Y", and I would like to specify my own value for Y
Can this be accomplished? If so, how? If not, why not?
The simplest, is just to resolve the path into an absolute path, this will be the recommended approach for most if not all cases.
var path = require('path');
var basedir = '/another/dir';
var filename = 'foo'; // renamed from dirname
var filepath = path.join(basedir, 'node_modules', filename);
var imports = require(filepath);
If you really need to make require act as if it is in a different directory,
you can push the base directory to module.paths
module.paths.unshift('/another/dir/node_modules');
var imports = require('foo');
module.paths.shift();
module.paths can also be modified externally via the environment variable NODE_PATH, tho that would be the least recommended approach but this does apply it globally across all modules.
A symlink with npm link
To avoid problems or modify source code I would use npm link, from your example:
First:
cd /another/dir/node_modules/foo # go into the package directory
npm link # creates global link
This will create a global link for the foo module, on Linux you need root permissions to do this.
Then:
cd /some/folder/ # go into some other package directory.
npm link foo # link-install the package
/some/folder/package.json should contain foo as a dep, is not mandatory, without it you get an extraneous warning with npm ls:
"dependencies": {
[...]
"foo": "*"
}
No symlink with local NODE_PATH
You don't like symlinks ? You can still use NODE_PATH but locally instead setting a global variable as #rocketspacer suggested, because as he rightly stated, it's not recommended to use it globally.
Note: In any case I would use a User variable and not a System-wide variable, a co-worker could log with a different username on the same machine and still get a modified NODE_PATH.
But to do this locally for just one invocation on Linux you can simply call:
NODE_PATH=$NODE_PATH:/another/dir/node_modules npm start
It will use that NODE_PATH only for that invocation.
Same one time invocation on Windows:
#ECHO OFF
SET BASE_NODE_PATH=%NODE_PATH%
SET NODE_PATH=%BASE_NODE_PATH%;C:\another\dir\node_modules\
node index.js
SET NODE_PATH=%BASE_NODE_PATH%
And...
You could also use a local dep like:
"dependencies": {
"foo": "file:/another/dir/node_modules/foo"
}
But would require an npm install and it would copy the content of foo in the current package node_modules folder.
It's quite easy to achieve, just add absolute paths to module object
in your current script /some/folder/node_modules/mine/my_module.js add this
module.paths.push('/another/dir/node_modules');
//this must be absolute, like /Users/John/another/dir/node_modules
var foo = require('foo');
For demo, open node in terminal, and type module.paths, it will show all the path node will search for require, you just add your path
"require(X) from module at path Y"
Means calling require(X) from within a file located at path Y. So you practically can't change Y.
Although the above solutions work (modifying module.paths & requiring absolute path), you'll have to add those snippets to every file in your project where you need requiring the foreign modules.
Even more, modifying module.paths is not officially supported. So it's not guaranteed to work in future updates of node
Introducing NODE_PATH
NODE_PATH is an environment variable that is set to a colon-delimited list of absolute paths.
Within those absolute paths, Node.js will search for a module that matches your require statement when all else has failed (Having indexed node_modules up to File System Root and still no match was found)
It is officially supported, although not recommended as it goes against convention (Your co-worker may not be aware of the NODE_PATH usage as there is no descriptive way of telling that in your project itself)
Notes:
On Windows, NODE_PATH is delimited by semicolons instead of
colons.
Node doesn't look for node_modules within those paths like
its default behavior, so your paths should be exactly where you
contain needed modules. For example: "/another/dir/node_modules"
Detailed information can be found on NodeJs official document:
https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
For those of you who are unaware of what environment variables is and how to set them, I have a windows screenshot that will get you started
In simple lines, u can call your own folder as module :
For that we need: global and app-module-path module
here "App-module-path" is the module ,it enables you to add additional directories to the Node.js module search path And "global" is, anything that you attach to this object will b available everywhere in your app.
Now take a look at this snippet:
global.appBasePath = __dirname;
require('app-module-path').addPath(appBasePath);
__dirname is current running directory of node.You can give your own path here to search the path for module.

Node.js - Error: Cannot find module 'config/chgpass'

I created the files following the tutorial (http://dataops.co/android-login-registration-system-with-node-js-and-mongodb/), but unfortunately the error is shown like in the image.
I'm new to node.js and to this kind of programming.
PS.: All of the other files that are referred in the tutorial are right, and the chgpass.js is in the target folder.
Code from the file that requests the chgpass.js file AND the tree from the folder (open with Word and select MS-DOS):
http://www.mediafire.com/download/w283nsjuuj9j794/File-Folder.txt
As your config folder is inside of node_modules folder, thus use:
var chgpass = require('config/chgpass');
Explanation:
In tutorial config folder is inside node_modules that way you can directly access it using require('config/chgpass')
But if you put outside of node_modules then you have to give the complete path of the folder from the location you are requiring it. That is in your case: require('../config/chgpass')

locating path of a file in meteorjs

I have a project in meteorjs that is using the nodes filesystem to read file, but I am not able to locate the file to be read.
My file Location
Server
- startup
- app.load.coffee
- myfileToBeRead.txt
My try in app.load.coffee
fs = Npm.require('fs')
console.log fs.readFileSync 'server/startup/myfileToBeRead.txt'
I am not able to read the file as it says
Error: ENOENT, no such file or directory 'server/startup/myfileToBeRead.txt'
I think since meteor merges everything in a js file, I have to add full path to the file.
I have tried other paths aswell (with the full path, without the full path). Can you point me out to the correct direction here?
Thank you
Well with the answer from David, I also found that I could do this with the assets/app directory of the project. All I had to do was add the file to a directory named private. This would also help me write to a file inside the directory aswell.
fs = Npm.require('fs')
console.log fs.readFileSync "assets/app/myfileToBeREad", 'utf8'
if the file should be checked in
This is the easy case - just place the file in your private directory and access it with the assets api. For more examples, see my blog post on exactly this subject.
if the file should exist somewhere else on the server
Use an absolute path to a directory not associated with your project, e.g. /tmp or /home/foo/bar. Directories inside of a meteor project get jumbled up after you bundle and deploy your app, so their existence can't be counted on. Using your example above it should work if you do something like:
var fs = Npm.require('fs');
fs.readFileSync('/tmp/myfileToBeRead.txt');

Categories