Node.JS Express - Importing a folder As A Module - node.js

I am new in express.
What I am trying to do is import a folder as a module so that in future I can use other files in the folder can be used as modules.
So, what I have done is change this-
var routes = require('./routes/index');
var users = require('./routes/users');
app.use('/', routes);
app.use('/users', users);
to this-
var routes = require('./routes');
app.use('/', routes.index);
app.use('/users', routes.users);
But I am getting error like this-
Can anyone please help, what can I do to solve this issue so that I can use all files inside route folder as modules?
Update-
Regarding to #AnubhavSrivastava , my requirement is OK because I have seen this in MVA tutorial. Link is here and time is 1:32:58.
Code is like this-
Thanks in advance for helping.

When you do require over a folder, it returns index.js module by default, you wont get route.user, unless you have a variable that is exported in index.js.
Extract from node js official documentation here - https://nodejs.org/api/modules.html#modules_folders_as_modules
Folders as Modules
It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to that library. There are three ways in which a folder may be passed to require() as an argument.
The first is to create a package.json file in the root of the folder, which specifies a main module. An example package.json file might look like this:
{ "name" : "some-library",
"main" : "./lib/some-library.js" }
If this was in a folder at ./some-library, then require('./some-library') would attempt to load ./some-library/lib/some-library.js.
This is the extent of Node.js's awareness of package.json files.
Note: If the file specified by the "main" entry of package.json is missing and can not be resolved, Node.js will report the entire module as missing with the default error:
Error: Cannot find module 'some-library'
If there is no package.json file present in the directory, then Node.js will attempt to load an index.js or index.node file out of that directory. For example, if there was no package.json file in the above example, then require('./some-library') would attempt to load:
./some-library/index.js
./some-library/index.node

Related

How to access the base package form a node_module

I am looking to access a JSON config file that the user would place next to their package.json from a node_module package that I created. Is there a best approach to do this. I tried a relative import but that didn't really work and I am not sure how best to accomplish dynamic imports if the config file doesn't exist because I want to allow it to not exist as well.
Here is how I tried to handle dynamic imports though:
export const overrides = (function () {
try {
return require('../../../../../../overrides.json');
} catch (_err) {
return null;
}
})();
Also I tried fs but I get a browser config error I am not sure if that is something else. I should research but I didn't understand the docs around that.
using a library
This worked for me: find-package-json
Basically on any js file who needs the base, home or workspace path, do this:
var finder = require('find-package-json');
var path = require('path');
var f = finder(__dirname);
var rootDirectory = path.dirname(f.next().filename);
rootDirectory will be the location of the folder in which the main package.json exist.
If you want to optimize, get the appRootPath variable at the start of your app and store/propagate the variable to the hole nodejs system.
no libraries
Without any library, this worked for me:
console.log("root directory: "+require('path').resolve('./'));
This will get you the root directory of your nodejs app no matter if you are using npm run start or node foo/bar/index.js
More ways to get the root directory here:
Determine project root from a running node.js application
usage
If you achieve to obtain the root directory of your nodejs app and your file is at the package.json level, use this variable like this to locate any file at root level:
rootDirectory+"/overrides.json"

How to bundle and require non JS dependencies in Firebase Cloud Functions?

I have an http cloud function that returns some dynamic HTML. I want to use Handlebars as the templating engine. The template is sufficiently big that it's not practical to have it in a const variable on top of my function.
I've tried something like:
const template = fs.readFileSync('./template.hbs', 'utf-8');
But when deploying the function I always get an error that the file does not exist:
Error: ENOENT: no such file or directory, open './template.hbs'
The template.hbs is in the same directory as my index.js file so I imagine the problem is that the Firebase CLI is not bundling this file along the rest of files.
According to the docs of Google Cloud Functions it is possible to bundle local modules with "mymodule": "file:mymodule". So I've tried creating a templates folder at the root of the project and added "templates": "file:./templates" to the package.json.
My file structure being something like this:
/my-function
index.js
/templates
something.hbs
index.js //this is the entry point
And then:
const template = fs.readFileSync('../node_modules/templates/something.hbs', 'utf-8');
But I'm getting the same not found error.
What is the proper way of including and requiring a non JS dependencies in a Firebase Cloud Function?
The Firebase CLI will package up all the files in your functions folder, except for node_modules, and send the entire archive to Cloud Functions. It will reconstitue node_modules by running npm install while building the docker image that runs your function.
If your something.hbs is in /templates under your functions folder, you should be able to refer to it as ./templates/something.hbs from the top-level index.js. If your JS is in another folder, you might have to work you way out first with ../templates/something.hbs. The files should all be there - just figure out the path. I wouldn't try to do anything fancy is your package.json. Just take advantage of the fact that the CLI deploys everything but node_modules.
This code works fine for me if I have a file called 'foo' at the root of my functions folder:
import * as fs from 'fs'
export const test = functions.https.onRequest((req, res) => {
const foo = fs.readFileSync('./foo', 'utf-8')
console.log(foo)
res.send(foo)
})
The solution was to use path.join(__dirname,'template.hbs').
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname,'template.hbs'), 'utf-8');
As #doug-stevenson pointed out all files are included in the final bundle but for some reason using the relative path did not work. Forcing an absolute path with __dirname did the trick.

Node / express - require exported js file inside route file

