10 Ocak 2018 Çarşamba

Node.js dersleri 3 - Modules – exports vs module.exports

6 -  Modules – exports vs module.exports - HelloAngular2

https://nodejs.org/docs/v0.4.1/api/modules.html
Node has a simple module loading system. In Node, files and modules are in one-to-one correspondence. As an example, foo.js loads the module circle.js in the same directory. ( Aşağıdaki örnek dosyayı inceleyelim. Bu iki dosya aynı directory'dedir. foo.js dosyasında circle.js dosyası diğer bir deyişle circle.js modülü load edilir.  )
foo.js:
var circle = require('./circle.js');  // circle.js modülünü load et.
console.log( 'The area is ' + circle.area(4));
console.log( 'The circumference is ' + circle. circumference(4));
circle.js:
var PI = Math.PI;
exports.area = function (r) {
 return PI * r * r;
};
exports.circumference = function (r) {
 return 2 * PI * r;
};
Run as ->  node foo.js
The module circle.js has exported the functions area() and circumference(). To export an object, add to the special exports object. Variables local to the module will be private. In this example the variable PI is private to circle.js. ( circle.js modülünde, area() ve circumference() fonksiyonları export edilir, bu modülü include ederek bu fonksiyonlara erişilebilir. Bu örnekteki fonksiyonları export etmek için, exports isimli object'e bu fonksiyonları ekleriz. circle.js modülündeki PI, local bir variable'dır, bir private variable'dır, bu variable'a diğer module'lerden erişilemez.  )
Core Modules
The core modules are defined in node's source in the lib/ folder.
Core modules are always preferentially loaded if their identifier is passed to require(). For instance,require('http') will always return the built in HTTP module, even if there is a file by that name.(Node.js'deki core modüller(built-in modüller) lib/ klasöründe tanımlanmıştır. Bir core modülün ismi require() method'una argument olarak verilirse, bu core modül load edilir. Örneğin, require('http') built-in HTTP modülünü load eder. )
File Modules
If the exact filename is not found, then node will attempt to load the required filename with the added extension of .js, and then .node.
.js files are interpreted as JavaScript text files, and .node files are interpreted as compiled addon modules loaded with dlopen.
A module prefixed with '/' is an absolute path to the file. For example, require('/home/marco/foo.js') will load the file at /home/marco/foo.js.
A module prefixed with './' is relative to the file calling require(). That is, circle.js must be in the same directory as foo.js for require('./circle') to find it.
Without a leading '/' or './' to indicate a file, the module is either a "core module" or is loaded from a node_modules folder.


Loading from `node_modules` Folders
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 either the module is found, or the root of the tree is reached.
For example, if the file at '/home/ry/projects/foo.js' called require('bar.js'), then node would look in the following locations, in this order:
  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

This allows programs to localize their dependencies, so that they do not clash.

7 - Modules – exports vs module.exports
http://nodeguide.com/beginner.html
In order to structure your program into different files, node.js provides you with a simple module system.
Create a new file called 'main.js' with the following content:
var hello = require('./hello');
hello.world();
The require('./hello') is used to import the contents from another JavaScript file. The initial './' indicates that the file is located in the same directory as 'main.js'. Also note that you don't have to provide the file extension, as '.js' is assumed by default. ( main.js dosyasında require('./hello') kullanılarak, başka bir Javascript dosyası olan hello'nun içeriği load edilir(import edilir). ./ işaretinden bu 2 dosyasının aynı directory'de olduklarını anlıyoruz. Ayrıca hello.js dosyasını include etmek için .js extension'ı söylesek de olur söylemesek de olur, require('./hello') diyerek hello.js'yi include edebiliriz. )
Create our 'hello.js' file, with the following content:
exports.world = function() {
  console.log('Hello World');
}
What you notice here, is that we are assigning a property called 'world' to an object called 'exports'. Such an 'exports' object is available in every module, and it is returned whenever the require function is used to include the module. If we run our 'main.js' program, we will see the expected output below(hello.js modülünde, exports isimli bir object'e world isimli bir property ekledik. require() fonksiyonu exports object'i return eder. exports object'e, tüm modüllerden erişilebilir. node.js modülünü aşağıdaki gibi run edip output'a bakalım.)
$ node main.js
Hello World

At this point it should also be mentioned that many node users are overwriting the exports object directly like below code. As you might have expected, this will directly cause the require function to return the assigned function. This is useful if you're doing object oriented programming, where each file exports the constructor of one class. (Çoğu node geliştirici, module.exports object'i aşağıdaki gibi ezer, bir fonksiyonu doğrudan module.exports object'e assign eder mesela aşağıdaki gibi. Çünkü artık require fonksiyonu, module.exports'a assign edilen fonksiyonu return edecektir. Başka bir modülde bu modülü require ederek doğrudan bu fonksiyona erişebiliriz. Ancak module.exports'u genellikle object oriented programlama yaparken kullanırız, herbir dosyada bir class yazıp bu class'ını constructor'ını export ederiz. )
module.exports = function() {
  // ...
}

The next thing you need to know about the module system is how it deals with require calls that don't include a relative hint about the location of the included file. Look at the below code example. What node.js will do in this case, is to first look if there is a core module named http, and since that's the case, return that directly. But what about non-core modules, such as 'mysql'? ( require() method'unun aldığı parametre './hello' ise hello.js dosyası current directory'dedir deriz, /hello ise /hello absolute directory'sindedir deriz, 'hello' ise hello isimli bir core module var mı diye bakarız, varsa load ederiz, örneğin http diye bir core modül vardır.)
var http = require('http');
In this case node.js will walk up the directory tree, moving through each parent directory in turn, checking in each to see if there is a folder called 'node_modules'. If such a folder is found, node.js will look into this folder for a file called 'mysql.js'. If no matching file is found and the directory root '/' is reached, node.js will give up and throw an exception.( Aşağıdaki kod çalışınca mysql diye bir core module olmadığı için, bu directory'de node_modules klasörü var mı diye bakar varsa bu klasörde mysql diye bir modül var mı diye bakar. Yoksa, bir üst parent directory'de böyle bir modül var mı diye bakılır, varsa onun içine bakar mysql diye bir modül var mı diye. Yoksa bir üst directory'ye bakar... Eğer root directory'ye kadar bakılmış ama mysql.js diye bir module bulunamamışsa bir exception throw edilir. )
var mysql = require('mysql');

Last but not least, node.js also lets you create an 'index.js' file, which indicates the main include file for a directory. So if you call require('./foo'), both a 'foo.js' file as well as an 'foo/index.js' file will be considered, this goes for non-relative includes as well.(index.js diye bir dosya(modül) yaratırsak, bu dosya bulunduğu directory'deki default include modülü, dosyası olur. Sonuç olarak require('./foo') dersek, bu şu 2 anlama da gelmiş olur :
- current directory'deki foo klasörünün altındaki index.js modülü
- current directory'deki index.js modülü  ).

8 - Modules – exports vs module.exports

http://www.hacksparrow.com/node-js-exports-vs-module-exports.html
http://www.techthali.org/node-js-asynchronous-non-blocking-events-callbacks/

What is the difference between exports and module.exports in Node.js?

You must be familiar with the exports object in Node.js modules, using which you create functions in your modules like this (assume in a file named rocker.js):
exports.name = function() {
   console.log('My name is Lemmy Kilmister');
};
which you call from another file thus:
var rocker = require('./rocker.js');
rocker.name(); // 'My name is Lemmy Kilmister'
But what the heck is module.exports? Is it even legal?
Here is an eye-opener - module.exports is the real deal. exports is just module.exports's little helper. Your module returns module.exports to the caller ultimately, not exports. All exports does is collect properties and attach them to module.exports IF module.exports doesn't have something on it already. If there's something attached to module.exports already, everything onexports is ignored.
Put the following in rocker.js:
module.exports = 'ROCK IT!';
exports.name = function() {
   console.log('My name is Lemmy Kilmister');
};
And this in another file, and run it:
var rocker = require('./rocker.js');
rocker.name(); // TypeError: Object ROCK IT! has no method 'name'
The rocker module completely ignored exports.name, and returned a string 'ROCK IT!'. From that you probably realize that your modules don't always have to be 'module instances'. Your modules can be any legal JavaScript object - boolean, number, date, JSON, string, function, array, and so on. Your module is whatever you set module.exports to. If you don't set module.exports to anything explicitly, the properties of exports and attached to it and returned.
In this case, your module is a class:
module.exports = function(name, age) {
   this.name = name;
   this.age = age;
   this.about = function() {
       console.log(this.name +' is '+ this.age +' years old');
   };
};
and you'd use it this way:
var Rocker = require('./rocker.js');
var r = new Rocker('Ozzy', 62);
r.about(); // Ozzy is 62 years old
In this case, your module is an array:
module.exports = ['Lemmy Kilmister', 'Ozzy Osbourne', 'Ronnie James Dio', 'Steven Tyler', 'Mick Jagger'];
and you may use it this way:
var rocker = require('./rocker.js');
console.log('Rockin in heaven: ' + rocker[2]); //Rockin in heaven: Ronnie James Dio
So you get the point now - if you want your module to be of a specific object type, usemodule.exports; if you want your module to be a typical module instance, use exports.
The result of attaching properties to module.exports is akin to attaching properties to exports. For example this:
module.exports.name = function() {
   console.log('My name is Lemmy Kilmister');
};
does the same thing as:
exports.name = function() {
   console.log('My name is Lemmy Kilmister');
};
But note that, they are not the same thing. As I said earlier module.exports is the real deal,exports is just its little helper. Having said that, exports is the recommended object unless you are planning to change the object type of your module from the traditional 'module instance' to something else.
I hope this post helped you understand the difference between exports and module.exports, and learn a bit more about how modules work in Node.js. Any questions, ping me in the comments.
UPDATE: 7th Feb, 2014
As long are you don't overwrite the module.exports object with an assignment operation, anything attached to module.exports and exports will be available in the 'required' module.
If this is the content of your module:
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
The following code would work fine:
var rocker = require('./rocker.js');
console.log('%s is %s', rocker.name, rocker.age); // Lemmy Kilmister is 68
BUT
if you overwrite module.exports with anything in your module, it will fail:
module.exports = 'LOL';
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
or
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
module.exports = 'WTF';
the order doesn't matter, rocker.age and rocker.name will now be undefined.
Also, note: just because module.exports.age and exports.name are exported, does not mean you should use a combination of both. My recommendation is to stick to exports.*, and be aware of module.exports.*.

1 yorum:

  1. Node.js ortaya çıktıktan sonra artık Javascript sadece kullanıcı tarafında kullanılan basit bir programlama dili olmaktan çıkarak veri tabanı işlemleri gibi Back End işlemlerinin yapılabildiği bir dil haline gelmiştir. Javascript neden popüler şeklinde bir soru soracak olursanız da öğrenmesi kolay, olay tabanlı ve arkasında büyük bir topluluk olan bir dil olması denilebilir.

    YanıtlaSil