access all files in folder in nodejs - node.js

is library versioning is supported in nodeJS?
i have folder like package/version/1.0/
and files under this path
test1.js
test2.js
script.js
//access the folder package of version 1.1
var lib = require('require-all')(__dirname + '/package/version/1.0');
test1.js
========
function sum()
{ a+b ;}
exports.sum = sum;
test2.js
========
function sub()
{ a-b ;}
exports.sub = sub;
in script.js file, can require the package/version/1.1 folder. but how can i access the function sum() and sub() in my script file? and is library versioning supported in nodeJS? is the above code is a sort of library versioning ?

First of all, i haven't seen versions of libraries in one package, most common way is to release new versions of packages and upload them online, defining the required version in a package.json dependencies , npm will take care of download & install
If you want to deprecate a certain version of your library online there is npm deprecate which is the right command for that job.
When you create new npm package you can define a main script which will handle the loading of all files inside the package.
Usually its called index.js or main.js and it will be used when someone calls require('<library>');
So you can try the following to achieve the "versioning"
index.js
var fs=require('fs');
var path=require('path');
var _packageJSON=require(__dirname+'/package.json');
var defaultVersion=_packageJSON.version;
module.exports=function(whichVersion){
whichVersion=whichVersion||defaultVersion;
fs.exists(whichVersion,function(_exists){
if(_exists==null){
throw new Error('Unable to load version : '+whichVersion+' : '+_packageJSON.name);
}else{
// require , 1.0/index.js
require(path.join(whichVersion,'index.js'));
}
}
}
and any script that has that package as dependency it can load it by simply calling
require("<library name>")(<version>) ex.
require("mylib")("1.0")
under each version inside the package, you can have index.js which loads/exports variables and functions properly.
The final structure should look like
my npm package main module
index.js file
versions directory
1.0/index.js file
util.js
fn.js
var.js
2.0/index.js file
util.js
fn.js
var.js
Hope it helps.

Related

How to bundle and require non JS dependencies in Firebase Cloud Functions?

I have an http cloud function that returns some dynamic HTML. I want to use Handlebars as the templating engine. The template is sufficiently big that it's not practical to have it in a const variable on top of my function.
I've tried something like:
const template = fs.readFileSync('./template.hbs', 'utf-8');
But when deploying the function I always get an error that the file does not exist:
Error: ENOENT: no such file or directory, open './template.hbs'
The template.hbs is in the same directory as my index.js file so I imagine the problem is that the Firebase CLI is not bundling this file along the rest of files.
According to the docs of Google Cloud Functions it is possible to bundle local modules with "mymodule": "file:mymodule". So I've tried creating a templates folder at the root of the project and added "templates": "file:./templates" to the package.json.
My file structure being something like this:
/my-function
index.js
/templates
something.hbs
index.js //this is the entry point
And then:
const template = fs.readFileSync('../node_modules/templates/something.hbs', 'utf-8');
But I'm getting the same not found error.
What is the proper way of including and requiring a non JS dependencies in a Firebase Cloud Function?
The Firebase CLI will package up all the files in your functions folder, except for node_modules, and send the entire archive to Cloud Functions. It will reconstitue node_modules by running npm install while building the docker image that runs your function.
If your something.hbs is in /templates under your functions folder, you should be able to refer to it as ./templates/something.hbs from the top-level index.js. If your JS is in another folder, you might have to work you way out first with ../templates/something.hbs. The files should all be there - just figure out the path. I wouldn't try to do anything fancy is your package.json. Just take advantage of the fact that the CLI deploys everything but node_modules.
This code works fine for me if I have a file called 'foo' at the root of my functions folder:
import * as fs from 'fs'
export const test = functions.https.onRequest((req, res) => {
const foo = fs.readFileSync('./foo', 'utf-8')
console.log(foo)
res.send(foo)
})
The solution was to use path.join(__dirname,'template.hbs').
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname,'template.hbs'), 'utf-8');
As #doug-stevenson pointed out all files are included in the final bundle but for some reason using the relative path did not work. Forcing an absolute path with __dirname did the trick.

Module not found error when trying to use a module as a local module

I am trying to understand as how to make a local module. At the root of node application, I have a directory named lib. Inside the lib directory I have a .js file which looks like:
var Test = function() {
return {
say : function() {
console.log('Good morning!');
}
}
}();
module.exports = Test;
I have modified my package.json with an entry of the path to the local module:
"dependencies": {
"chat-service": "^0.13.1",
"greet-module": "file:lib/Test"
}
Now, if I try to run a test script like:
var greet = require('greet-module');
console.log(greet.say());
it throws an error saying:
Error: Cannot find module 'greet-module'
What mistake am I making here?
modules.export is incorrect. It should be module.exports with an s.
Also, make sure after you add the dependency to do an npm install. This will copy the file over to your node_modules and make it available to the require function.
See here for a good reference.
Update:
After going through some examples to figure this out I noticed, most projects have the structure I laid out below. You should probably format your local modules to be their own standalone packages. With their own folders and package.json files specifying their dependencies and name. Then you can include it with npm install -S lib/test.
It worked for me once I did it, and it'll be a good structure moving forward. Cheers.
See here for the code.

Node 'resolve' with file watching and reloading