I created an app using express generator. I have a js file in my public/javascripts directory. I exported an obj:
module.exports = { my obj here }
Then in my route file (index.js) I've been trying to serve this object as an API so I can fetch it from another js file and do stuff on the front end.
But my require simply won't work. I tried:
var specs = require('./javascripts/specs')
and all variation of the path cause I assumed that my path was wrong.
Am I missing something obvious? I get the following error:
Error: Cannot find module '/javascripts/specs'......
File Structure
https://www.dropbox.com/s/ou9afzckboxbe1w/Screenshot%202018-04-18%2011.59.32.png?dl=0
Your public folder and your routes folder are on the same level in your directory. Therefore you need to go up to the common parent, then down through public/javascripts like this:
var specs = require('../public/javascripts/specs');
Your public/javascript is for client only scripts, if you want to require it from the server you have to provide the full path :
var specs = require('../public/javascripts/specs');

NodeJitsu error: Error: ENOENT, stat '/opt/run/snapshot/

My app’s folder structure for NodeJitsu is as follows (i.e., when i do a jitsu deploy, I'm in the folder that contains "server.js" - i.e., the "server" folder).
Root server
|___server.js
|___package.json
client
|___www
|___index.html
|___css
|___js
|___etc.
So at the root is the folder "server", containing the starting script, “server.js”. Then there’s a folder called “client”, parallel to "server", with a folder within that called “www”, and within “www” is the main “index.html”.
In my “server.js” file, I have the following code:
app.get(‘/’, function(req,res)
{
var aPath = path.resolve(“../client/www/”, “index.html”);
res.sendFile(aPath);
});
I don’t have a app.use(express.static(__dirname + '/somefolder'). And when I start the app, I get this error:
Error: ENOENT, stat '/opt/run/snapshot/client/www/index.html'
My process.cwd() is /opt/run/snapshot/package. Obviously the above path isn’t pointing to the location where “index.html” resides. But I thought the way I do the path.resolve(…) should point to “index.html”. I can’t see where the problem is. If “server.js” is in the root, then to get to “index.html”, which is in “client/www/index.html”, then I should need to write “../client/www”, relative to the excuting script, to get to “index.html”, right?.
Do you have any insights as to where the path is not set up correctly? What should /opt/run/snapshot/ be pointing to? Or, what changes do I need to make in the get(‘/’) handler to correctly point to my “index.html”?
EDIT
I incorrectly drew the folder structure. Now it's correct.
I also turned off the app.get() and turned on the app.use(express.static(__dirname + '/../client/www/'). But to no avail: now i get a Cannot GET / error.
What I'm ultimately after is to have the "server.js" file be the Node server that, mostly, just serves AngularJS HTML files to the browser, with attendant images, stylesheets, etc., from the "client" folder. This is the server's main role, with an additional role of authenticating the app's users, employing the very nice Satellizer module. And that's it. I have a MongoDB attached, but otherwise this is a very common and straightforward Node.js server app.
Thanks!
Try it without rooting, resolving and log out to double check:
// notice no leading / which is root. __dirname should be the dir of current file running
var staticPath = path.resolve(__dirname, '../client/www');
console.log(staticPath);
Then pass that into express.static
app.use(express.static(staticPath);
I would probably recommend following the layout and convention of express generated apps with app in the root and static files under public
/public
<static files>
app.js
Then do what the generated app does:
app.use(express.static(path.join(__dirname, 'public')));

Setting Up Node.js App Directory

I'm completely new to using Node.js and even utilizing the command line, so this question may be extremely elementary, but I am unable to find a solution.
I am trying to set up an app directory using Node.js and NPM. For some reason, whenever I try to use the port:5000 I get a "Cannot GET/" error. My question is, why is my setup for my app directory not working?
I have installed connect and serve-static, and yet it will not retrieve files and listen on port 5000. I have created a server.js file in my user, kstach1. Here is the code I have within that file:
var connect = require('connect');
var serveStatic = require('serve-static');
var app = connect();
app.use(serveStatic('../angularjs'));
app.listen(5000);
So, I don't quite understand why this won't reference my folder of angularjs, where I want to store my app. I have tested it by adding a file within the folder called test.html, and entered localhost:5000/test.html, and still get the "Cannot GET/test.html" error.
I know that Node is working correctly because I can enter scripts into the command line and they give the correct output. I do this as a user (kstach1).
The only thing I can think of that I may be doing wrong, is where my files are located. I have the angularjs folder located in the root user folder on my Mac (kstach1), as well as the server.js file. Is this incorrect? If this is not the issue, is it because of where Node is installed (usr/local/bin/node)? My research to this point has led me to think that my problem could also be that I need to add the installation directory to my path. However, I don't want to mess with this unless I know that is the case.
Any help would be greatly appreciated.
I did a little research on the serve-static package and copied the code you provided.
My project folder is located at "C:\teststatic" and the folder with the static files is: "C:\angularjs", also using "text.html" that is located in the 'angularjs' folder.
When running the code you provided and going to localhost:5000 it indeed returns "Cannot GET/". This is most likely because there is no "/" file declared.
Going to localhost:5000/test.html works for me, so you could try setting a "/" like this:
app.use(serveStatic('../angularjs', {'index': ['test.html', 'index.html']}));
And see if that works for you. If not, you should double check directory names / locations.
EDIT:
From reading the comment you posted: try this instead:
app.use(serveStatic('angularjs'));
I suggest moving your angularjs folder up into your main project's directory in a public/ folder. Its a pretty standard convention to have all of your static assets in public/. You can then use the path module to automatically resolve your path, inserting this where you have '../angularjs': path.join(__dirname, 'public').
So, your code would look like this:
var connect = require('connect');
var serveStatic = require('serve-static');
var app = connect();
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public'));
app.listen(5000);
And, your directory structure would look like this:
server.js
public/
angularjs/
test.html
You should then be able to use localhost:5000/angularjs/test.html to view your test.html

Resources