I am quite new to Node.js and have come across the "__dirname" and found it to be quite handy for getting the absolute directory path of the script. But I am curious as to how it is implemented, how is it able to understand the directory structure. I have gone through the node js source code but I am not able to find a proper answer.
these object are available globally to use in node
create a file anywhere in your system with any name suppose app.js
and write in that file
console.log(__dirname);
run it like :-
node app.js
it will print the path of current directory.
Related
I was wondering if anyone here had some ideas or experience getting rid of long, hard-to-maintain relative imports inside of large node.js cloud functions projects. We’ve found that the approach which uses local NPM packages is very sub-optimal because of how quickly we tend to roll out and test new packages and functionality, and refactoring from JS to TS is impossible for us at the moment. We'd love to do it in the near future but are so slammed as it is currently :(
Basically what I’m trying to do in cloud functions is go from const {helperFunction} = require(‘../../../../../../helpers’)
to
const {helperFunction} = require(‘helpers’)
I have been unable to get babel or anything similar to that working in cloud functions. Intuitively I feel like there is an obvious solution to this beyond something like artifact registry or local NPM packages but i’m not seeing it! Any help would be greatly, greatly appreciated :)
For CommonJS modules in general, you have several options. I don't know the Google Cloud environment so you will have to decide which options seem appropriate to it.
The most attractive option to me is #5 as it's just a built-in search up the directory tree, designed specifically to look in the node_modules sub-directories of your parent directories. If you can install the shared modules in that way, then nodejs should be able to find them as long as your directory hierarchy is retained by Google Cloud.
Options #3 and #4 are hacking on the loader which has its own risks, but does give you imlementation flexibility as you could implement your own prefix that looks in a particular spot. But, it's hacking and may or may not work in the Google cloud environment.
Options #1 and #2 rely on environment variables and shared directories which may or may not be relevant in the Google cloud environment.
You can specify the environment variable NODE_PATH as a colon-delimited (or semi-colon on Windows) list of paths to search for modules. Doc here.
In addition, nodejs will search $HOME/.node_modules and $HOME/.node_libraries where $HOME is the user's home directory.
There is a package called module-alias here that is designed specifically to help you solve this. You define module aliases in your package.json, import this one module and then you can use the directory aliases in your require() statements.
You can make your own pre-processor for resolving a module filename that is being loaded by require. You cando this by monkey patching Module._resolveFilename to either modify the filename passed to it or to add additional search paths to the options argument. This is the general concept that the module-alias package (mentioned in point #3 above) uses.
If the actual location of the helper module you want to load is in a node_modules directory somewhere above your current module directory on this volume, it can be found automatically as long as the require is just a filename as in require("helpers"). An example in the doc here describes this:
For example, if the file at /home/ry/projects/foo.js called require('bar.js'), then Node.js would look in the following locations, in this order:
/home/ry/projects/node_modules/bar.js
/home/ry/node_modules/bar.js
/home/node_modules/bar.js
/node_modules/bar.js
You can see how it automatically searches up the directory tree looking in each parent node_modules sub-directory all the way up to the root. If you put these common, shared modules in your main project file's node_modules or in any directory above, then it will be found automatically. This might be the simplest way to do things as it's just a directory structuring and removing of all the ../../ stuff you have in the paths. Clearly these common, shared modules are already located somewhere common - you just need to make sure they're in this search hierarchy so they can be found automatically.
Note this info is for CommonJS modules and may be different for ESM modules.
I am trying to run a node.js script from a walkthrough I found online however I am gettings errors early on.
(Link to walkthrough I am trying to go through) https://www.education-ecosystem.com/elliottminns/l5DN4-how-to-create-a-cryptocurrency-trading-bot-in-nodejs/q6knD-how-to-create-a-cryptocurrency-trading-bot-in-no-7/
When I run the code with Node.js in windows 10 its give me an error where it can't find the other modules or other .js files in the subdirectory.
I know this is something probably super simple but when I look around, I think I getting the wrong information.
I use Brackets to look at the project folders and .js files, and I use cmd with node or node.js to run the index.js file.
The line
const app = require("app");
will make Node attempt to load a module called app from the node_modules folder.
Obviously, this is not what you want – instead, you need to load a file which is located relative to the current file. To specify a relative load path, use this:
const app = require("./app");
Node will then look for a file or directory called app. If it's a directory, it will load index.js from it.
An excerpt from this article:
The require function will look for files in the following order:
Built-in core Node.js modules (like fs)
NPM Modules. It will look in the node_modules folder
Local Modules. If the module name has a ./, / or ../, it will look for the directory/file in the given path.
The express-generator tool creates a file called bin/www and uses it as the application's main entry-point. I believe I've seen a couple of other modules do this as well, but the vast majority simply use index.js.
What is the rationale behind this? Of course I understand why you would split the server and the code for setting up the program into a separate modules, but why bin/www and not index.js? Why nest the main-entry point to a program two levels deeper than the stuff it calls? And remove the file-extension, making it even less descriptive?
Is there a clever, non-obvious reason behind this? Should I use this for my node-modules as well?
Thank you!
[edit]:
All good answers, thank you folks! I've accepted the one pointing out that this is standard behaviour for packages that include executables. Here's some more reading I've come across on this:
https://docs.npmjs.com/files/package.json#bin
https://blog.npmjs.org/post/118810260230/building-a-simple-command-line-tool-with-npm
You're used to running npm run, but not sysadmin. He will look for executables (attribute x) in thebin directory.
The entry point index.js is for node module. All packages that provide commands to run on the console contain the bin directory.
The extension is removed because it is not a script, but as a program. And these do not have extensions.
express-generator create a basic structure for an express application. By convention, the entry point of the app is index.js or app.js. In fact, express-generator create an app.js at the root of the application with the initial setup of express.
Also by convention, the bin/ directory is used for binary files, and by extension for the scripts you can directly launch (note the shebang at the first line of www file). This is common on Linux that binary file has no extension and it could explain the choice to keep this habit for this file.
www, by convention again, is used for naming web application (like /var/www/html in Apache server)
Anyway, as the documentation says,
The app structure created by the generator is just one of many ways to
structure Express apps. Feel free to use this structure or modify it
to best suit your needs.
See also this answer who talk about the core structure of express between version 3 & 4, with the removing of external module.
Okay so I am really new to server-side scripting but love to give it a try. My issue thus far is that when I attempt to launch a file like "hellonode.js" I cannot.
I launch node and attempt to access a file from within a folder called new
and I get this error:
console is undefined
however when I use node and manually type the address in I get the intended results
the javascript application works completely as intended
I really wanna know why it is I cannot execute Node from within a folder but if I manually go to it each time I can. It is rather frustrating
When you are going to execute a node script the 1st argument to node should be the uri of the script file. so
node path/to/your/nodeScript
path would be absolute or relative to your current working directory.
also you can run a node script by giving only the folder of the node script but you need to create the node script file as index.js
suppose you have a folder name MyFirstNodeScript and inside the folder there is a file named index.js the script would be
console.log('hello world!!!');
now you can run the script by node MyFirstNodeScript but you should be in the parent directory of the MyFirstNodeScript
I'm not sure how you get the error but essentially you just "opened" a .js file in windows, which resulted in windows JScript executing your file instead of node executing your file. Maybe because your node.js file, or do you simple double-click?
Basically if you want a file to double-click to start your server create a short .bat file that contains the working snippet to start your node script. However in reality you usually don't need a thing to double click at all.
I think you need to give the address to the current file in the directory. It's more of a command line way of executing files rather than a node js convention.
node .\hellonode.js
In Unix (Linux or Mac) command lines it should be like this:
node ./hellonode
im trying to set up an electron app with typescript.
So in my app.ts i have to following statement to tell electron which file should be opened:
win.loadURL(`file://../views/index.html`);
When i had only javascript it worked fine.
But now after compiling electron just opens an empty window.
Because im compiling my typescript to a different directory.
Is there a variable for the root dir or something dynamic path resolution i could use?
Thanks
This is probably caused because your file location is not absolute, this may be fine when debugging your app because your running it from a specific place but once you compile it will not be able to find the file try using something like this:
win.loadURL(__dirname + "../views/index.html");
__dirname is a variable provided by NodeJS which is the absolute location to the directory of the current file.