検索

Nodeモジュールの仕組みの解析

Jul 11, 2018 pm 03:18 PM
node.js

这篇文章主要介绍了关于Node模块机制的解析,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

模块机制

一、CommonJS出现背景

js实现编写后端程序的不足之处

1. 没有模块系统(js一个先天不足就是模块功能)

2. ECMAScript仅仅定义了js的核心库,但是对于文件系统、IO系统等却没有标准的API。HTML5虽然在一直致力于推进标准化,但是这些标准耶都是前端的。

3. 没有标准接口,没有定义过服务器或者数据库的接口。

4. 缺乏包管理系统,没有自动安装和管理依赖的能力。

而CommonJS的出现正好弥补了没有标准的这一个缺点。

CommonJS 规范了 模块二进制Buffer二进制I/0,进程环境文件系统web服务器网管接口包管理等

二、CommonJS和Node的关系

Node的出现离不开CommonJS规范的影响,而CommonJS能以一种独寻常的姿态出现在各大公司的代码中,离不开Node优异的表现。

Nodeモジュールの仕組みの解析

三、CommonJS的模块规范

1. 模块引入

var http = require("http");

2. 模块导出

// math.js
exports.add = function(){
    ...
}
// program.js
Var math = require('math.js');

exports.increament = function(val){
    return math.add(val);
}

3. 模块标识

模块标识就是require()的括号中的参数,必须是小驼峰结构,可以是相对路径也可以是绝对路径,还可以没有后缀名。


四、Node的模块实现

node 的模块实现实际上是借鉴了CommonJS的部分,并不是全部照搬,而且也增加了一些自己需要的东西进去。

Nodeモジュールの仕組みの解析

1. 模块引入

node中模块引入需要经过:

1. 路径分析
2. 文件定位
3. 编译执行

2. 模块分类

1. 核心模块 Node提供的
2. 文件模块 用户编写的

3. 核心模块

核心模块部分在Node源码加载中就编译完毕了,编译成了二进制执行文件,在Node进程启动后,部分核心模块就直接加载进内存中,所以可以不用`文件定位`和`编译`,因此部分核心模块的加载时最快的。

4. 文件模块

文件模块则是在运行时动态加载,要经过完整的路径分析、文件定位、编译执行,一次一般比较慢。

5. 缓冲加载

node对二次加载的核心模块,一律采用的时缓冲优先的原则。

6. 路径分析和文件定位

模块标识符分析
  • 核心模块

核心模块的加载仅次于缓冲加载
  • 路径形式的文件模块

首先将其转换为真实的路径,然后以真实路径作为索引,将其编译后放进缓冲中,等待调用。
由于是通过确切的文件地址找到的,所以需要花费一定的时间,
  • 自定义模块

这是非核心模块,也不是路径形式的标识,它是一种特殊的文件模块,可能是一个文件或者是一个包。这种查找是最费时间的。首先需要知道一下/模块路径/的概念/

> 例子

比如你要加载一个包,这个包放在了node_modules文件夹下,你要引入的话可以不以路径的形式写,可以是只写名称。(也就是引入一个自己npm的包)

console.log(module.paths);
// 会得到下面的数组
[ 'D:\\myweb\\node\\node\\module\\node_modules',
  'D:\\myweb\\node\\node\\node_modules',
  'D:\\myweb\\node\\node_modules',
  'D:\\myweb\\node_modules',
  'D:\\node_modules' ]

这就是模块路径了,查找机制是: 首先在当前路径下找是否有node_modules文件夹下的该包,如果没有就查找上一层目录,依次类推,直到根目录下的node_modules,如果依旧没有找到,那么就报错了。

// 显然这种情况就是导致它速度较慢的主要原因了,(查找的路径越深就越慢),但是我们可以通过一些小技巧来经可能的减少这种情况哦~~
文件定位

文件定位中还需要注意的包括有文件扩展名目录包的处理

node 的模块引入的时候是可以不写扩展名的,node会按照js json node的顺序来分析。依次尝试。由于尝试使用的是node中fs模块的同步文件查找,因此可能会导致阻塞情况发生,因此这里我们需要注意两个小技巧了:

