Do each parent directories need to have their own node_modules folder? - node.js

I am working on an app powered by node which has a few (three) different folders. It looks like this:
Client-
Server-
-node_modules
-mongoose
Database-
-index.js
Config-
-credentials.js
I have made an exports object with all of my passwords and put it in the database folder (this way I can easily ignore it from being checked in to any version control).
I am wondering if there is a way to have ALL of the node_modules used by my server and database directories in the server directory so that the package.json file in my server directory would contain all of the needed packages for the "backend" of my project.
However, when I do this, and try to require(mongoose) from the Database/index.js file, I get "cannot find module" errors. I tried the following combinations and still get the error in every case:
require(mongoose) require(../server/mongoose) require(../server/node_modules/mongoose)
Installing the mongoose module directly in the Database directory fixes this problem but this means that I have to have a node_modules (and thus package.json) file in each directory. Is that the right way to fix this issue or is there a more simple solution?
Thanks

Maybe you find interesting having a look at the following article: "Where does Node.js and require() look for modules?", in order to understand why the different ways you are trying to "require" mongoose are not actually working - and that is because the way you are organizing your code (your node_modules directory is inside your Server and your Database directory is under the / - root directory).
So, in your case, you will have to specify your /Database/index.js the relative file path to mongoose in order to find your module:
require('../server/node_modules/mongoose');
Another solution (I personally organize my code like this) would be moving your database code within the server code; after all, it's all backend code.

I aware this not elegant way but i have an advice for your case.
You can try like below;.
var mongoose = require('../server/node_modules/mongoose/index');
I was simulated your case in my local and this worked.

Related

Cloud Foundry - Folder structure and relative paths

This is somewhat related to an issue I'm having with CF on IBM Cloud here. My question after playing around with the folder structures is how exactly is CF building the app when it comes to relative paths?
For example, if i have the following folder structure
when I add <script type = 'text/javascript' src = '../index.js'></script> to the index.html file, I get GET https://simple-toolchain-20190320022356947.mybluemix.net/index.js net::ERR_ABORTED 404. This error does not happen when I move index.js into the public folder and change <script type = 'text/javascript' src = 'index.js'></script>.
The problem I have then is that when I try to require() any modules when the index.js file is in a sub-directory, it returns a Require is not defined error indicating that it is not getting the module from the node_modules cache which CF is suppose to build. Requiring any files in the same sub-directory also throws the same error. This does not seem to be a problem when the require() is used in the default app.js as the application loads without any errors.
I'm relatively new to the IBM Cloud Foundry tool but I'm following the same structure as when I pushed apps via Cloud9 IDE and didn't have any such issues there. I feel I might be missing something ridiculously simple like configuration of endpoint or package.json. However, I've been searching around for days and can't seem to find a solution.
Appreciate if you have any pointers. Thanks!
Due to my lack of understanding, I was trying to use require() on the client side hence the errors. Going to figure out how to use Browserify now. ;)

How should I load a file that is inside my own module?

Current code in /config/index.js
const options = (require('js-yaml')).safeLoad(
(require('fs')).readFileSync(`./config/default-config.yaml`, "utf8"));
module.exports = options;
Works fine. Until I publish and use it in my other project. Then it's unable to find the file (naturally) as ./config/default-config.yaml doesn't exist in that project.
The only option I can think of involves checking to see if the file exists at that path, then trying to load it from node_modules/#company/alpha-gamma/config/default-config.yaml. This seems really hacky.
The config object is large, 200+ keys. I don't think it belongs in the code.
What's the best solution for loading a file that exists inside your module? I need to be able to load it for unit tests before publishing and load it at runtime when the library is required by another module.
Maybe the best alternative is to use json since I can then use the require module to load it in, instead of fs.
While I originally suggested utilizing __dirname as a valid option, I was wrong. Calling process.cwd() to fetch the application root and building the path off of that is the best approach.
As documented here:
Proper way to reference files relative to application root in Node.JS

Integrating jQuery-File-Upload plugin with blueimp-file-upload-node npm module

