Setting a path for require in node.js - javascript

I have a folder structure like this.
include/
index.js
plugin/
plugin.js
helper.js
Where:-
include/index.js
//Function for mapping the path of "require" statement in the plugin.js file.
var mapRequirePath = function(){
var plugins = require('./plugin/plugin');
return plugins;
}
//Now call the plugins..
var plugin = mapRequirePath();
include/plugin/plugin.js
/*
I want all four require statements to point to the same file location '/include/plugin/helper.js'
i.e search in the same folder location for module irrespective of the '../' or '../../' present in the require statement
*/
var helper1 = require('./helper');
var helper2 = require('helper');
var helper3 = require('../../helper');
var helper4 = require('../helper');
I want to map the path of require in plugin.js file so that all require call should search for its module in the same directory only.

You might be able to dynamically change the NODE_PATH environment variable:
// First take a backup:
var _NODE_PATH = process.env.NODE_PATH;
// Add /includes/plugin to the path, also note that we need to support
// `require('../hello.js')`. We can do that by adding /includes/plugin/a,
// /includes/plugin/a/b, etc.. to the list
process.env.NODE_PATH+=':/includes/plugin:/includes/plugin/a';
// Do your think...
require('./plugins/plugin');
// Restore NODE_PATH
process.env.NODE_PATH = _NODE_PATH;

Try changing the NODE_PATH variable via the command line:
exports NODE_PATH=directoryYouWant
If you don't want to have to change it for every other project, you could try just dynamically changing it in you .js file:
var currentNodePath = process.env.NODE_PATH;
process.env.NODE_PATH = directoryYouWant;
//do stuff then change it back
process.env.NODE_PATH = currentNodePath;

If your wanna add /foo/bar to require:
by editting process.env.NODE_PATH
then your js files should reside inside /foo/bar/node_modules/
process.env.NODE_PATH = '/foo/bar' + ':' + process.env.NODE_PATH;
by editting module.paths
then your js files should reside inside /foo/bar/
module.paths.push('/foo/bar');

Related

Loading an asset within the app.js Symfony 4 file

