NodeJS require from unknown child folder - javascript

-- plugins
---- myplugin1
------ core
---- myplugin2
------ core
If this is my directory structure, is there any way for me to import all core folders from plugins without knowing the name myplugin1 etc?
require('/plugins/./core')
I know how to require from parent folders... but there seem to be nothing about child folders?

Node-Cheat available here, run node app followed by npm i glob.
Possible try:
const glob = require('glob');
const path = require('path');
glob.sync('./plugins/**/core/*.js').forEach(( file ) => {
require(path.resolve( file ) );
});
Expected output:
myplugin1 core loading
myplugin2 core loading

You can use require-dir to achieve this.
These will be the steps
npm install require-file-directory
var requireDir = require('require-dir');
var dir = requireDir('pathToyourCoreDirectory');
And inside the above handler function you can require all of the modules

Related

Ignore variable dependency of node_module webpack

I have built a library that I want to use in a Next.JS project. Within this library a certain dependency is using an import via a string passed into a require statement within the source code where the import is taking place. This is causing webpack to not recognize the import. I don't want to change code within any node_modules as this is not a preferred approach but how can I ensure that my project using the library I built is able to compile and run?
Within file_using_string_passed_into_require_to_get_import.js:
let importName = "./potential_import_A.js"
if(condition){
importName = "./potential_import_B.js"
}
module.exports = require(importName)
This is the folder structure:
Project/
| node_modules
| my-library
| node_modules
| library-dependency
| file_using_string_passed_into_require_to_get_import.js
| potential_import_A.js
| potential_import_B.js
To create a local (unpublished) library package
Create a 'my-library' folder (outside your current project dir).
Do npm init (Folder must include the 'package.json' )
Include source code (potential_import_A), exporting any desired functions.
In the actual project folder:
cd into the folder of the project that needs to use your library.
Run npm install --save local/path/to/my-library.
The --save will add the package to your dependencies in the project's package.json file, as it does with 3rd party published packages. It will also add a copy of the source code to the node modules folder of the project, as always.
Importing your new library:
import/require the package as you would normally, from any project.
For example
import { myFunction } from "my-library"
I got it to work by excluding node_modules from the webpack build. Since I am using Next.JS this is within my next.config.js
const nodeExternals = require('webpack-node-externals');
module.exports = {
webpack: (
config,
{
buildId, dev, isServer, defaultLoaders, nextRuntime, webpack,
},
) => {
if (isServer) {
config.target = 'node';
config.node = {
__dirname: true,
global: true,
__filename: true,
};
config.externals = [nodeExternals()], // in order to ignore all modules in node_modules folder
config.externalsPresets = {
node: true, // in order to ignore built-in modules like path, fs, etc.
};
}
return config;
},
};

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

Process.chdir() has no effect on require

Given the structure directory structure:
.
├── alpha.js
└── foo
└── beta.js
And file contents
alpha.js
module.exports = "alpha"
foo/beta.js
var cwd = process.cwd()
process.chdir('../')
var alpha = require('./alpha.js')
console.log(alpha)
process.chdir(cwd)
From within foo/beta.js. I'd like to be able to trick require into thinking that the current working directory is the project root. The example above does not work when the following is run.
node ./foo/beta.js
However if I switch over the code to within foo/beta.js to the following. Reading the file from the system and passing it to the npm module _eval.
updated foo/beta.js
var path = require('path')
var cwd = process.cwd()
process.chdir(path.join(__dirname, '..'))
var fs = require('fs')
var _eval = require('eval')
var alpha = _eval(fs.readFileSync('./alpha.js'))
console.log(alpha)
process.chdir(cwd)
This does work, which proves it should be possible with require as well. No matter where you run if from it will always require the file. node ./foo/beta.js or cd foo && node ./beta.js
Is there any way that I can prepend or set the directory that require uses from within the file?
From the node.js doc for require():
If the module identifier passed to require() is not a native module,
and does not begin with '/', '../', or './', then node starts at the
parent directory of the current module, and adds /node_modules, and
attempts to load the module from that location.
If it is not found there, then it moves to the parent directory, and
so on, until the root of the file system is reached.
From this, you can see that the current directory is not used in loading modules. The main takeaway here should be that modules paths are relative to the location of the current module. This allows modules to load sub-modules in a self-contained fashion without having to know anything about where the parent is placed in the directory structure.
Here's a work-around function that loads a module file descriptor from the current directory if the filename passed to it does not start with a path separator or a ..
var path = require('path');
function requireCWD(fname) {
var fullname = fname;
if (fname && fname.length &&
!path.isAbsolute(fname) &&
fname.charAt(0) !== '.') {
fullname = path.join(process.cwd(), fname);
}
return require(fullname);
}
Then, any filename you give to requireCWD that is not relative and does not start with a "." will be loaded relative to the current working directory. If you want to allow even "." and ".." to be relative to the current working directory, then you can remove that test for '.' from the function.

