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.
Related
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')
hello and today i want to know if i can have only one node_modules folder for all my node js bots, note they are not in app form just single files that use ..... = require('module'); my point is that i have easily more than 7 bots and i go back and forth improving them and maintaining the node_modules folder can be tedius, is there a way where i can have only one folder with all my modules and just do .... = require('path/to/node_modules/module');
or .... = require('path/to/node_modules/'); could someone please point me in the right direction, because when i update my code on my various bots i have to make sure the module is installed, can i have only one node_modules folder???
I can think of these different options:
You can put all your bot files in the same directory and run them all from that directory so all the modules installed in that directory can be used by all the bot files.
You can install all your modules globally.
You could make one shared directory where you installed all the modules and then explicitly point to that every time you want to load a module by referencing that path. This seems less clean because every single user of a module has to know where to load it from.
For each module you want to use in a project, create symlinks to the place where the modules are actually installed. This doesn't seem like it saves any work over just installing the modules again for each bot though.
In another file say myLibs.js you could do something like
module.exports = {
lib1: require('lib1'),
...
libn: require('libn')
}
then in the original file you would do
var myLibs=require('./myLibs.js');
and reference them by myLibs.lib1...
A little clunky, I know, but it should work.
I want to do something like:
var dynamicRequire = require.context('./', true);
console.log(dynamicRequire.keys());
dynamicRequire('react/foo/bar');
But the console.log only shows files from the local directory, not the npm packages. When webpack builds i can see it get included as number 234 but the mapping from that path to that number is lost. How can I accomplish this? Thanks!
I'm not sure, what your problem exactly is here, but I suspect, that for your purpose you have just forgotten to provide require.context with second argument, which is a flag, that decides, whether the webpack should look into your subfolders and pick your files there also. So you could use require.context('./', true, [some regexp maybe ?]).
Let me know if that's not addressing your problem.
I have more than javascript files in my html documents as external which I'd like to combine on account of not to be crowded. is there any way to combine my js files ? for example;
my files:
a.js
b.js
c.js
d.js
and i want;
all.js
Take a look at requirejs.org and especially look at r.js (http://requirejs.org/docs/optimization.html)
a.js
var i=0;
function fun1()
{
...
}
b.js
var k=0;
function fun2()
{
...
}
all.js just copy, paste like css
var i=0;
function fun1()
{
...
}
var k=0;
function fun2()
{
...
}
take care of semicolons and closed braces when you purticularly write whole script in an eventlistener, especially 'DOMContentLoaded'
document.addEventlistener('DOMContentloaed',function()
{
//whole big script
}
);
instead use
document.addEventlistener('DOMContentloaed',some_function);
var some_function = function(){*bla bla bla*};
A simple bash cat operation will do what you want, but, at some stage you're probably going to want more right?
Grunt and Grunt-contrib-concat is a good starter, but you'll quickly realise grunt is not particularly good. To summarise usage, you create a gruntfile, install a few dependencies (i.e. install grunt and its command line interface, this is easy) and run grunt from your project root. It then parses the gruntfile to find out what you want it to do, and it does it. Pretty simple, and simple is good.
Next up is Gulp, which is a nice build system using streams, so, slightly more complex (well, easier and more powerful but, streams can be kind-of confusing at first). Gulp works in the same way only it parses a gulpfile for instructions. For a concat operation the actual gulp command is trivial:
gulp.src( '*.js' )
.pipe( gulp.dest( 'all.js' )
Between the .src and the .dest you can pipe the files through multiple transforms, such as minifying, transpiling, notifying—the list of plugins and modules is dizzying (as it is for grunt).
However, if you’re a fan of node and npm (you probably should be) then you can use npm scripts to create a build system. npm is the node package manager and requires a package.json to give some clues as to how to work. Part of that json specification is a scripts block
"scripts": {
"build" : "cat *.js > all.js"
}
You can then use npm run build from the command line, whereby npm will parse the package.json and execute the script using bash (sh actually).
Note that these are build systems, and there are many others.
There are also other packagers (which you would probably use as part of your build system, although for some projects they are you entire build system) but they are more complex than your needs, for your own research browserify, webpack and jspm are all excellent (bare in mind AMD modules lost so require.js is probably not worth your time), although this area is becoming congested. Each of these are very powerful modularisation tools, but they will require some changes to how you structure your code. If you are serious about modularisation then they are worth your time learning.
On a slightly different tangent, there is some discussion about whether one large file is actually more beneficial than a number of smaller scripts. In many cases simply serving a few small files is actually quicker, and may be easier, although there can be other benefits of smashing code together. Currently it is probably still best to concat at least into less HTTP requests, but this requirement for performance is going away.
It might be helpful : https://github.com/mrclay/minify
OR
create file all.js and paste a.js,b.js,c.js,d.js file code
If I have a node.js application that has hundreds of files that reference a module (say underscore) and I want to replace that module with another (say lodash) then the obvious way to do this substitution would be a global name replace and switch out the modules in the package.json file.
Is there anyway to just change the module that a name refers to so that when node.js sees require('moduleA') it actually loads 'moduleB' instead? Now I know that this would cause naming hell because anyone working on the project would see require('moduleA') and wouldn't know that the real module being loaded was 'moduleB' so ultimately you'd probably want to go with the first solution. The use case that I'm thinking of is if you want to try a few alternatives for API compatible modules to measure your application's performance (for example) with each module.
If this is an on-going thing and you want to maintain the ability to programmatically switch between the options often, such as in tests:
Instead of using require("underscore"); throughout your codebase, require a local file instead like require("./lib/underscore");, and have that file conditionally re-export underscore or a different library:
if (global.USE_LODASH) {
module.exports = require("lodash");
} else {
module.exports = require("underscore");
}
If this is a one-off thing to try out an alternative library before making the decision to switch, and you want to do this test quickly first without find-and-replacing in all of your files:
Go inside your node_modules folder, delete or rename the underscore folder, and make a symlink named underscore to the replacement module's folder. I don't recommend this as a long-term solution: running npm install again will likely undo this hack, and most projects choose to avoid checking the node_modules folder into their source repository.
Try to use mock-require module.