In the server.js file of mean.io
I can see
//expose app
exports = module.exports = app;
Can anyone explain me the meaning, what is it for ?
File in Question: https://github.com/linnovate/mean/blob/master/server.js
I would write something up, but I found an article that covers it nicely:
[ . . . ] In /src/node.js you can see that your
code is wrapped in a closure and passed both exports and module. Of
course, further inspection will show you that exports contains a
pointer to module.exports and suddenly everything makes sense.
Overwriting exports overwrites the pointer to module.exports which
disconnects exports from the Node.js environment!
What’s the point?
Exports is a helper function that points to module.exports. This is
meant to make your life easier. That is all. Use it to expose
functions of your module, but if your module needs to replace what is
exposed, you must use module.exports.
Open up that article and take a look at the examples that are provided for more information.
In short, it's a way of making the app variable be referenced directly when it's required from another module instead of being nestled into an object, e.g.
// hello.js
module.exports = 'hello';
// foo.js
exports.foo = 'bar';
// testing it out
console.log(require('hello.js')); // outputs 'hello'
console.log(require('foo.js')); // outputs { foo: 'bar' }
Related
In node.js we can use
module.exports
exports
exports is shorthand for module.exports.
In my opinion, providing module.exports and exports is confusing.
It is not only confusing but error prone also because we can reassign one.
Why module.exports is not the only way to export?
What was the goal to provide both?
The documentation says it's so that code writing to export can be more concise:
exports shortcut
The exports variable is available within a module's file-level scope, and is assigned the value of module.exports before the module is evaluated.
It allows a shortcut, so that module.exports.f = ... can be written more succinctly as exports.f = ....
(my emphasis)
What is the difference between require() vs module.require() in nodejs ?
require()
module.require()
The documentation don't provide any content about the difference between them. Can anyone explain ?
They both require other modules (call other module's and returns their module.exports objects)
module.require('./module1.js');
require('./module1.js');
but they are NOT the same
require === module.require // -> false
module.require can only be used as method
require is a method but also has their own properties (cache main)
providing additional data
module.require.cache // -> undefined
require.cache // -> {the cached module}
The official documentation is not only a little unclear on how they differ, but also lacks any example usage that would help determine the usefulness of using module.require vs require. So I resorted to experimentation, and what I discovered is that, essentially, require() takes a path relative to the module doing the importing, where as module.require takes a module id (this is outlined in the docs, but it is a little unclear what 'id' refers to).
So what id actually refers to is an attribute 'id' of the module object (module.id). If you console.log(module.id) from within a module, you will get the full path to that file. But the only way to load a module using module.require() is if you have access to the module.id variable, which is not exported in module.exports. So technically you could load the current module inside itself as so:
Example Usage 1:
test.js
module.exports = {};
module.exports.foo = function() {
console.log('bar');
};
let thisModule = module.require(module.id);
thisModule.foo();
app.js
const test = require('./test');
output
$ bar
How this use case is useful is beyond me, but loading a module inside itself to run its own exported functions is possible for some reason. Another possible use case is something like this:
Example Usage 2:
test.js
const loader = require('./loader'); // Some library that handles module loading
// dynamically. loader.register passes the module
// info to the dynamic loader to be called
// later by the client perhaps.
loader.register(module);
module.exports = {};
module.exports.foo = function() {
console.log('bar');
};
app.js
const loader = require('./loader');
const test = loader.require('./test'); // loader module will have to do some parsing
// to match './test' with the fully qualified
// path name. Just to be clear, loader.require
// is some function defined by the library
test.foo();
Theoretically outputs bar. So I guess the second use case could be useful if you want to control the loading of the modules for some reason. But you would have to build your modules specifically to this usage. I imagine there could be other uses, I plan to investigate further and if I discover anything new, then I will expand this answer. I hope this helps.
https://nodejs.org/api/modules.html#modules_module_require_id
The module.require() method provides a way to load a module as if require() was called from the original module.
In order to do this, it is necessary to get a reference to the module object. Since require() returns the module.exports, and the module is typically only available within a specific module's code, it must be explicitly exported in order to be used.
What this is saying is that you can require() as if you are in another module, given that you somehow have access to the other module's module variable.
For example, I can do a module.require('./c'), even if c.js doesn't exist as a sibling in my current directory. It will work as long as module's directory has c.js in it.
Example:
.
├── a
│ ├── c.js
│ └── index.js
└── b.js
// b.js
console.log(require('./a').require('./c'));
// a/index.js
module.exports = module;
// a/c.js
module.exports = 'c';
node b.js // stdout 'c'
Documentation for module.require is clear:
The module.require method provides a way to load a module as if require() was called from the original module.
In order to do this, it is necessary to get a reference to the module object. Since require() returns the module.exports, and the module is typically only available within a specific module's code, it must be explicitly exported in order to be used.
In the guide of the Brunch website, they start the config file as following module.exports = config:, however most of the skeletons you can find on the same website use another syntax exports.config =.
What is the difference between them? Are both javascript CommonJS Module?
I had a look directly at the doc: module node documentation. Something I should have done at first :)
The exports variable that is available within a module starts as a reference to module.exports. As with any variable, if you assign a new value to it, it is no longer bound to the previous value.
If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exports instead of exports.
Finally, they said:
As a guideline, if the relationship between exports and module.exports seems like magic to you, ignore exports and only use module.exports.
Et voilà!
I have seen many examples of the self-invoking pattern that detects the global object (module.export / window) -- but I am not sure how to do namespacing with this pattern and still have it work in node the same way.
(function(exports) {
'use strict';
// how do i do something like this and have it work in node as well
// exports Namespace.Models.HelloWorld = function () {}
exports.say = function() {
return 'hello world';
};
}(typeof exports === 'undefined' ? this.helloworld = {} : exports));
After looking at the code some more I think you're code should work fine. What you want is to namespace all your code so that it doesn't pollute the global namespace right? So what you need is a single object in the global namespace that you then put all your code under.
Note: The global namespace in the browser is window in case you didn't know.
For example, JQuery creates only two global objects: jQuery and $. Everything you do with JQuery involves only those two global objects. JQuery even has a compatibility mode that disables the dollar sign so then you only have the jQuery object. The pattern people use to get the dollar sign back even when it's been disabled is to do this:
(function ($) {
// Do stuff with $
})(jQuery);
It's a self-invoking function that passes the jQuery object into itself which then becomes the $ argument. That way you can still have the convenience of the dollar sign without clogging up the global window object with yet another property. In your code (this.helloWorld) the this keyword refers to the global namespace (unless your code is wrapped inside another function or something and you didn't post it). What you've done is create a property on the window object (global namespace) called helloWorld, you set it to an empty object, and you pass it in. But you only do this if exports is undefined. That's the part that identifies if you're in node or not. exports will only be undefined if you're in the browser because exports is only available in node modules (just don't add an exports property to the global namespace in the browser, lol).
Note: Node has no application-wide "global" namespace that things get put into by default. Everything in node is scoped to the module level. So even if you define a variable on the first line of your module you can still define the exact same variable on the first line of another module and they won't conflict with each other. There is however, a global object in node that truly is global and you can access its properties from any module. I do not encourage you to use the global object, like, ever. If you need to use that object then you should probably reconsider your application structure.
Whatever you attach to exports in node becomes available to any other module that requires it.
// helloWorld.js
exports.message = "Hello, world!";
and then...
// main.js
var helloWorld = require('./helloWorld.js');
// Now all the properties are available on the variable `helloWorld`.
console.log(helloWorld.message);
// Prints "Hello, world!" to the console.
In the browser you want to do something similar by attaching a single uniquely named object to window and then whomever uses your script should access all your functions through that "namespace". So finally we have this:
// helloWorld.js
(function (myNamespace) {
myNamespace.message = "Hello, world!";
})(typeof exports === 'undefined' ? this.helloWorld = {} : exports)
If exports does not exist then add helloWorld to this (which refers to window when in the global scope like it is in this example) and pass that in. If exports does exist then pass it in instead. Now inside the function we can attach properties and methods to myNamespace and they'll either be attached to window.helloWorld or exports depending on the environment.
I could add the above helloWorld.js file to my node application and use it like this:
// nodeScript.js
var helloWorld = require('./helloWorld.js');
console.log(helloWorld.message);
Or I could add the above helloWorld.js file to my web app. Your page might look like this:
// index.html
<html>
<head>
<title>My Site</title>
<script src="helloWorld.js" />
<script src="clientScript.js" />
</head>
<body>
<div id="messageBox"></div>
</body>
</html>
And your script might look like this:
// clientScript.js
document.getElementById('messageBox').innerHTML = helloWorld.message;
The above page would end up with "Hello, world!" inside the div because it read the message from our module's exposed properties :)
Hopefully that clears things up. Sorry for jumping in with browserify at first instead of directly answering your original question. I do highly recommend browserify though :)
You need browserify. Write your modules in the node-style and then let browserify turn them into proper client-side scripts :)
From browserify home page:
Write your browser code with node.js-style requires:
// main.js
var foo = require('./foo');
var gamma = require('gamma');
var n = gamma(foo(5) * 3);
var txt = document.createTextNode(n);
document.body.appendChild(txt);
Export functionality by assigning onto module.exports or exports:
// foo.js
module.exports = function (n) { return n * 11 }
Install modules with npm:
npm install gamma
Now recursively bundle up all the required modules starting at main.js into a single file with the browserify command:
browserify main.js -o bundle.js
Browserify parses the AST for require() calls to traverse the entire dependency graph of your project.
Drop a single <script> tag into your html and you're done!
<script src="bundle.js"></script>
Not only is it fun to write client-side scripts like this but browserify will bundle it all together into a nice and tidy minified single script file :D
In my Node app, have a config file like this:
module.exports = {
BUILD_DIR: '/some.path',
OTHER_CONFIG: 42,
// ...
};
I also have some tests doing things like
var appConfig = require('./path/to/appConfig');
appConfig.BUILD_DIR = 'tmp/some/path';
// and stuff done with appConfig
To my big surprise doing this apparently modifies the state of the module. My next test that requires it will have BUILD_DIR set to 'tmp/some/path'. I did not realize modules had this kind of state across requires. How do I get rid of this effect in my test? Also, how can I prevent people from modifying the state of this module? If someone includes it, they should always get what it defines, and not possibly something some other code wrote to it.
The reason why is explained here:
Modules are cached after the first time they are loaded. This means
(among other things) that every call to require('foo') will get
exactly the same object returned, if it would resolve to the same
file.
(emphasis mine)
So the object that you're exporting is cached and shared among the code that uses it.
If that's not what you want, you could export a function instead:
module.exports = function() {
return {
BUILD_DIR: '/some.path',
OTHER_CONFIG: 42,
// ...
};
};
And require it like so:
var appConfig = require('./path/to/appConfig')();
Assuming your module is called 'Config', and you originally:
var Config=require('Config');
you could:
delete require.cache[require.resolve('Config')];
which will remove the module from require's cache, causing it to be loaded afresh when you next 'require' it.
Gist: https://gist.github.com/raisch/6786930