Brunch config file: what is the difference between exports.config and module.exports = config? - brunch

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Ă !

Related

Why in node exist more than one way to export?

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)

Require behaves differently in Angular project

If to write something like const theoretically = require('jasmine-theories');, require returns the content of the file.
But if to set declare var require: any;, then next **require** executions steps inside webpack bootstrap function __webpack_require__(moduleId) and return real file path with hash, not content (for example 'file.65465436547.js').
I've found out that file-loader has such behavior https://www.npmjs.com/package/file-loader .
I may assume that depending on declare var require: any; require is taken from NodeJS or from File-loader.
Is that correct? And is there more obvious way how and when to use each of them?
And how can I config File-loader to behave another way in case of Angular application? Angular CLI doesn't provide webpack.config, therefore loaders just get installed without any configuration possible.
Overall the question can be shortened to:
Why require returns content in one case and file name in another case?
Don't use require, use
import { theoretically } from 'jasmine-theories';
This is webpack tree shakable.
It looks that before declare var require: any; default method is used from Node JS. But after explicit declaring FileLoader's method becomes visible. And as it has default exporting - require usage is switched to FileLoader's one.

Making a node module with js_of_ocaml

The js_of_ocaml documentation says about making a Node.js module:
Js.export and Js.export_all will export a value to module.exports if it exists.
What I'm confused about is the "if it exists" part. How do I make sure that the module def exists? i.e. if I'm making an OCaml library that I'd like to be able to import from JavaScript (TypeScript actually), how can I make sure that I get such a module as the output of js_of_ocaml?
If module.exports exists, a value is exported as node module.
And if module.exports doesn't exists (on web browser for example), a value is exported as global variable.

Object doesn't seem to load with all of its properties. - Node.js

I have two js files on my node server that require each other.
both have objects that are exposed via the module.exports mechanism.
1st file is located under bl/commands.js and uses:
var smUtil = require('./../utils/smUtil');
2nd file is located under utils/smUtil.js and uses:
var commands = require('./../bl/commands');
When a function runs from smUtil.js and uses some properties of commands.js it seems like command is an empty object and the import was not successful.
Here is the catch, when i remove the require of smUtil form inside commands.js everything works, which makes me think that i'm doing a newbe mistake.
Any thoughts?
Node.js documentation about circular dependencies
You are absolutely right that empty objects are returned.
To Quote Node.js documentation
When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module.
A solution could be to create a separate file to require both the files there and instantiate that file to avoid the circular dependency.
The specific solution which solved my problem was to place var smUtil = require('./../utils/smUtil'); Underneath the module.exports inside commands.js.
However i feel like this solution is not the best one out there.
Thanks to the author of:
coderwall.com/p/myzvmg/circular-dependencies-in-node-js

Why does accessing variables declared without `var` work without having to use `require` in other files?

Here's an example
$ cat main.js
App = {
version : 1.1
};
require('./mymod.js');
$ cat mymod.js
console.log(App.version);
$ node main.js
1.1
Note how I declared App in main.js without var. This allowed me to access App from mymod.js without having to call require. If I declare App with a var, this won't work.
I want to understand why this happens? Is it the intended behaviour for node.js or a bug? Is this behavior consistent with ECMAScript or CommonJS standards?
This trick gives a powerful mechanism to circumvent the require module system of node.js. In every file define your objects and add them to the top level App namespace. Your code in other files will be automatically have access to those objects. Did I miss something?
If you assign a variable without using var, it is automatically a global variable. That's just the way JavaScript works. If you put 'use strict'; (quotes required) at the top of your js file, this becomes an error instead.
All has to do with local scope vs global scope.
You can even do this (which is much neater):
app.js:
exports = {
version : 1.1
};
main.js:
var App = require('./app.js');
console.log(App.version);
Defining a variable without a preceding var will place it into the global namespace which is visible to all of your JavaScript code.
While this may seem a useful feature, it is generally considered bad practice to "pollute" the global namespace and can lead to subtle, hard-to-locate bugs when two non-related files both rely upon or define variables with the same name.
In nodeJS environment there is a global scope referenced by 'global' , just like the way we have 'window' in browser environments. In effect every javascript host enviroments always start with creating a global object.
When require('main.js') is executed, there is this following function that is created and executed against the global scope 'global'.
(function(exports,...){
//content of main.js
App = {
version : 1.1
};
})(module.exports,..);
When the above function is executed and since there is no var declaration for App , a property with name 'App' is created on global object and assigned the value.This behavior is according to ECMA spec.
That is how the App gets into global scope and is accessible across all modules.
require has been introduced to standardize development of modules that can be ported and used.

Resources