I am trying to integrate the jQuery-File-Upload (https://github.com/blueimp/jQuery-File-Upload) with the npm module "blueimp-file-upload-node" to process file uploads.
Sadly, this package "blueimp-file-upload-node" has not been documented yet.
The frontend integration is working correctly, but I am struggling to get the upload functionality working.
I have read and followed this section:
https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-nodejs which tells me to start the service by running:
./node_modules/blueimp-file-upload-node/server.js (notice, the path of this file is within my node_modules folder)
I would like to have the file uploader as a route of my app, (i.e. /upload) not a separate service, on a different port.
How would I go about that?
My code is here:
https://github.com/robsilva/fileUploader
I really appreciate if anyone can shed some light here.
Seems like you are looking for the express middleware
https://github.com/aguidrevitch/jquery-file-upload-middleware

ExpressJS Static Serve Images

I know there are a bunch of questions on this topic but none seem to directly answer my problem.
I am trying to static serve images from NodeJS using ExpressJS. I've already successfully statically served a CSS file using:
this.app.use(express.static(path.join(__dirname, "style")));
and accessing the file at URL/file.css. However when I try and do something similar for images using:
this.app.use('/images', express.static(path.join(__dirname, "images")));
and I try and access the file using URL/images/file.jpg - I just get an error saying
Cannot GET /images/file.jpg
I've also tried variants without the /images/ similar to the way I've done style and get the same problem. Unsure where I'm going wrong.
The answer was obvious but subtle. I was compiling typescript from ./ and putting it into /dist and sass from /style into /dist/style so I put my images folder at the root level, rather than inside dist. Problem solved.

Meteor.js: How do you require or link one javascript file in another on the client and the server?

1) In node on the backend to link one javascript file to another we use the require statement and module.exports.
This allows us to create modules of code and link them together.
How do the same thing in Meteor?
2) On the front end, in Meteor is I want to access a code from another front end javascript file, I have to use globals. Is there a better way to do this, so I can require one javascript file in another file? I think something like browserify does this but I am not sure how to integrate this with Meteor.
Basically if on the client I have one file
browserifyTest.coffee
test = () ->
alert 'Hello'
I want to be able to access this test function in another file
test.coffee
Template.profileEdit.rendered = ->
$ ->
setPaddingIfMenuOpen()
test()
How can I do this in Meteor without using globals?
Meteor wraps all the code in a module (function(){...your code...})() for every file we create. If you want to export something out of your js file (module), make it a global. i.e don't use var with the variable name you want to export and it'll be accessible in all files which get included after this module. Keep in mind the order in which meteor includes js files http://docs.meteor.com/#structuringyourapp
I don't think you can do this without using globals. Meteor wraps code in js files in SEF (self executing function) expressions, and exports api is available for packages only. What problem do you exactly have with globals? I've worked with fairly large Meteor projects and while using a global object to keep my global helpers namespaces, I never had any issues with this approach of accessing functions/data from one file in other files.
You can use a local package, which is just like a normal Meteor package but used only in your app.
If the package proves to be useful in other apps, you may even publish it on atmosphere.
I suggest you read the WIP section "Writing Packages" of the Meteor docs, but expect breaking changes in coming weeks as Meteor 0.9 will include the final Package API, which is going to be slightly different.
http://docs.meteor.com/#writingpackages
Basically, you need to create a package directory (my-package) and put it under /packages.
Then you need a package description file which needs to be named package.js at the root of your package.
/packages/my-package/package.js
Package.describe({
summary:"Provides test"
});
Package.on_use(function(api){
api.use(["underscore","jquery"],"client");
api.add_files("client/lib/test.js","client");
// api.export is what you've been looking for all along !
api.export("Test","client");
});
Usually I try to mimic the Meteor application structure in my package so that's why I'd put test.js under my-package/client/lib/test.js : it's a utility function residing in the client.
/packages/my-package/client/lib/test.js
Test={
test:function(){
alert("Hello !");
}
};
Another package convention is to declare a package-global object containing everything public and then exporting this single object so the app can access it.
The variables you export NEED to be package-global so don't forget to remove the var keyword when declaring them : package scope is just like regular meteor app scope.
Last but not least, don't forget to meteor add your package :
meteor add my-package
And you will be able to use Test.test in the client without polluting the global namespace.
EDIT due to second question posted in the comments.
Suppose now you want to use NPM modules in your package.
I'll use momentjs as an example because it's simple yet interesting enough.
First you need to call Npm.depends in package.js, we'll depend on the latest version of momentjs :
/packages/my-moment-package/package.js
Package.describe({
summary:"Yet another moment packaged for Meteor"
});
Npm.depends({
"moment":"2.7.0"
});
Package.on_use(function(api){
api.add_files("server/lib/moment.js");
api.export("moment","server");
});
Then you can use Npm.require in your server side code just like this :
/packages/my-moment-package/server/moment.js
moment=Npm.require("moment");
A real moment package would also export moment in the client by loading the client side version of momentjs.
You can use the atmosphere npm package http://atmospherejs.com/package/npm which lets you use directly NPM packages in your server code without the need of wrapping them in a Meteor package first.
Of course if a specific NPM package has been converted to Meteor and is well supported on atmosphere you should use it.

Resources