I'm looking to mainstream a certain asset loading within app.js
My assets get built like such: public/build/images/icons/**.svg
Within my app.js file, I have the following:
/*
* Welcome to your app's main JavaScript file!
*
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
// any CSS you require will output into a single css file (app.css in this case)
import '../sass/standards.scss';
// Need jQuery? Install it with "yarn add jquery", then uncomment to require it.
const $ = require('jquery');
$(window).on("load", function() {
$(".icon").each(function(){
var $classes = $(this).prop("classList");
var className;
$.each($classes, function(){
if(this.match("^icon-"))
{
className = this;
return;
}
});
className = String(className);
var fileName = className.replace("icon-", "") + ".svg";
$(this).load("public/build/images/icons/" + fileName);
})
});
The idea is to find any .icon element and inject it with the appropriate SVG file that I have in the assets folder. But the problem is, there is also some caching happening so the file names change for version controlling. Is this the correct way to call an asset through the app.js file?
What's the proper way?
You need to require the file before using it. Docs.
// assets/js/app.js
// returns the final, public path to this file
// path is relative to this file - e.g. assets/images/logo.png
const logoPath = require('../images/logo.png');
var html = `<img src="${logoPath}">`;

calling a function in another file in javascript using node.js

I have a problem, i am trying to create an object that i can use over and over in a separate javascript file. I have a file called foo.js and another file called boo.js. I want to create the object in boo.js In my server.js file i required foo.js, and it works fine i can access foo.js. I want to be able to access boo.js from foo.js. I keep getting errors when i require boo.js in foo.js and i cant access it. Is There a way to do this?
here is my code
//boo.js
var obj = function () {
return {
data: 'data'
}
}
module.exports = {
obj: obj
}
foo.js
//foo.js
var request = require('request');
var x = require('./modules/boo')
var random= function() {
return x.obj();
}
module.exports = {
random: random
}
If they are in the same directory you will want to require like so var x = require('./boo'). The ./ is relative to the current directory.
they are both in the same directory
In that case, you'll want to remove the modules/ from the path:
var x = require('./boo');
require() is aware of the current script's location and bases relative paths from the script's own parent directory.
The ./ at the start of the path will refer to the same directory as __dirname, which seems to be modules/.
console.log(__dirname);
// "/project-path/modules"
Including modules/ in the path will result in doubling it:
var path = require('path');
console.log(path.resolve(__dirname, './modules/boo'));
// "/project-path/modules/modules/boo"
(Side note: The fs module does not behave the same way. Relative paths for it are based from the current working directory or process.cwd().)

Obtaining path in nodejs

My Directory structure is something as below:
app/
server/
api/
user/
controller.js
images/
image1.jpeg
The problem is when reading image1.jpeg within controller.js I have to use a string like
var imagePath = __dirname + '/../../../images/images1.jpeg';
fs.readFile(imagePath, ()....
now the above works FINE. however what I don't like is this string '/../../../'
is there a better way to access files in the images/ folder ?
You could use path.relative. You'd probably want to save these as constants but you could do the following to make things more readable.
Pass in the path to your current directory as the first parameter and the path to the image itself from the same parent directory (in this case app) and it will return the relative path from the current directory to the image.
// returns '/../../../images/images1.jpeg'
var relativePathToImage = path.relative(
'/app/server/api/user',
'/app/images/images1.jpeg');
var pathToImage = __dirname + relativePathToImage;
Short of passing the path to app/images to the controller, that's about as good as you can do.
You could traverse the module.parent references until module.parent isn't set, if you can safely make assumptions about where your main script is. For example, if your main script is app.js inside app/, you could do something like:
var path = require('path');
var topLevel = module;
while (topLevel.parent)
topLevel = topLevel.parent;
topLevel = path.dirname(topLevel.filename);
var imagesBasePath = path.join(topLevel, 'images');
// ...
fs.readFile(path.join(imagesBasePath, 'images1.jpeg'), ...);
I use an npm module called node-app-root-path to help me manage my paths within the NodeJS application.
See:
https://github.com/inxilpro/node-app-root-path
To obtain the application's root path you would do require('app-root-path');
Example:
global.appRoot = require('app-root-path');
var imagePath = global.appRoot.resolve('server/images');
var img1 = imagePath + '/image1.jpeg';
fs.readFile(img1, ()....
Not sure whether is it a good idea or not but for this case I have stored the appRoot as a global variable and this is so that it will be available anywhere within my NodeJS application stack, even to some of my other NodeJs libraries.
There are many other usages noted in their documentation, have a look and see if it helps you too.

Is it possible to require modules from outside of your project directory without relative paths?

I'm trying to build a local library of JS modules to use in Node projects.
If a new project lives in /Users/me/projects/path/to/new/project/ and my library files are located in /Users/me/projects/library/*.js is there a way to access those files without using a relative path?
In /Users/me/projects/path/to/new/project/app.js you can require foo.js like so:
var foo = require('../../../../../library/foo') and that will work but that's clunky and if files move you'd have to update your relative paths.
I've tried requireFrom and app-module-path with no luck as they are relative to a project root.
Any ideas for how to require files from outside of your project dir?
Thanks in advance!
var librarypath = '/Users/me/projects/library/';
// or if you prefer...
// var librarypath = '../../../../../library/';
var foo = require(librarypath + 'foo.js');
... or dressed up a bit more ...
function requirelib(lib){ return require('/Users/me/projects/library/'+lib+'.js'); }
var foo = requirelib('foo');
var bar = requirelib('bar');
I had the same problem many times. This can be solved by using the basetag npm package. It doesn't have to be required itself, only installed as it creates a symlink inside node_modules to your base path.
const localFile = require('$/local/file')
// instead of
const localFile = require('../../local/file')
Using the $/... prefix will always reference files relative to your apps root directory.
Disclaimer: I created basetag to solve this problem

Best way to load modules node.js

My project has got many folders and I often load my own modules in node.js in the following way:
var request = require("request"),
config = require("../../../modules/config"),
urls = require("../../../modules/urls");
I sometimes move the folders around and the path changes, so I need to adjust the ../ part manually.
I don't want to move my modules into the node_modules folder, but I'd like to load the modules in the following way:
var request = require("request"),
config = require("config"),
urls = require("urls");
or
var request = require("request"),
config = require("modules/config"),
urls = require("modules/urls");
What are my options?
New Answer:
Relative paths seem to be the simplest choice after all, it allows you to run your script from any location.
var config = require("../../config");
Old answer:
I found out that, while not ideal, there's also the possibility to use process.cwd().
var request = require("request"),
config = require(process.cwd() + "/modules/config");
or, if the process.cwd() is set to a global variable in the main js file
global.cwd = process.cwd();
then
var request = require("request"),
config = require(global.cwd + "/modules/config"),
urls = require(global.cwd + "/modules/urls");
You can try to do the following, based on some conditions
if the scripts are exclusively written for your application, meaning it won't work with any other application, and the scripts don't have any dependencies place them under modules directory and try to create expose a variable such as global.basepath and using path.join to construct the filepath and require it.You could also inject module variable after you require them at the main script of your app.
main.js
var config = require('modules/config.js')(_,mongoose,app);
modules/config.js
module.exports=function(_,mongoose,app){
return function(){
// _,mongoose,app
this.loadConfigVariable..
}
}
if the scripts are not one-files that have separate tests, require other vendor modules in order to be executed then create individual node modules and publish them to a registry for convenience when installing the main application.
Just as express does, there is the main application express and there are modules that express uses such as express-validation which in turn has its own dependencies.
You could add a symlink in node_modules, pointing to wherever your modules are.
For example, add a symlink named "my_modules", referencing '../foo/bar/my_modules'. Then, your requires will look like
var config = require('my_modules/config');
var urls = require('my_modules/urls');

Categories

Resources