Let's assume the module I am requiring has no dependencies. For example, a json file, or a webpack compiled file.
Is there a built in method (or an npm package) that allows you to resolve live instances of files in node?
For example:
foo.js
module.exports = function() {
return 'test!';
}
implementation.js
var liveFoo = require("live-monitor")("foo");
console.log(liveFoo.instance()); // this will auto update when saving foo.js.
I'd imagine this hypothetical node module live-monitor would internally use fs.watch to update the instance export as the file foo.js is changed.
So, anything built in to node? Any package out there that does this already?

Why can node not find my module?

I am using node v0.12.5 with nwjs and I have defined my own custom module inside of my project so that I can modularise my project (obviously).
I am trying to call my module from another module in my project but every time I attempt to require it I get the error could not find module 'uploader'.
My uploader module is currently very simple and looks like:
function ping_server(dns, cb) {
require('dns').lookup(dns, function(err) {
if (err && err.code == "ENOTFOUND") {
cb(false);
} else {
cb(true);
}
})
}
function upload_files()
{
}
module.exports.ping_server = ping_server;
module.exports.upload_files = upload_files;
With the idea that it will be used to recursively push files to a requested server if it can be pinged when the test device has internet connection.
I believe I have exported the methods correctly here using the module.exports syntax, I then try to include this module in my test.js file by using:
var uploader = require('uploader');
I also tried
var uploader = require('uploader.js');
But I believe node will automatically look for uploader.js if uploader is specified.
The file hierarchy for my app is as follows:
package.json
public
|-> lib
|-> test.js
|-> uploader.js
|-> css
|-> img
The only thing I am thinking, is that I heard node will try and source the node_modules folder which is to be included at the root directory of the application, could this be what is causing node not to find it? If not, why can node not see my file from test.js given they exist in the same directory?
UPDATE Sorry for the confusion, I have also tried using require('./uploader') and I am still getting the error: Uncaught Error: Cannot find module './uploader'.
UPDATE 2 I am normally completely against using images to convey code problems on SO, but I think this will significantly help the question:
It's clear here that test.js and uploader.js reside in the same location
When you don't pass a path (relative or absolute) to require(), it does a module lookup for the name passed in.
Change your require('uploader') to require('./uploader') or require(__dirname + '/uploader').
To load a local module (ie not one from node_modules) you need to prefix the path with ./. https://nodejs.org/api/modules.html#modules_modules
So in your case it would be var uploader = require('./uploader');
This problem stemmed from using Node Webkit instead of straight Node, as stated in their documentation all modules will be source from a node_modules directory at the root of the project.
Any internal non C++ libraries should be placed in the node_modules directory in order for Node webkit to find them.
Therefore to fix, I simply added a node_modules directory at the root of my project (outside of app and public) and placed the uploader.js file inside of there. Now when I call require('uploader') it works as expected.
If you're developing on a mac, check your file system case sensitivity. It could be that the required filename is capitalized wrong.

How to use Gulp to create a separate vendor bundle with Browserify from Bower components

I'm using Gulp and Browserify to package my Javascript into 2 separate bundles: application.js and vendor.js.
How do I bundle the vendor package if my vendor libraries are installed with Bower?
In my gulpfile, I'm using the following modules:
var gulp = require("gulp");
var browserify = require("browserify");
var debowerify = require("debowerify");
var source = require("vinyl-source-stream");
Assuming that I have only the Phaser framework installed with bower (for this example), my Gulp task to create the application package looks like this:
gulp.task("scripts-app", function () {
browserify("./app/javascripts/index.js")
.external("phaser")
.pipe(source("application.js"))
.pipe(gulp.dest("./tmp/assets"));
});
Meanwhile, the vendor task looks like this:
gulp.task("scripts-vendor", function () {
browserify()
.transform(debowerify)
.require("phaser")
.pipe(source("vendor.js"))
.pipe(gulp.dest("./tmp/assets"));
});
When I run this Gulp task, I get an error that states Error: Cannot find module 'phaser' from and then all the directories it search through (none of which are the bower_components directory).
Any ideas about how to package these up successfully are greatly appreciated. Thanks!
Answered my own question:
When using require in the Gulp task, you need to supply a path to a file, not just a name.
gulp.task("scripts-vendor", function () {
browserify()
.transform(debowerify)
.require("./bower_components/phaser/phaser.js")
.pipe(source("vendor.js"))
.pipe(gulp.dest("./tmp/assets"));
});
Notice that require("phaser") became require("./bower_components/phaser/phaser.js").
Doing this works, although the bundle takes forever to build (around 20 seconds). You're probably better of just loading giant libraries/frameworks directly into your app through a <script> tag and then using Browserify Shim.
This let's you require() (in the NodeJS/Browserify sense) global variables (documentation).
Seems like you figured out how to require the bower file. Hopefully you'll only have to bundle it once initially, and not every build. Including the library via a script tag isn't a bad idea. Another technique I'm using is to use scriptjs (a polyfill would work too), to async load whatever vender libraries I need, but make sure to include any/all require's after the script loads. For example, your index.js could be like:
$script.('/assets/vendor', function() {
var phaser = require('phaser');
//rest of code
});
It's especially nice for loading cdn files or having the ability to defer loading certain libraries that aren't necessarily used in the core app by every user, or loading libraries after client-side routing.

Resources