how to require some npm modules into my js file

i have this index.jade file
include scripts
script( src='path of my site/project name/src/scripts/index.js' )
and also index.js file
var _ = require('./underscore');
var IScroll = require('iscroll/build/iscroll-probe.js');
var zepto = require('./vendor/zepto.js');
var morpheus = require('morpheus');
var easings = require('./vendor/morpheus-easings.js');
require('./vendor/zepto.touch.js');
I am getting ReferenceError: require is not defined
I want to include modules for the correct working any help ?
First :
npm install iscroll --save
Then this :
global.IScroll = require('iscroll');
The type of require you are looking to use is the node type. You can't use it directly in your browser. You need to get a bundler such as browserify or webpack, which would convert those requires to actual dependencies behind the scenes. Here's an article that would get you started with browserify.

Where do we put node modules we install by npm in a Meteor project?

I followed the github meteorirc project's lead and put them in /public/
I installed my node modules via npm from inside /public/ and therefore I have a /public/node_modules/ directory.
I don't think this is the 'proper' or 'standard' place for them because according to the Meteor docs...
Meteor gathers all your JavaScript files, excluding anything under the
client and public subdirectories, and loads them into a Node.js server
instance inside a fiber
The code to load is in the server dir and server js files and looks like this.
var require = __meteor_bootstrap__.require;
var path = require("path");
var fs = require('fs');
var base = path.resolve('.');
if (base == '/'){
base = path.dirname(global.require.main.filename);
}
var Twit;
var twitPath = 'node_modules/twit';
var publicTwitPath = path.resolve(base+'/public/'+twitPath);
var staticTwitPath = path.resolve(base+'/static/'+twitPath);
if (path.existsSync(publicTwitPath)){
Twit = require(publicTwitPath);
}
else if (path.existsSync(staticTwitPath)){
Twit = require(staticTwitPath);
}
else{
console.log('WARNING Twit not loaded. Node_modules not found');
}
Based on the docs this is not standard and I don't believe I should be doing it this way. Yet, it works both on my dev platform and in production at deploy meteor.com.
Where in the directory structure of the project should node modules be installed so that they work locally and upon deployment at meteor.com or elsewhere?
cd /usr/local/meteor/lib/ && npm install <module>
To use Npm modules in Meteor its adding the npm module in.
First you need to add a npm package adapter such as meteorhacks:npm
meteor add meteorhacks:npm
Then start your meteor app by running meteor, you will notice a new packages.json file in your project
Add in modules like this (you need to explicitly define a version)
{
"request" : "2.53.0"
}
Then you can use the npm modules in your meteor app, use Meteor.npmRequire instead of require
var request = Meteor.npmRequire("request")
Meteor takes lib/node_modules from the development bundle and makes a symbolic link or copies it to server/node_modules, which is in the hidden .meteor sub folder under your project.
So, if you cd into the lib directory of the development bundle or into server directory of the .meteor folder (I believe it is in build); you will be able to use the node modules. If you have trouble loading them, you might want to check out this question.
You have to add bundle folder to the path:
var staticTwitPath = path.resolve(base+'/bundle/static/'+twitPath);
Here is my working sample in coffeescript, node_modules are in public folder:
# loading node_modules from public folder
require = __meteor_bootstrap__.require
path = require("path")
fs = require('fs')
cheerioPath = 'node_modules/cheerio'
base = path.resolve('.')
if base == '/'
base = path.dirname(global.require.main.filename)
publicPath = path.resolve(base+'/public/'+cheerioPath)
staticPath = path.resolve(base+'/bundle/static/'+cheerioPath)
if path.existsSync(publicPath)
cheerio = require(publicPath)
else if path.existsSync(staticPath)
cheerio = require(staticPath)
else
console.log('node_modules not found')
Good luck!
This helped me a lot including a syntax highlighting package! Thanks!
I use a little helper though, as I think this will not be the last npm package I'll use ;)
meteorNpm = do() ->
require = __meteor_bootstrap__.require
path = require 'path'
fs = require 'fs'
base = path.resolve '.'
if base is '/'
base = path.dirname global.require.main.filename
meteorNpm =
# requires npm modules placed in `public/node_modules`
require: (moduleName) ->
modulePath = 'node_modules/' + moduleName
publicPath = path.resolve(base + '/public/' + modulePath)
staticPath = path.resolve(base + '/bundle/static/' + modulePath)
if path.existsSync(publicPath)
module = require publicPath
else if path.existsSync(staticPath)
module = require staticPath
else
module = null
return module
Use it like this:
highlight = meteorNpm.require "highlight.js"
I am using such script which nicely install all node.js dependencies. It behaves similar to official support in Meteor engine branch (it installs dependencies at runtime) but it supports also installing from git repositories and similar goodies.

Categories

Resources