How to export an object with Browserify? - javascript

I started using Browserify and not sure if I completely understand how to use it.
I have a file with some functions bundled in one object in foo.js
var foo = {
f1: function(){...}
f2: function(){...}
}
module.exports = function () {
return foo;
};
And I want to export them to a variable in the main.js file, so I tried doing this:
var bar = require('/foo')();
The goal is to be able to do bar.f1().
Without executing require('/foo') I get only a function definition, so I have to execute it. Am I doing something wrong?

Just export the object:
var foo = {
f1: function(){...}
f2: function(){...}
};
module.exports = foo;

Related

Is there a way to have a constructor within an already existing constructor?

I have the following function that acts a base constructor:
function Foo() = {}
...
exports Foo
It's an empty constructor, and is used by other functions which I don't want to change. Also, Foo is only being exported from the file.
Now I need to create a different constructor perhaps within Foo.
The following is what I'd have with enum as a standalone constructor. But how do I make it a part of Foo?
function enum(data) {
this.data = data
}
enum.prototype.getVal() { return this.data; }
var obj = new enum(5);
obj.getVal();
Taking a completely wild guess from your commnets.
exporting from the file is of no real concern. If you're just using Foo as a namespace to "hang" functions off of you can do this:
Enum.js
// all constructors should be capitalized
function Enum() { }
Enum.prototype.whatever ...
exports Enum
Foo.js
const Enum = require('./Enum');
// it's unclear why `Foo` is even a function to be honest
function Foo() { }
Foo.Enum = Enum;
exports Foo
someOtherFile.js
const Foo = require('./Foo');
const myEnumInstance = new Foo.Enum();

Module functions appear undefined in outside scripts

This code tells me that the parse function is not a function:
const MyModule = require('./MyModule.js');
MyModule.parse('...');
In my module script it's defined like this:
MyModule = {};
MyModule.parse = function(data){
};
module.exports.MyModule = MyModule;
What am I doing wrong?
You have to understand that you are not exporting MyModule but an object (module.exports to be exact) with a member called MyModule (this is what you assigned to it).
If, in your code that requires MyModule, you console.log the result of your require, it will look like:
{ MyModule: {parse: [Function] } }
which is the module.exports object with a property (object) called MyModule that has a property (function) called parse.
So when you require you are getting the module.exports object that you assigned MyModule to and not just MyModule.
If you were to change your module.exports code to:
module.exports.X = MyModule;
Your code that required MyModule would then log:
{ X: {parse: [Function] } }
and you would call it as
MyModule.X.parse(...).
If you then changed your code to read
const MyFabulousModule = require('./MyModule');
you would then call it like:
MyFabulousModule.X.parse(...);
Finally, if you added another line to your module:
module.exports.Y = 4;
And then in your calling code added:
console.log(MyFabulouseModule.Y);
you would see the value 4 logged to the console.
Code:
MyModule.js
const MyModule = {};
MyModule.parse = function(data) {
console.log(data);
};
module.exports.X = MyModule;
module.exports.Y = 4;
test.js
const MyModule = require("./MyModule");
console.log(MyModule);
MyModule.X.parse("hello world");
console.log(MyModule.Y);
To run: node test.js
First of all, you need to add a keyword in definition object.
const MyModule = {};
And you export the object, which you appoint to constant, so you need to call the object from it like this:
MyModule.MyModule.parse('...')

Create a new object from export modules using bowserify