小技巧:

1. json node文件最好加扩展名

2. 同步配合缓冲可以环节Node单线程阻塞调用的缺陷

另外,如果没有找到对应的文件,确实找到了一个目录,那么将会将其当作是一个包来处理了。

如何在这个包下找到我们需要引入的入口文件对呢?

1. 首先找是否含有package.json,如果有,则分析它的main属性,找到main属性对应的那个文件。

2. 如果没有package.json或者是main解析失败了,那么就找文件名为index的文件,依次从index.js index.json index.node查找。

3. 如果在该目录下依旧没有找到,那么就查找写一个匹配的目录,如果仍然没有找到,那么就报错了。


6. 模块编译

node中每一个模块都是一个对象,当定位到一个文件的时候,node就会将其包装成一个module对象,然后根据不同的文件名,其载入方法也不同的。

  1. js文件: 通过fs的同步读取文件来执行

  2. json文件,通过fs同步读取文件,用Json.parse()来得到对象,将其赋值给Module.exports

  3. node文件,这事c/c++编写的扩展文件,通过Process.dlopen()方法来加载执行。(不需要编译)

Nodeモジュールの仕組みの解析


7. module.exports和exports的区别和联系

exports = module.exports = {};的区别就和 var a = {}; b = a;的区别一样.

首先要明确的一点,module是一个对象 {Object}。
当你新建一个文件,比如mo.js,文件内容如下:

console.log(module);

然后在CMD里执行这个文件node mo.js,就能看到module其实是一个Module实例,你可以这么理解,NodeJS中定义了一个Module类,这个类中有很多属性和方法,exports是其中的一个属性:

function Module {
  id : 'blabla',
  exports : {},
  blabla...
}

当每一个文件被执行或者时require的时候,node就会创建一个module实例。var module = new Module();

console.log(module); //你会看到Module中的exports为空对象{}
module.exports = {
  print : function(){console.log(12345)}
}
console.log(module); //你会看到Module中的exports对象已经有了print()方法

module.exports 其实就是module实例中的module添加方法或者属性。

console.log(module); //你会看到Module中的exports为空对象{}
console.log(exports); //你会看到Module中的exports为空对象{}
module.exports = {
  print : function(){console.log(12345)}
}
console.log(module); //你会看到Module中的exports对象有了print()方法
exports.name = '小白妹妹';
console.log(module); //你会看到Module中的exports对象不仅有了print()方法,还有了name属性

不难看出exports其实就是module.exports的一个引用。

// 你可以这么理解
var module = new Module();
var exports = module.exports;

当你require的时候,返回的就是module.exports的内容。

// 常用场景分析
module.exports.name = '小白妹妹';
exports.age = 10;
module.exports.print = function(){console.log(12345)};
//如果只是添加属性和方法,两者可以混用。

// 也可以
module.exports = {
  name = '小白妹妹';
};
exports.age = 10;
module.exports.print = function(){console.log(12345)};

// 【X】但是不可以
module.exports = {
  name = '小白妹妹';
};
exports = {age:10}; // exports现在是{age:10}这个对象的引用,不再是module.exports的引用了
console.log(module); //你会看到Module的exports中只有name属性!!!

// 【X】
exports.age = 10; 
console.log(module); //你会看到Module的exports中多了age属性
module.exports = {
   name = '小白妹妹';
};
// 直接改变了module.exports的引用,之前的属性值也被覆盖掉了。
console.log(module); //你会看到Module的exports中还是只有name属性!!!

总结

  1. 改变exports的指向后所添加的exports.xxx都是无效的。因为require返回的只会是module.exports

  2. 不能在使用了exports.xxx之后,改变module.exports的指向。因为exports.xxx添加的属性和方法并不存在于module.exports所指向的新对象中。

  3. 对于要导出的属性,可以简单直接挂到exports对象上

  4. 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到module.exports对象上,不要和导出属性值混在一起

Nodeモジュールの仕組みの解析

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

关于Node基本概念的介绍

以上がNodeモジュールの仕組みの解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境