บทนำและข้อมูล
ผ่าน API อย่างเป็นทางการของ Node.js เราจะเห็นว่า Node.js นั้นมีโมดูลหลักมากมาย http://nodejs.org/api/ โมดูลหลักเหล่านี้รวบรวมไว้ในไฟล์ไบนารีและสามารถรับได้โดยต้องการ ('ชื่อโมดูล'); โมดูลหลักมีลำดับความสำคัญในการโหลดสูงสุด (จะสะท้อนให้เห็นเมื่อมีโมดูลและโมดูลหลักที่มีชื่อเดียวกัน)
(คราวนี้เราพูดถึงโมดูลที่กำหนดเองเป็นหลัก)
node.js ยังมีประเภทของโมดูลที่เป็นโมดูลไฟล์ซึ่งสามารถเป็นไฟล์รหัส JavaScript (.js เป็นไฟล์เสริม) ไฟล์ข้อความรูปแบบ JSON (.json เป็นไฟล์เสริม) หรือไฟล์ C/C ++ ที่แก้ไขแล้ว (.node เป็นไฟล์เสริมไฟล์);
วิธีการเข้าถึงโมดูลไฟล์สามารถเข้าถึงได้ผ่านต้องการ ('/filename.suffix') ต้องการ ('./ filename.suffix') requrie ('../ filename.suffix') และสามารถละเว้นคำต่อท้ายไฟล์; เริ่มต้นด้วย "/" ถูกโหลดด้วยเส้นทางที่แน่นอนเริ่มต้นด้วย "./" และเริ่มต้นด้วย "../" หมายถึงการโหลดด้วยเส้นทางสัมพัทธ์และเริ่มต้นด้วย "./" หมายถึงการโหลดด้วยไฟล์ในไดเรกทอรีในระดับเดียวกัน
ไฟล์คำต่อท้ายที่กล่าวถึงก่อนหน้านี้สามารถละเว้นไฟล์ js ลำดับความสำคัญที่ nodejs พยายามโหลด> ไฟล์ json> ไฟล์โหนด
สร้างโมดูลที่กำหนดเอง
ยกตัวอย่างเป็นตัวอย่าง
การคัดลอกรหัสมีดังนี้:
var outputVal = 0; // ค่าเอาต์พุต
เพิ่ม var = 1; // เพิ่มขึ้น
/* ตั้งค่าเอาต์พุต*/
ฟังก์ชั่น seoutputval (val) {
outputVal = val;
-
/* ตั้งค่าการเพิ่มขึ้น*//
ฟังก์ชั่น setIncrement (เพิ่มขึ้น) {
การเพิ่ม = เพิ่มขึ้น val;
-
/* เอาต์พุต*/
ฟังก์ชั่น printnextcount ()
-
outputVal += เพิ่มขึ้น;
console.log (outputVal);
-
ฟังก์ชั่น printoutputval () {
console.log (outputVal);
-
exports.seoutputVal = seoutputVal;
Exports.setIncrement = setIncrement;
module.exports.printnextCount = printNextCount;
ซอร์สโค้ดตัวอย่างโมดูลที่กำหนดเอง
จุดสนใจของตัวอย่างคือการส่งออกและโมดูลส่งออก; มันมีอินเทอร์เฟซการเข้าถึงภายนอก เรียกมันว่าเพื่อดูเอฟเฟกต์
เรียกโมดูลที่กำหนดเอง
การคัดลอกรหัสมีดังนี้:
-
ไฟล์ node.js เป็นโมดูลซึ่งอาจเป็นรหัส JavaScript, JSON หรือส่วนขยาย C/C ++ ที่รวบรวม
วัตถุสำคัญสองอย่าง:
จำเป็นต้องได้รับโมดูลจากภายนอก
การส่งออกเปิดเผยอินเทอร์เฟซโมดูล
-
var counter = ต้องการ ('./ 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 ();
-
ต้องการการโทรไปยังโมดูลเดียวกันหลายครั้งจะไม่ถูกโหลดซ้ำ ๆ
-
var counter = ต้องการ ('./ 1_modules_custom_counter');
console.log ('โมดูลการโทรที่สอง [1_modules_custom_counter]');
counter.printnextcount ();
ซอร์สโค้ดโทรโหมดกำหนดเอง
เรียกใช้และพบว่าทั้งสองวิธีที่เปิดเผยต่อสาธารณะผ่านการส่งออกและโมดูลสามารถเข้าถึงได้!
อย่างที่คุณเห็นในตัวอย่างฉันได้รับโมดูลสองครั้งโดยต้องการ ('./ 1_modules_custom_counter') แต่หลังจากการอ้างอิงครั้งที่สองฉันเรียกวิธี PrintNextCount () เริ่มต้นจาก 60 ~~~
เหตุผลก็คือ Node.js เรียกโมดูลเดียวกันหลายครั้งผ่านทางที่ต้องการและจะไม่โหลดซ้ำ ๆ node.js จะแคชโมดูลไฟล์ที่โหลดทั้งหมดตามชื่อไฟล์ดังนั้นจะไม่โหลดใหม่
หมายเหตุ: การแคชผ่านชื่อไฟล์หมายถึงชื่อไฟล์จริงและจะไม่ถือว่าเป็นไฟล์ที่แตกต่างกันเนื่องจากเส้นทางที่เข้ามาแตกต่างกัน
มีเมธอด printoutputVal () ในไฟล์ 1_modules_custom_counter ที่ฉันสร้างขึ้นซึ่งไม่ได้ให้วิธีการเข้าถึงสาธารณะผ่านการส่งออกหรือโมดูล exports
จะเกิดอะไรขึ้นถ้าคุณเข้าถึงไฟล์ 1_modules_load โดยตรง
คำตอบคือ: TypeError: Object #<jobch> ไม่มีวิธี 'PrintOutputVal'
ความแตกต่างระหว่างการส่งออกและโมดูลส่งออก
ผ่านตัวอย่างข้างต้นทั้งการส่งออกและโมดูลการส่งออกพร้อมสำหรับการเข้าถึง! เนื่องจากทั้งคู่สามารถบรรลุผลได้จึงต้องมีความแตกต่างเล็กน้อย ~~~ มายกตัวอย่าง!
การคัดลอกรหัสมีดังนี้:
var counter = 0;
exports.printnextCount = function () {
เคาน์เตอร์ += 2;
console.log (เคาน์เตอร์);
-
var iseq = (exports === module.exports);
console.log (iseq);
2_modules_diff_exports.js ซอร์สโค้ดไฟล์ไฟล์
มาสร้างไฟล์ 2_modules_diff_exports_load.js ใหม่แล้วโทรหามัน
การคัดลอกรหัสมีดังนี้:
var counter = ต้องการ ('./ 2_modules_diff_exports');
counter.printnextcount ();
หลังจากการโทรแล้วผลลัพธ์การดำเนินการดังแสดงในรูปด้านบน
ฉันเอาต์พุตค่าของ iseq ในไฟล์ 2_modules_diff_exports_load.js (var iseq = (exports === module.exports);), true ที่ส่งคืน
PS: โปรดทราบว่ามีสามสัญญาณเท่ากัน หากคุณไม่ทราบว่าคุณกำลังมองหาข้อมูลด้วยตัวเอง!
อย่ารีบดึงข้อสรุปเปลี่ยนไฟล์ JS สองไฟล์นี้เป็นรหัสที่สอดคล้องกันของโมดูล exports
การคัดลอกรหัสมีดังนี้:
// รหัสต้นฉบับ 2_modules_diff_exports.js มีดังนี้
var counter = 0;
module.exports = function () {
เคาน์เตอร์ += 10;
this.printnextCount = function ()
-
console.log (เคาน์เตอร์);
-
-
var iseq = (exports === module.exports);
console.log (iseq);
การคัดลอกรหัสมีดังนี้:
// การแก้ไข 2_modules_diff_exports_load.js ซอร์สโค้ดไฟล์มีดังนี้
var counter = ต้องการ ('./ 2_modules_diff_exports');
var counterobj = ตัวนับใหม่ ();
Counterobj.printnextcount ();
หลังจากการโทรแล้วผลลัพธ์การดำเนินการดังแสดงในรูปด้านบน
ฉันเอาต์พุตค่าของ ISEQ ในไฟล์ 2_Modules_Diff_Exports_Load.js (var iseq = (exports === โมดูล exports);) และเท็จที่ส่งคืนซึ่งไม่สอดคล้องกับผลลัพธ์ที่ได้มาก่อน!
PS: อย่าใช้ counter.printnextcount (); ในการเข้าถึงคุณจะได้รับพรอมข้อผิดพลาดเท่านั้น
API ให้คำอธิบาย
http://nodejs.org/api/modules.html
โปรดทราบว่าการส่งออกเป็นการอ้างอิงถึงโมดูลการส่งออกทำให้เหมาะสำหรับการเสริมเท่านั้น หากคุณกำลังส่งออกรายการเดียวเช่นตัวสร้างคุณจะต้องใช้โมดูลส่งออกโดยตรงแทน
การส่งออกเป็นเพียงการอ้างอิงที่อยู่ไปยังโมดูลส่งออก NodeJS จะส่งออกตัวชี้ของโมดูลส่งออกเท่านั้น หากตัวชี้การส่งออกมีการเปลี่ยนแปลงมันเป็นเพียงการส่งออกไม่ได้ชี้ไปที่โมดูลส่งออกดังนั้นพวกเขาจะไม่ถูกส่งออกอีกครั้ง
อ้างถึงความเข้าใจอื่น ๆ :
http://www.hacksparrow.com/node-js-exports-vs-module-exports.html
http://zihua.li/2012/03/use-module-exports-or-exports-in-node/
module.exports เป็นอินเทอร์เฟซจริงการส่งออกเป็นเพียงเครื่องมือเสริมสำหรับมัน การกลับมาสู่การโทรครั้งสุดท้ายคือโมดูลส่งออกแทนที่จะส่งออก
คุณสมบัติและวิธีการทั้งหมดที่รวบรวมโดยการส่งออกจะถูกกำหนดให้กับโมดูลส่งออก แน่นอนว่ามีข้อกำหนดเบื้องต้นสำหรับสิ่งนี้นั่นคือโมดูลการส่งออกเองไม่มีคุณลักษณะหรือวิธีการใด ๆ
หาก Module.exports มีคุณสมบัติและวิธีการบางอย่างข้อมูลที่รวบรวมโดยการส่งออกจะถูกละเว้น
การส่งออกและโมดูลส่งออกแทนที่
ข้างต้นยังเข้าใจถึงความสัมพันธ์และความแตกต่างระหว่างการส่งออกและโมดูลส่งออก แต่ถ้าการส่งออกและโมดูลมีการส่งออกสำหรับทั้งวิธี PrintNextCount () ผลลัพธ์คืออะไร?
โทร
ดังที่เห็นได้จากผลลัพธ์ไม่มีข้อผิดพลาดซึ่งหมายความว่าสามารถกำหนดได้เช่นนี้ แต่ในโมดูลสุดท้ายการส่งออกส่งออกการส่งออก
แม้ว่าผลลัพธ์จะไม่เกิดข้อผิดพลาดหากคุณใช้เช่นนี้ แต่ก็จะมีปัญหาบางอย่างในการพัฒนาอย่างหลีกเลี่ยงไม่ได้
1. เป็นการดีที่สุดที่จะไม่กำหนดโมดูลส่งออกและส่งออกแยกกัน
2.nodejs นักพัฒนาแนะนำโมดูลส่งออกไปส่งออกวัตถุและส่งออกเพื่อส่งออกหลายวิธีและตัวแปร
อื่น...
มีวิธีอื่น ๆ ใน API ดังนั้นฉันจะไม่เข้าไปดูรายละเอียด จากตัวอย่างข้างต้นคุณจะรู้ด้วยตัวเองด้วยตัวเองทันทีที่คุณส่งออก
module.id
ส่งคืนตัวระบุโมดูลของประเภทสตริงซึ่งโดยทั่วไปจะเป็นชื่อไฟล์ที่แยกวิเคราะห์เต็มรูปแบบ
module.filename
ส่งคืนชื่อไฟล์ที่แยกวิเคราะห์เต็มรูปแบบของประเภทสตริง
module.loaded
ส่งคืนประเภทบูลแสดงว่าการโหลดเสร็จสมบูรณ์
module.parent
ส่งคืนโมดูลที่อ้างอิงโมดูล
โมดูลเด็ก
ส่งคืนอาร์เรย์ของวัตถุโมดูลทั้งหมดที่อ้างอิงโดยโมดูลนี้