ホームページ >ウェブフロントエンド >jsチュートリアル >Nodejs を一緒に学びましょう --- Node.js モジュール

Nodejs を一緒に学びましょう --- Node.js モジュール

高洛峰
高洛峰オリジナル
2016-12-26 09:25:131439ブラウズ

简介及资料

    通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require('模块名')去获取;核心模块具有最高的加载优先级(有模块与核心模块同名时会体现)

    (本次主要说自定义模块)

    Node.js还有一类模块为文件模块,可以是JavaScript代码文件(.js作为文件后缀)、也可以是JSON格式文本文件(.json作为文件后缀)、还可以是编辑过的C/C++文件(.node作为文件后缀);

    文件模块访问方式通过require('/文件名.后缀')    require('./文件名.后缀')    requrie('../文件名.后缀') 去访问,文件后缀可以省略;以"/"开头是以绝对路径去加载,以"./"开头和以"../"开头表示以相对路径加载,而以"./"开头表示同级目录下文件,

    前面提到文件后缀可以省略,Nodejs尝试加载的优先级 js文件 > json文件 > node文件

创建一个自定义模块

   以一个计数器为例

 Nodejs を一緒に学びましょう --- Node.js モジュール

var outputVal  = 0;     //输出值
var increment = 1;    //增量
/* 设置输出值 */
function seOutputVal (val) {
    outputVal = val;
}
/* 设置增量 */
function setIncrement(incrementVal){
    increment = incrementVal;
}
/* 输出 */
function printNextCount()
{    
    outputVal += increment;
    console.log(outputVal) ;
}
function printOutputVal() {
    console.log(outputVal);
}
exports.seOutputVal = seOutputVal;
exports.setIncrement = setIncrement;
module.exports.printNextCount = printNextCount;
自定义模块 示例源码

示例中重点在于exports和module.exports;提供了外部访问的接口,下面调用一下看看效果吧

调用自定义模块

 Nodejs を一緒に学びましょう --- Node.js モジュール

/*
    一个Node.js文件就是一个模块,这个文件可能是Javascript代码、JSON或者编译过的C/C++扩展。
    重要的两个对象:
    require是从外部获取模块
    exports是把模块接口公开    
*/
var counter = require('./1_modules_custom_counter');
console.log('第一次调用模块[1_modules_custom_counter]');
counter.seOutputVal(10);               //设置从10开始计数
counter.setIncrement (10);             //设置增量为10
counter.printNextCount();
counter.printNextCount();
counter.printNextCount();
counter.printNextCount();
/*
    require多次调用同一模块不会重复加载
*/
var counter = require('./1_modules_custom_counter');
console.log('第二次调用模块[1_modules_custom_counter]');
counter.printNextCount();
自定义模式调用 源码

    运行可以发现通过exports和module.exports对外公开的方法都可以访问!

    示例中可以看到,我两次通过require('./1_modules_custom_counter')获取模块,但是第二次引用后调用printNextCount()方法确从60开始~~~

    原因是node.js通过requirerequire多次调用同一模块不会重复加载,Node.js会根据文件名缓存所有加载过的文件模块,所以不会重新加载了

    注意:通过文件名缓存是指实际文件名,并不会因为传入的路径形式不一样而认会是不同的文件    

    在我创建的1_modules_custom_counter文件中有一个printOutputVal()方法,它并没有通过exports或module.exports提供对外公开访问方法,

    如果1_modules_load文件中直接访问运行会出现什么样的情况呢?

    答案是:TypeError: Object # has no method 'printOutputVal'

exports和module.exports 区别

经过上面的例子,通过exports和module.exports对外公开的方法都可以访问!那既然两种都能达到效果,但总得有点区别的吧~~~用个例子看看吧!

Nodejs を一緒に学びましょう --- Node.js モジュール

var counter  = 0;     
exports.printNextCount = function (){    
    counter += 2;
    console.log(counter);
}
var isEq = (exports === module.exports);
console.log(isEq);
2_modules_diff_exports.js 文件源码

下面再新建个2_modules_diff_exports_load.js文件调用一下

Nodejs を一緒に学びましょう --- Node.js モジュール

var Counter = require('./2_modules_diff_exports');
Counter.printNextCount();

    调用后,执行结果如上图

    我在2_modules_diff_exports_load.js文件中输出了isEq的值  ( var isEq = (exports === module.exports); ),返回的true

    PS:注意是三个等号,如果不清楚自已查查资料吧!

不用急着下结论,把这两个JS文件分别改成module.exports对应的代码

//修改后的2_modules_diff_exports.js源码如下
var counter  = 0;     
module.exports = function(){    
    counter += 10;
    this.printNextCount = function()
    {
        console.log(counter);    
    }
}
var isEq = (exports === module.exports);
console.log(isEq);
//修改后的2_modules_diff_exports_load.js文件源码如下
var Counter = require('./2_modules_diff_exports');
var counterObj = new Counter();
counterObj.printNextCount();

Nodejs を一緒に学びましょう --- Node.js モジュール

    调用后,执行结果如上图

    我在2_modules_diff_exports_load.js文件中输出了isEq的值  ( var isEq = (exports === module.exports); ),返回的false,这与用先前得到的结果不一致!

    PS:不要用Counter.printNextCount();去访问,你只会得到一个错误的提示

    API提供了解释

    http://nodejs.org/api/modules.html

    Note that exports is a reference to module.exports making it suitable for augmentation only. If you are exporting a single item such as a constructor you will want to use module.exports directly instead
    exports仅仅是module.exports的一个地址引用。nodejs只会导出module.exports的指向,如果exports指向变了,那就仅仅是exports不在指向module.exports,于是不会再被导出

Module.exports は実際のインターフェースであり、exports はその補助ツールにすぎません。最終的に呼び出しに返されるのは、exports ではなく module.exports です。
エクスポートによって収集されたすべての属性とメソッドは Module.exports に割り当てられます。もちろん、これには前提があります。つまり、module.exports 自体にはプロパティやメソッドがありません。
module.exports にすでにいくつかのプロパティとメソッドがある場合、exports によって収集された情報は無視されます。

Exports と module.exports の対象範囲

上記でも基本的には、exports と module.exports の関係と違いを理解していますが、printNextCount() メソッドに対して、exports と module.exports が同時に存在する場合、結果はどうなるでしょうか?

Nodejs を一緒に学びましょう --- Node.js モジュール

Call result

Nodejs を一緒に学びましょう --- Node.js モジュール

結果から、エラーが報告されていないことがわかり、この方法で定義できることがわかりますが、最終的には module.exports がexportsをオーバーライドします

。このように使用すると、必ずエラーが報告されます。いくつかの問題があるため、

1. module.exports と exports を別々に定義しないことが最善です

2. NodeJs 開発者は、module.exports を使用して次のことを行うことをお勧めします。オブジェクトをエクスポートし、複数のメソッドと変数をエクスポートするエクスポート

その他...

API には他にもメソッドが用意されているため、詳細は説明しません。上記の例に基づいて、ご自身で理解できると思います。出力したらすぐに

Module.id

文字列型のモジュール ID、通常は完全に解析されたファイルを返します Name

module.filename

文字列型の完全に解析されたファイル名を返します

module.loaded

読み込みが完了したかどうかを示すbool型を返します

module.parent

モジュールを参照するモジュールを返します

module .children

このモジュールによって参照されるすべてのモジュールオブジェクトの配列を返します

Node.jsモジュール関連の詳細はこちら記事をご覧になる際は、PHP 中国語 Web サイトにご注意ください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。