Artikel ini akan membawa anda melalui spesifikasi CommonJs dan mekanisme modul Node, dan memperkenalkan proses asas Node yang melaksanakan spesifikasi CommonJs saya harap ia akan membantu semua orang.
Sebelum spesifikasi CommonJs dicadangkan, Javascript tidak mempunyai sistem modul, yang bermakna sukar bagi kami untuk membangunkan aplikasi berskala besar kerana organisasi kod akan menjadi lebih sukar.
Pertama sekali, CommonJS bukanlah sesuatu yang unik untuk Node ialah spesifikasi modul yang mentakrifkan cara merujuk dan mengeksport modul , Nodejs hanya melaksanakan spesifikasi ini Spesifikasi modul CommonJS terutamanya dibahagikan kepada tiga bahagian: rujukan modul, definisi modul dan pengenalan modul.
Rujukan modul
Rujukan modul bermaksud kita boleh memperkenalkan modul lain melalui require
.
const { add } = require('./add'); const result = add(1 ,2);
Definisi modul
Fail ialah modul, dan modul akan menyediakan dua pembolehubah, iaitu modul dan eksport. modul ialah modul semasa itu sendiri, eksport ialah kandungan yang akan dieksport, dan eksport ialah atribut modul, iaitu, eksport ialah modul.eksport. Kandungan yang diimport oleh modul lain melalui memerlukan adalah kandungan modul.eksport.
// add.js exports.add = (a, b) => { return a + b; }
ID Modul
ID modul ialah kandungan yang diperlukan Contohnya, require('./add')
, kemudian ID modul ialah ./add
.
Mekanisme import dan eksport modul yang dibina melalui CommonJS membolehkan pengguna membina aplikasi berskala besar dengan mudah tanpa perlu mempertimbangkan pencemaran berubah-ubah.
Pelaksanaan modul Node
Node melaksanakan spesifikasi CommonJs dan menambahkan beberapa ciri yang diperlukannya. Node terutamanya melakukan tiga perkara berikut untuk melaksanakan spesifikasi CommonJs:
Analisis laluan
Kedudukan fail
Kompilasi dan laksanakan
Analisis laluan
Apabila memerlukan() dilaksanakan, memerlukan menerima Parameter ialah pengecam modul, dan nod menggunakan pengecam modul untuk melaksanakan analisis laluan. Tujuan analisis laluan adalah untuk mencari laluan di mana modul ini terletak melalui pengecam modul. Pertama sekali, modul nod terbahagi kepada dua kategori iaitu modul teras dan modul fail. Modul teras ialah modul yang disertakan dengan nod, dan modul fail ialah modul yang ditulis oleh pengguna. Pada masa yang sama, modul fail dibahagikan kepada modul fail dalam bentuk laluan relatif, modul fail dalam bentuk laluan mutlak, dan modul fail dalam bentuk bukan laluan (seperti ekspres).
Apabila nod menemui modul fail, ia akan menyusun, melaksanakan dan cache modul Prinsip umum adalah menggunakan laluan penuh modul sebagai kunci, dan kandungan yang disusun sebagai nilai, apabila modul ini diperkenalkan untuk kali kedua, tidak perlu melakukan langkah-langkah analisis laluan, lokasi fail, penyusunan dan pelaksanaan Kandungan yang disusun boleh dibaca terus dari cache.
// 缓存的模块示意: const cachedModule = { '/Usr/file/src/add.js': 'add.js编译后的内容', 'http': 'Node自带的http模块编译后的内容', 'express': '非路径形式自定义文件模块express编译后的内容' // ... }
Apabila anda ingin mencari modul yang diimport oleh memerlukan, tertib mencari modul adalah untuk menyemak dahulu sama ada modul itu sudah berada dalam cache Jika ia tiada dalam cache, kemudian semak modul teras, dan kemudian cari modul fail. Antaranya, modul fail dalam bentuk laluan lebih mudah dicari Laluan fail lengkap boleh diperolehi berdasarkan laluan relatif atau mutlak. Agak menyusahkan untuk mencari modul fail tersuai dalam bentuk bukan laluan Node akan mencari fail dari folder node_modules.
Di manakah direktori node_modules? Contohnya, fail yang sedang kami laksanakan ialah /Usr/file/index.js; Penambahan ini bukan modul teras mahupun modul fail dalam bentuk laluan, jadi cara mencari modul tambahan ini pada masa ini.
/** * /Usr/file/index.js; */ const { add } = require('add'); const result = add(1, 2);
Kami melaksanakan nod dalam fail. direktori. index.js boleh mencetak nilai laluan. Nilai dalam laluan ialah tatasusunan, seperti berikut:
/** * /Usr/file/index.js; */ console.log(module.paths);
Iaitu, Node akan mencari secara berurutan dari direktori di atas untuk melihat sama ada ia mengandungi modul tambah Prinsipnya serupa dengan rantaian prototaip. Mula mencari dalam folder node_modules direktori tahap yang sama dengan fail yang sedang dilaksanakan Jika direktori node_modules tidak ditemui atau tidak wujud, teruskan mencari ke peringkat atas.
[ '/Usr/file/node_modules', '/Usr/node_modules', '/node_modules', ]
Analisis laluan dan kedudukan fail digunakan bersama-sama Pengecam fail boleh tanpa akhiran, atau ia boleh diluluskan Laluan analisis mencari direktori atau pakej Pada masa ini, mencari fail tertentu memerlukan beberapa pemprosesan tambahan.
Analisis sambungan fail
const { add } = require('./add');
比如上面这段代码,文件标识符是不带扩展名的,这个时候node会依次查找是否存在.js、.json、.node文件。
目录和包分析
同样是上面这段代码,通过./add
查找到的可能不是一个文件,可能是一个目录或者包(通过判断add文件夹下是否有package.json文件来判断是目录还是包)。这个时候文件定位的步骤是这样的:
如果package.json里没有main字段,那么也会将index作为文件,然后进行扩展名分析找到对应后缀的文件。
模块编译
我们开发中主要遇到的模块为json模块和js模块。
json模块编译
当我们require一个json模块的时候,实际上Node会帮我们使用fs.readFilcSync去读取对应的json文件,得到json字符串,然后调用JSON.parse解析得到json对象,再赋值给module.exports,然后给到require。
js模块编译
当我们require一个js模块的时候,比如
// index.js const { add } = require('./add');
// add.js exports.add = (a, b) => { return a + b; }
这个时候发生了什么呢,为什么我们可以直接在模块里使用module、exports、require这些变量。这是因为Node在编译js模块的时候对模块的内容进行了首尾的包装。
比如add.js这个模块,实际编译的时候是会被包装成类似这样的结构:
(function(require, exports, module) { exports.add = (a, b) => { return a + b; } return module.exports; })(require, module.exports, module)
即我们编写的js文件是会被包装成一个函数,我们编写的只是这个函数里的内容,Node后续的包装的过程对我们隐藏了。这个函数支持传入一些参数,其中就包括require、exports和module。
当编译完js文件后,就会执行这个文件,node会将对应的参数传给这个函数然后执行,并且返回module.exports值给到require函数。
以上就是Node实现CommonJs规范的基本流程。
更多node相关知识,请访问:nodejs 教程!
Atas ialah kandungan terperinci Ketahui lebih lanjut tentang mekanisme modul Node dan bercakap tentang proses pelaksanaan modul. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!