I'm trying to use the object I've expose from the a javascript file using browserify, but I keep getting error Uncaught TypeError: undefined is not a function
Here is an example:
foo.js:
var foo = function() {
this.f1 = function(){
console.log('function1')
}
this.f2 = function(){
console.log('function2')
}
};
module.exports = foo;
I'm trying to use the foo in the index.html.
after enter command: browserify foo.js > bundle.js
and include bundle.js to html file.
index.html:
<html>
<head>
<script src="./bundle.js"></script>
<script>
var foo = new foo(); // Uncaught TypeError: undefined is not a function
foo.f1();
</script>
</head>
<body>
</body>
</html>
What am I doing wrong with browserify? Thanks in advance.
EDIT: for wrong example.
original wrong example
foo.js:
var foo = {
f1: function(){
console.log('function1')
},
f2: function(){
console.log('function2')
}
};
module.exports = foo;
If you want to use new, you should declare the foo class like:
foo = function() {
this.f1 = function(){
console.log('function1')
};
this.f2 = function(){
console.log('function2')
};
};
foo_obj = new foo();
foo_obj.f1();
foo_obj.f2();
Instead of a literal. Otherwise, simply the methods of the foo object.
var foo = {
f1: function(){
console.log('function1')
},
f2: function(){
console.log('function2')
}
};
foo.f1();
foo.f2();
Update:
Let's see, I've never used browserify, but accordingly to their docs, you should do something like:
foo.js
module.exports = function() {
this.f1 = function(){
console.log('function1')
},
this.f2 = function(){
console.log('function2')
}
};
main.js
var foo = require('foo');
Then, do:
browserify main.js -o bundle.js
And finally import bundle.js and use new foo() to create the object inside your script.
You're trying to instantiate an object as if it was a function, e.g.
new {}; // invalid!!
new function() {}; // valid!
I would recommend you use either
exports.foo1 = function() { console.log('foo'); }
exports.bar1 = function() { console.log('bar'); }
or if you really want to keep new foo() use:
module.exports = foo;
function foo() {
this.foo1 = function() { console.log('foo'); }
this.bar1 = function() { console.log('bar'); }
}
browserify foo.js --standalone foo > bundle.js

JavaScript design patterns: Injecting a dependency that is not yet created

I have a CommonJS module:
// main-module
module.exports = function () {
var foo,
someModule = require('other-module')(foo);
// A value is given to foo after other-module has been initialised
foo = "bar";
}
As you can see, this requires other-module:
// other-module.js
module.exports = function (foo) {
function example() {
console.log(foo);
// > "bar"
}
}
I would like the example function inside of other-module to be aware of the foo variable inside of main-module, even though is it established after the module is required.
When other-module runs, foo will not be undefined. However, the point is that by time my example function runs, foo will have been given a value of bar.
The pattern above obviously does not work. What design pattern do I need to implement?
I'm not super-familiar with CommonJS, so this might not be the idiomatic way to do it, but using a function instead of a variable should work:
// main-module
module.exports = function () {
var foo,
someModule = require('other-module')(function() { return foo; });
foo = "bar";
}
// other-module.js
module.exports = function (fooFn) {
function example() {
console.log(fooFn());
}
}
The foo value (a string) will be passed by value, so it's undefined inside other-module. You could use an options object that is passed by reference:
var options = {},
someModule = require('other-module')(options);
options.foo = "bar";

coffee -cj overwrites module.exports for each class

I just can't get my head around how this is supposed to work: As I understand, a pretty common way to define a class/module in CoffeeScript is by using module.exports = class MyClass at the top of the file. I would also guess that the coffee compiler would facilitate this pattern. Take this minimalist example:
# src/Foo.coffee
module.exports = class Foo
# src/Bar.coffee
module.exports = class Bar
Then compile and join the two with:
coffee -cj all.js src
The result is all.js where module.exports is redefined/overwritten for each module:
// Generated by CoffeeScript 1.4.0
(function() {
var Bar, Foo;
module.exports = Bar = (function() {
function Bar() {}
return Bar;
})();
module.exports = Foo = (function() {
function Foo() {}
return Foo;
})();
}).call(this);
If I now try to do this, the result would be an error stating that the Foo module cound not be found, and rightly so because the last module (here: Bar) has redefined module.exports to only contain itself.
Foo = require('foo');
I guess this is quite the noob question but I can't seem to get a good answer anywhere.
This is pretty much the desired behaviour... You're merging two modules into one, and they both want to be at the top level, so one of them has to win.
One possible solution would be as follows:
# src/Foo.coffee
module.exports.Foo = class Foo
# src/Bar.coffee
module.exports.Bar = class Bar
which yields:
# all.js
(function() {
var Bar, Foo;
module.exports.Bar = Bar = (function() {
function Bar() {}
return Bar;
})();
module.exports.Foo = Foo = (function() {
function Foo() {}
return Foo;
})();
}).call(this);
And then you can use (in CoffeeScript)
{Foo, Bar} = require "all"
to get at the classes contained therein

Categories