what does "./" path specification means? [duplicate] - javascript

This question already has answers here:
What does "./" (dot slash) refer to in terms of an HTML file path location?
(12 answers)
Closed 8 years ago.
I have been reading through RequireJS
i dont get the difference between
define(["./cart", "./inventory"], function(cart, inventory) {...}
and
define(["cart", "inventory"], function(cart, inventory) {...}
what difference does the "./" makes?? and what alternative do we have to do , to use dependency paths without "./" ?

Generally speaking, the presence of ., .. and / in module names in RequireJS has the same meaning as for HTTP paths.
The presence of ./ in a dependency tells RequireJS to start its search from the current directory. It is extremely useful if what you want is use a module which you know is located in the same directory as the one that needs it. Let's say moduleA needs moduleB and both are in the same directory then moduleA can just require "./moduleB". One advantage of doing this is that you then don't have to worry about where the modules are stored. If you move them around but they are always together in the same directory then moduleA will always find moduleB.
Another thing is that if you require("moduleX") and there are multiple modules named moduleX available, which module are you going to get? Relative paths clarify which one you are going to get.
You ask how you can get rid of the ./ First, I'd ask do you really want to get rid of it? In the scenario I gave where two modules are in the same directory and this relation is meant to be stable, then it does not make sense to get rid of ./. It actually helps people reading the code. If what you are requiring is something like jQuery, which happens to be located in the same directory as another module at some moment but could legitimately be installed somewhere else, and which you would conceivably want to be unique for a given application, then it makes sense to have it be at a global well-known location. To do this, you use paths in your requirejs configuration, like:
paths: {
'jquery': 'external/jquery-1.9.1'
}
This is an actual piece of code part of an actual application. No matter which module wants jquery, it just issues require("jquery"). It does not have to worry about were jquery is located relative to itself. You can specify a path like this for any module you like, not just jQuery. If jQuery moves to a different location in the future or you want to serve it from a CDN, then this mapping in the snippet above is edited, but require("jquery") still works.

In context of your code, it means define cart in same directory as the current executing script.
The alternative is to use absolute paths:
/var/www/site/cart
as:
define(["/var/www/site/cart", "/var/www/site/inventory"], function(cart, inventory) {...}

Wikipedia
define(["./cart", "./inventory"], function(cart, inventory) {...}
it search specific file in current directory in filesystem
define(["cart", "inventory"], function(cart, inventory) {...}
it search specific file in root directory in filesystem

./ is refers to the current directory, to get the module currently in the same directory as the script. No ./ refers to the node path, where native and installed modules go (e.g.: net, fs, and anything use install via npm) Using an absolute path can get anywhere in the filesystem (/i/like/node/js/modules.js)

'/' refers to the root directory and
'./' refers to the current directory
define(["./cart", "./inventory"] : This will refer cart in the current directory where script is being executed.

./ means that you'll stay in the same directory.

Related

Better usage of require() in child module

after Googling around for a few hours on this topic to no avail, I'm hoping someone on here might be able to help clarify this piece of my project for me...
I have a project that has modules that it loads via require() and is able to name them explicitly as they are included in the package.json and have the "main" attribute in their package.json files themselves.
example: require('submodule-name')
The functionality works perfectly, but in each of these modules, I have to require the main file like so: const mainModule = require('../../mainModuleName');
This is so I can access functions and config variables that are attached to the main piece.
I'm wondering if there is a better way to require() this main module without a relative path, since my linter is complaining that the module doesnt exist when I lint the child-module repo on its own. Also, I'd like to employ the use of npm link for future development happiness.
Is there a way of doing this without relative paths? Maybe fix the package.json of the main project file?
UPDATE:
File/folder structure is as follows:
/
mainModule.js
/node_modules
childModule.js <- this requires the mainModule file with a relative path
/modules
anotherChildModule.js <- same relative path requirement of mainModule
I think the problem is in the approach itself. Submodules should not depend on the main modules, as this reverses the dependencies (now the submodule depends on the parent module implementation). I recommend you avoid requiring parent directories, and pass the functions & config to the submodule when you require it instead.
eg: const sub = require('submodule-name')(config)
As an alternative option, NPM supports importing local dependencies therefore you can create a "config" package that you could include in both your sub modules e.g.
package.json
"myconfig": "file:./common"
childModule.js
const config = require('myconfig')

Node.js package self-reference

Can package require itself and its subsystems?
For instance there is module:
src/deep/path/to/module.js
which need to require
src/another/module.js
Instead of:
require('./../../../another/module.js');
Can one just:
require('<self>/another/module.js');
?
For instance this might be useful in testing: test unit can reference its test object without long up-and-down-style path.
I have two considerations (but they do not satisfies this issue completely):
If package is already in node_modules folder it can reference to itself by its
canonical name (that in its package.json).
Package can create symlink to itself in its own node_modules folder (sic!). Haven't try it yet, possible will lead to infinite loop in some resolving cases.
Solution 1
Split it to different sub-projects, put each one into different folders. As an example:
sub.project.1/
sub.project.2/
in sub.project.1/
# cd ../sub.project.1
npm link
# cd ../sub.project.2
npm link sub.project.1
Then in sub.project.2 you can do it simply:
var something = require("sub.project.1")
This can remove the '../../...' relative path.
Note: it can be done in same folder/project, by doing this,
in the sub folders, the project self can be easily referred.
For example when both sub.project.1 and sub.project.2 replaced by my.project. And of course, all the names should be the name in package.json initialized by npm.
Solution 2
Create a link in the folder node_modules/
# cd node_modules
ln -s .. myProjectRootDir
#
# where: .. : means parent directory in linux shell
# '#' means comments in linux shell
#
Then it can be used under same level directory trees:
var something = require("myProjectRootDir/path/to/js/file")
Thus the "../../..." can change to path read more easily.
And if myProjectRootDir happens to be the project name and
package name in package.json, it's ok.
Solution 3
There are npm packages: require-self, install-self,
they do the similar things.
Solution 4
Write a new .js file where it's easy to require,
then put all the annoying relative references into it.
For example write it at node_modules/mymods.js
// mymod.js
module.exports.mod_one = require("../path/to/mod/one.js");
//...
Then require('mymod') can gives all the other modules.
This is not the best solution, all references of requiring
need to be doing by hand. But it's a single file, so it's
manageable, and centralize the references for future deployments.
One of the cons of this solution is, if you put it in
node_modules/ folder and this folder is ignored in git repository, you need to take care when pushing or branching the git repo.
When deleting the node_modules folder, the file can also be deleted by accidents.
There could be more solutions I don't know.
Well you can shorten it a little bit. You don't need the leading ./ in this case
require("../../../another/module.js");
And a little further by removing the trailing .js
require("../../../another/module");
Another answer is suggesting the use of process.cwd() but be very careful with this. Your require calls will only work if the app is initialized from the same directory.
From the sounds of it though, 4 directories is already pretty deep. You might want to considering fragmenting your large project into smaller, single-purpose modules. We would need more information on the project to know if that was the right decision though.
I often use process.cwd() to make things like this a little more manageable. This returns where the node application is actually running from and lets you create the path in a little cleaner fashion.
Something maybe like var x = require(process.cwd() + '/lib/module')
Without seeing exactly what you're trying to do; I'm not sure if this will be helpful, but you can do things like var connect = require('express/connect') as well. Basically you can pass an installed local module, and then create paths off of it as well.

Nodejs get directory of `required` module

Is it possible to determine the directory where required scripts come from?
My ultimate goal is to...
// return the directory where `mysql` module is found
var mysqldir = requiredir('mysql')
if(fs.existsSync(mysqldir+"/README.md")){
console.log(fs.readFileSync(mysqldir+"/README.md").toString())
}
So I can have a handy reference for all these modules, and hopefully people in the enlightened future, will include module docs/cheatsheets intended to be accessed in this manner
required.resolve(...) may be what you're looking for:
function requiredir(id) {
return path.dirname(require.resolve(id));
}
Though, this will follow the main setting:
> requiredir('grunt')
.../node_modules/grunt/lib/
(Update: Documentation for the API isn't available anymore, so its use likely isn't supported.) Another option may be to use npm's view, though this is limited to registered packages:
npm.load({}, function (err) {
npm.commands.view(['mysql', 'readme'], true, function (err, readme) {
console.log(readme);
});
});
If you want to determine the absolute path of a module you can use require.resolve('module')
http://nodejs.org/api/globals.html#globals_require_resolve
You can extract the folder path by a regular expression
If you'd like to know programmatically, the module main directory which nodejs is using, this works
require.resolve('module_name').replace(/(.*node_modules.)(.*?)(\/)(.*)/, `$1$2`)
Example
For example, if you want to know where is the module main directory of module jquery which you're using in your nodejs code, the first part
require.resolve('jquery')
returns (in my case)
/home/jfolpf/autocosts/node_modules/jquery/dist/jquery.js
Pay attention that jquery.js is not stored in the module main directory; nonetheless
require.resolve('jquery').replace(/(.*node_modules.)(.*?)(\/)(.*)/, `$1$2`)
returns
/home/jfolpf/autocosts/node_modules/jquery
This takes into account that to resolve a module's path, node always seeks recursively for the folder named node_modules, as can be seen in documentation.

node.js require relative paths

I have node.js modules in several directories because I am following MVC pattern. I am in need to call require to several modules which are located outside current directory. How can I do that?
/app/controller/c1.js
...
/app/model/m1.js
...
/app/view/v1.js
...
/app/view/v2.js
// this works
require('./v2');
// these doesn't work
require('../model/m1.js');
require('~/model/m1.js');
...
Why is that so?
For modules in other directories, use the format:
testAuth =require('./public/javascripts/test.js'),
//in case the test.js is in the public/javascripts directory (I am using Linux)
If you skip the '.js' extension, node should look for .js first before .json etc.
hope it helps.
check out this project
https://github.com/nadav-dav/rekuire
it allows you to use "require" without the relative paths, just stating the file/class name

nodeJS require.paths resolve problem

I am trying to require a file relatively and mysteriously the following is happening
This works well which points to /Users/marcos/Desktop/Taper/lib/utils.js
myPath = "/Users/marcos/Desktop/Taper/lib/./utils";
require(myPath);
This doesn't but it should point to exactly the same file:
require.paths.unshift("/Users/marcos/Desktop/Taper/lib")
require("./utils"); //Doesn't work with './'
require("utils"); //Works Fine
Anyone knows why I can't still use ./ in this case for loading the path since
require("path").resolve("/Users/marcos/Desktop/Taper/lib", "./utils")
results in:
"/Users/marcos/Desktop/Taper/lib/utils"
anyway?
Thanks in advance
UPDATED:
From the documentation:
A module prefixed with '/' is an absolute path to the file. For
example, require('/home/marco/foo.js') will load the file at
/home/marco/foo.js.
A module prefixed with './' is relative to the file calling require().
That is, circle.js must be in the same directory as foo.js for
require('./circle') to find it.
Without a leading '/' or './' to indicate a file, the module is either
a "core module" or is loaded from a node_modules folder.
If the given path does not exist, require() will throw an Error with
its code property set to 'MODULE_NOT_FOUND'.
Here’s the original answer, which refers to require.paths (which is no longer supported):
From the documentation:
In node, require.paths is an array of strings that represent paths to be searched for modules when they are not prefixed with '/', './', or '../'.
(emphasis mine)
You can pass that using NODE_PATH
Example:
NODE_PATH=`pwd` node app.js
I created a new node module called rekuire.
It allows you to "require" without using relative paths.
It's a big time saver when it comes to testing/refactoring.
https://npmjs.org/package/rekuire

Categories

Resources