Module not found outside of main directory - node.js

I have the following dir structure:
src/
app/
package.json
node_modules/
app.js
tools/
tool_A.js
tool_A.js requires the express package
app.js requires tool_A
I have defined the express package in the requirements for app/package.json and it was correctly installed in the node_modules folder.
The issue is that if I run app/app.js I still get the error:
Error: Cannot find module 'express'
Is there a way to make it search the modules starting from the root app, rather than the outside directory?

You can move the package.json to the root directory and use require("../tools/toolA.js") inside of app.js.
Alternatively you create a new package inside of tools and install express for that package:
.../src/tools> npm init
[...]
.../src/tools> npm i express
Given your description, it seems as though the first solution is more appropriate for your situation, but both theoretically work.
EDIT:
Theoretically, though it's anything but clean, you could also use require("../app/node_modules/express"), but that would break as soon as the path to the express module changes.

Related

When using a private git url for an npm module, how can I configure the consuming application to only use files from the module's dist folder?

I am using angular-cli for my angular application, but because angular-cli currently does not support use for creating a library, I used the seemingly most widely used git project to create my library: https://github.com/jvandemo/generator-angular2-library
My issue is that I don't want to publish my npm module library to the public directory. Instead I want to use the git url directly in my dependencies. During development, this works fine. I can run the build locally and run an npm link inside the "dist" folder and everything is dandy. However when I push my npm module code to git, and then run an npm install in the consuming project, I'm not sure how to set it so that my consuming project just looks inside the dist folder of the module and treats it as if it was the root of the module.
For example, in node_modules/my_private_module, my file structure looks like:
dist/
-- component1
-- compoennt2
-- my_module.metadata.json
-- my_module.d.ts
-- my_module.umd.js
-- index.d.ts
-- index.js
-- package.json
-- README.MD
package.json
README.md
All the files that my application is using are in the /dist folder, but I DO NOT want to specify "dist" in all my imports like
import { myComponent1 } from 'my_private_module/dist';
I want to be able to just specify
import { myComponent } from 'my_private_module";
As I do in development when I run an npm link in the dist folder.
Is there a way I can achieve this?
Thanks
In package.json for your module, in the root folder:
typings: 'dist/index.d.ts',
main: 'dist/index.js'
Remove the package.json in your dist folder.
When the package is resolved from import {...} from 'my_private_module', the module loader will look for a folder called my_private_module under node_modules, and look either for index.js which defines the exports, or within package.json for the main property - which in your case also points to index.js from the dist folder.
It is good practice to put package.json where you want your module to be found, and have main and typings point to index.js and index.d.ts.
I answered a similar question here and it seems relevant.
Basically, treat the generated library in the dist folder as it's own repo. In order to keep the git init files and folders, you tell ng-packagr to not destroy the destination when building. Then you push the changes to the library specific repo and use that as your package url in other projects.

Requiring node modules locally

When working with modules already registered on NPM, the process of including them is easy: run npm install <package> and then add var package = require('<package>')
However, I'm not sure of the way to "set things up" when working on my own module. I'm not ready to publish to NPM but I do want to require the module in the same way as outlined before.
Therefore, I've completed the following steps:
Created a sub-directory inside the node_moduels directory for my module
Added a package.json file (via npm init) inside this new directory
Included a dependencies section in the package.json file
Is this the correct approach to using node modules locally.
Also, when I run npm install the dependencies do not appear to be detected in my module's package.json file - I assume this is an issue with the way I've gone about things?
I would not suggest putting it in the node_modules directory. This folder should be excluded from your source control.
Here's a minimal end to end example.
Put this file wherever you like. I suggest a 'lib' folder within your directory structure
myModule.js
module.exports = function(callback){
return callback("hello there");
};
Then, wherever you want to use it:
app.js
var myModule = require('./lib/myModule');
myModule.sayHello(function(hello) {
console.log(hello);
});
Now, if you run node app.js your console output will be:
hello there
As your myModule grows, you can refactor this into a separate set of files, create an package.json for it, and publish it to NPM
EDIT
Based on your comment, it looks like this is what you want
Local dependency in package.json
So, based on that, along with our above example, edit your package.json as follows
{
"dependencies": {
"myModule": "file:../lib/myModule"
}
}
Then you can require as:
var myModule = require('myModule');
If / when you publish myModule to npm, you can just change your package.json
ANOTHER EDIT
As another alternative, you can specify git urls in your package.json without publishing to NPM
Use Git dependencies with npm and Node on Heroku
This would be as easy as doing the following:
In the root directory of your (unpublished) module execute npm link
In the root directory of your module requiring that unpublished module execute npm link UNPUBLISHED_MODULE_NAME.
voilĂ !

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.

How to provide module dependencies for required script in a sibling directory

I am running a node.js script (foo.js) that requires a helper script that is located in a sibling directory.
//foo.js:
var magic = require('../util/magic');
magic.js uses a npm module express. However, the main directory of the 'program' (holding package.json and node_modules) is the folder where foo.js is located.
/program
/node_modules
/express
..
/foo.js
/package.json
/util
/magic.js
When running the program, the statement require('express') in magic.js fails - the module cannot be found.
Is there a way to make node.js load the express module from the program/node_modules directory?
I would like to avoid any of the following:
move the node_modules directory to a common parent of util and program
add a node_modules directory to util
pass in a reference of the required modules to magic.js
Appreciate your help!
You could supply a relative path instead the module name, because this is how Node.js is going to check for the modules folder if you don't specify a path:
/util/node_modules
/node_modules
Since you know where the module already exists, just do this instead:
var express = require('../program/node_modules/express');
However, you should place any files related to the module within the module itself when developing modules. If you don't, they don't get packaged with the module either when it is published, and you have this inconvenience of not being able to access dependencies specified in the package file.

How can I test my module locally using a symlink?

I am trying to run a module that I am developing on my local machine. So I have create a test nodejs application and within this test application I created the 'node_modules' director. The folder structure looks like it would if I had used npm install and specified my module as a dependency. Within the node_modules folder I have create a symlink to the directory where my module under test is.
When I attempt to run my test application node complains: Cannot find module 'my_module'.
I can figure out why this wouldn't work. Can this be done in this way?
Thanks!
The recommended way for doing this is:
In your my_module directory, do npm link .. npm will tell you it has made my_module available for linking.
Then, in your test_app directory, do npm link my_module. npm will now make my_module available to your app.
Note that you can still get a a "cannot find module" error this way, but this is then most likely because your my_module module is structured wrongly. By default, Node.js will look for an index.js file in the module's root directory. Otherwise, you need to specify a main entry in the module's package.json, containing the path to your main js file, relative to the module's root directory.

Resources