How do I execute symbolic linked files in node.js? - node.js

I'm writing an application that contain a skeleton directory that would be copied to a new node project. Since I'm debugging the skeleton, I'm symlinking the file in my new folder,
so:
mainapp/skel/index.js
sampleapp/index.js -> ../mainapp/skel/index.js
sampleapp/package.json
sampleapp/node_modules/abc
index.js:
require('abc');
But running the sampleapp with:
node index.js
are not working because it seems to try to find the module in mainapp/skel/node_modules instead of sampleapp/node_modules. Any idea for a workaround?

You have two options -
Symlink node_modules directory in skel
Set NODE_PATH environment variable
export NODE_PATH=<path_to_sampleapp_node_modules>

Related

Is there any way of changing the relative path of a mjs file (to make it see a different node_modules folder)?

When I'm executing pure node.js scripts I can change the path where it searches for node_modules as the following:
export NODE_PATH="/home/user/node_modules"
node "/home/user/different/path/file.js"
This way, I can make scripts located inside /home/user/different/path/ see the node_modules folder located in /home/user/ when they are executed.
So far everything is fine, the problem starts with .mjs files. If I try running:
export NODE_PATH="/home/user/node_modules"
node "/home/user/different/path/file.mjs"
I'll receive the error Error [ERR_MODULE_NOT_FOUND] for the modules that I use in my code. The workaround that I know for that is creating a symbolic link inside my script's folder. Something like:
ln -s "/home/user/node_modules" "/home/user/different/path/node_modules"
After doing that, if I run node "/home/user/different/path/file.mjs" it'll work as expected and I'll be able to use libraries installed on /home/user/node_modules with the import statement in my script. However, I'd like to find a solution that doesn't require me to create a symbolic link of the node_modules folder. Is there any alternative solution when I'm working with .mjs files that allows me to change its relative path?

Is it possible to make the node command see a node_modules folder on a different location than the specified one?

I know I can install Node.js libraries with the command npm from the command line... So, if I type:
npm install mylibrary
It'll create a node_modules folder on my current location and it'll install mylibrary (if it exists on npm)... Let's say that I create a Node.js code using it as the following:
const mylibrary = require('mylibrary')
mylibrary.doSomething()
Since I've installed this library on my current folder with the last command, this node.js script will work only if I save it on a file on my terminal current location as well. If I name this file as file.js, I can execute it with:
node file.js
Well, my problem is that I have a very specific case where the node_modules folder cannot exist in the same location that my file.js. Also, I'd like to avoid having to install mylibrary globally. Is there any way of defining as a parameter the path that the command node will search for the node_modules folder? I've checked node --help and it seems there's a lot of options, but I didn't manage to make it work. Is it possible to do? Can I use a node_modules folder that's neither the one of my file.js path or a global installed library?
You can have a link for the node_modules folder. For example, to create the symbolink link in Linux do this:
cd /path/to/script/folder
ln -s /path/to/where/you/can/have/node_modules node_modules
If you can't have the link, use the full path to the node_modules folder in the require, for example:
const mylibrary = require('/path/to/node_modules/mylibrary')
Also, you can solve the problem by using the NODE_PATH environment variable, set it like this
export NODE_PATH=/path/to/node_modules

how to make webpack use shared node modules in the parent directory

I want to use shared node modules which is kept in the parent directory. I have the following folder structure:
parent directory
node_modules
company
serverless.yml
handler.js
webpack.config
I have to use webpack to create packages and upload into aws-lamda. But the webpack is looking for node modules. But I am getting the following error:
Overriding the webpack directory in serverless-webpack since it uses v1 version of webpack...
cp: cannot stat 'node_modules/webpack': No such file or directory
How can I make webpack.config point to the node_modules in the parent directory?
if you read the NodeJS require documentation you are highly encouraged to use local node_modules folders even if your packages require have the same dependencies.
https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders
Alternatively your can work with NODE_PATH , notice that require will first look into local node_modules then start looking into other folders so try to delete local node_modules
If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they are not found elsewhere. (Note: On Windows, NODE_PATH is delimited by semicolons instead of colons.)
Since webpack exposes many module resolving options https://webpack.github.io/docs/resolving.html
Resolving a module path
For resolving a module Resolve first gathers all search directories for modules from Webpack’s context directory. This process is similar to the node.js resolving process, but the search directories are configurable with the configuration option resolve.modulesDirectories. In addition to this the directories in the configuration option resolve.root are prepended, and directories in the configuration option resolve.fallback are appended.

How is this node.js module getting loaded?

I have just started learning node and express and stumbled across this sample express application - https://github.com/madhums/node-express-mongoose-demo.
The server.js file loads a module named config without a relative path -
var config = require('config')
https://github.com/madhums/node-express-mongoose-demo/blob/master/server.js#L15.
What I don't understand is how the module is getting loaded. There is no module named config in node_modules. The package.json contains NODE_PATH which points to ./config folder. However, the config folder doesn't contain an index.js file.
So how does the config object gets its properties?
NODE_PATH points to super-folders that contain Node modules (which may themselves be in folders, or maybe single files).
The modules documentation says:
If the NODE_PATH environment variable is set... then node will search those paths for modules if they are not found elsewhere.
It search those paths for modules; it does not treat those paths as modules.
Therefore, require('config') loads ./config/config.js. The NODE_PATH=./config:... tells Node to look in ./config for modules, and it find successfully finds a file called config.js in that folder, which it loads as a module.

node.js require function not finding module

I have a server.js file that I downloaded from someone's website. The first line is: var express=require('express');
When I try to run this server with "node server.js" I get the following error: "Cannot find module 'express'." The express module is installed in the default node install location:
C:\Users\myname\node_modules\express\
I'm able to successfully run express by executing "node express.js" from the express install location in node_modules. I also tried copying over the express folder and file into my c:\node-testing\ directory where my server.js file is located but I still get the error. Any idea what the problem might be and how to fix?
You can set the NODE_PATH environment variable to tell nodejs to search other paths for globally installed modules that are not in the project directory.
See http://nodejs.org/api/modules.html#modules_loading_from_the_global_folders for details.
On Unix installations there are some built-in default locations, but on Windows, it appears you have to set this environment variable manually to support a global location.
FYI, if you want require to load a module from the project directory, then you have to use
require("./filename");
with the ./ in front of it. That's why it didn't work when you copied it to the project directory. node makes a distinction between loading from the project directory vs. loading from the node_modules directory below and thus requires a different syntax to specify which one you want. Express.js is also not a stand-alone module because it depends on a bunch of other modules so you could not copy only it. I'd recommend using the NODE_PATH option or install express into your project directory (it will end up in a node_modules sub-directory).
Node.js will only search for modules in from the current (and parent) directories. Unlike npm, Node has no concept of "global" modules.
You need to run npm install to install your modules into the directory containing your code.

Resources