
ในฐานะ front-end "siege lion" Webpack นั้นคุ้นเคยกันดีอยู่แล้ว Webpack สามารถทำสิ่งต่าง ๆ มากมายเกินไป มันสามารถรวมทรัพยากรทั้งหมดไว้เป็นแพ็คเกจ (รวมถึง JS, TS, JSX, รูปภาพ, แบบอักษร, CSS และอื่น ๆ ) และวางไว้ในการอ้างอิง . ช่วยให้คุณสามารถอ้างอิงการพึ่งพาเพื่อใช้ทรัพยากรได้ตามความต้องการของคุณ Webpack ทำงานได้อย่างยอดเยี่ยมในการแปลทรัพยากรไฟล์หลายรายการในส่วนหน้าและวิเคราะห์การพึ่งพาโมดูลที่ซับซ้อน เรายังปรับแต่งตัวโหลดและโหลดทรัพยากรของเราเองได้อย่างอิสระ แล้ว Webpack จะนำบรรจุภัณฑ์ไปใช้อย่างไร วันนี้มาลองดูครับ.
1. ข้อกำหนดคืออะไร?
เมื่อพูดถึง need สิ่งแรกที่นึกถึงคือการนำเข้า คือการนำเข้าไวยากรณ์มาตรฐานของ es6
- need คือการเรียกรันไทม์ ดังนั้นในทางทฤษฎีแล้ว need สามารถใช้ได้ทุกที่ในโค้ด
- การนำเข้าคือเวลาคอมไพล์ ดังนั้นจะต้องวางไว้ที่จุดเริ่มต้นของไฟล์
เมื่อเราใช้ Webpack เพื่อคอมไพล์ เราจะใช้ babel เพื่อแปลการนำเข้าเป็น need . AMD และ CMD ยังใช้วิธีการที่ต้องการในการอ้างอิง
ตัวอย่างเช่น:
var add = need('./a.js');
พูดง่ายๆ ก็คือ add(1,2)
required จริงๆ แล้วเป็นฟังก์ชัน และ ./a.js ที่อ้างอิงเป็นเพียงพารามิเตอร์ของฟังก์ชัน
2. การส่งออกคืออะไร?
ที่นี่เราถือว่าการส่งออกเป็นวัตถุ คุณสามารถดูการใช้งานเฉพาะของการส่งออก MDN
ได้ มาดูโครงสร้างรหัสหลังบรรจุภัณฑ์ของเราก่อน เราจะพบว่าข้อกำหนดดังกล่าวและการส่งออกจะปรากฏขึ้นหลังบรรจุภัณฑ์
เบราว์เซอร์บางประเภทไม่สามารถดำเนินการได้ซึ่งจำเป็นต้องมีการส่งออก คุณต้องใช้งานและส่งออกด้วยตนเองเพื่อให้แน่ใจว่าโค้ดทำงานได้ตามปกติ รหัสแพ็กเกจเป็นฟังก์ชันที่ดำเนินการด้วยตนเอง พารามิเตอร์มีข้อมูลการพึ่งพาและรหัสของไฟล์

ภาพวาดการออกแบบโดยรวมมีดังนี้:

ขั้นตอนที่ 1: เขียนไฟล์คอนฟิกูเรชันของเรา
ไฟล์คอนฟิกูเรชันจะกำหนดค่ารายการแพ็กเกจและเอาต์พุตแพ็กเกจทางออกเพื่อเตรียมพร้อมสำหรับไฟล์ที่สร้างขึ้นในภายหลัง
const path = need("เส้นทาง");
โมดูล.ส่งออก = {
รายการ: "./src/index.js",
เอาท์พุท: {
path: path.resolve(__dirname, "./dist"),//ที่อยู่ไฟล์ที่ส่งออกหลังจากการแพ็กเกจต้องใช้เส้นทางที่แน่นอน ดังนั้นจึงต้องระบุเส้นทาง
ชื่อไฟล์:"main.js"
-
โหมด: "การพัฒนา" ขั้นตอนที่ 2: แนวคิดโดยรวมของการวิเคราะห์โมดูล
: โดยสรุปคือการใช้ไฟล์ fs เพื่ออ่านไฟล์รายการและรับเส้นทางของไฟล์ที่ต้องพึ่งพาการนำเข้าผ่าน AST หากไฟล์ที่ต้องพึ่งพายังคงอยู่ มีการขึ้นต่อกัน ทำซ้ำต่อไปจนกว่าการวิเคราะห์การขึ้นต่อกันจะชัดเจน และคงอยู่ในแผนที่
รายละเอียดโดยละเอียด : บางคนอาจสงสัยว่าเหตุใดจึงใช้ AST เนื่องจาก AST เกิดมาพร้อมกับฟังก์ชันนี้ ImportDeclaration สามารถช่วยให้เรากรองไวยากรณ์การนำเข้าได้อย่างรวดเร็ว แน่นอนว่าคุณสามารถใช้การจับคู่แบบปกติได้เช่นกัน สตริงหลังจากถูกอ่าน โดยการเขียน regex ที่ยอดเยี่ยมนั้นมีประโยชน์สำหรับการรับเส้นทางการพึ่งพาไฟล์ แต่ก็ยังไม่สวยงามพอ
ไฟล์ index.js
{ str } จาก "./a.js";
console.log(`${str} Webpack`) นำเข้า ไฟล์ a.js
{ b} จาก "./b.js"
ส่งออก const str = "hello" ไฟล์ b.js
ส่งออก const b="bbb"
การวิเคราะห์โมดูล Webpack : ใช้ @babel/parser ของ AST เพื่อแปลงสตริงที่อ่านจากไฟล์เป็นแผนผัง AST และ @babel/traverse สำหรับ ไวยากรณ์ วิเคราะห์และใช้ ImportDeclaration เพื่อกรองการนำเข้าและค้นหาการอ้างอิงไฟล์
เนื้อหา const = fs.readFileSync(entryFile, "utf-8");
const ast = parser.parse (เนื้อหา { sourceType: "โมดูล" });
const dirname = path.dirname (รายการไฟล์);
ผู้อยู่ในอุปการะ const = {};
สำรวจ (ast, {
ImportDeclaration ({ โหนด }) {
//กรองการนำเข้าออก
const newPathName = "./" + path.join (dirname, node.source.value);
ผู้อยู่ในอุปการะ [node.source.value] = newPathName;
-
-
const { รหัส } = TransformerFromAst (ast, null, {
ค่าที่ตั้งไว้ล่วงหน้า: ["@babel/preset-env"]
-
กลับ {
ไฟล์รายการ,
อยู่ในความอุปการะ,
รหัส
} ผลลัพธ์มีดังนี้:

ใช้การเรียกซ้ำหรือการวนซ้ำเพื่อนำเข้าไฟล์ทีละไฟล์สำหรับการวิเคราะห์การพึ่งพา โปรดทราบว่าเราใช้ for loop เพื่อวิเคราะห์การขึ้นต่อกันทั้งหมด สาเหตุที่การวนซ้ำสามารถวิเคราะห์การขึ้นต่อกันทั้งหมดได้ก็คือความยาวของโมดูลจะเปลี่ยนไป การขึ้นต่อกันใหม่ modules.length จะเปลี่ยนไป
สำหรับ (ให้ i = 0; i < this.modules.length; i++) {
รายการ const = this.modules [i];
const { ผู้อยู่ในอุปการะ } = รายการ;
ถ้า (อยู่ในความอุปการะ) {
สำหรับ (ให้ j อยู่ในความอุปการะ) {
this.modules.push(this.parse(ผู้อยู่ในอุปการะ[j]));
-
-
} ขั้นตอนที่ 3: เขียนฟังก์ชัน WebpackBootstrap + สร้างไฟล์เอาต์พุต
เขียน ฟังก์ชัน WebpackBootstrap : สิ่งแรกที่เราต้องทำที่นี่คือฟังก์ชัน WebpackBootstrap หลังจากการคอมไพล์ การนำเข้าซอร์สโค้ดของเราจะถูกแยกวิเคราะห์เนื่องจากเบราว์เซอร์ ไม่รู้จัก need ดังนั้นเราต้องประกาศก่อน อย่างไรก็ตาม เมื่อเขียนฟังก์ชัน คุณต้องใส่ใจกับการแยกขอบเขตเพื่อป้องกันมลภาวะที่แปรผัน นอกจากนี้เรายังจำเป็นต้องประกาศการส่งออกในโค้ดของเราเพื่อให้แน่ใจว่ามีการส่งออกอยู่แล้วเมื่อมีการดำเนินการโค้ด
สร้างไฟล์เอาต์พุต : เราได้เขียนที่อยู่ของไฟล์ที่สร้างขึ้นในไฟล์กำหนดค่าแล้ว จากนั้นใช้ fs.writeFileSync เพื่อเขียนลงในโฟลเดอร์เอาต์พุต
ไฟล์ (รหัส) {
const filePath = path.join (this.output.path, this.output.filename)
const newCode = JSON.stringify (รหัส);
// สร้างเนื้อหาไฟล์บันเดิล const Bundle = `(function(modules){
ฟังก์ชั่นต้องการ (โมดูล) {
ฟังก์ชั่น pathRequire (relativePath) {
ส่งคืนต้องการ (โมดูล [โมดูล] .ผู้พึ่งพา [relativePath])
-
const ส่งออก={};
(ฟังก์ชั่น (ต้องการ, ส่งออก, รหัส) {
ประเมินผล(รหัส)
})(pathRequire,exports,modules[module].code);
ส่งคืนการส่งออก
-
ต้องการ('${this.entry}')
})(${รหัสใหม่})`;
// WebpackBoostrap
//สร้างไฟล์. วางไว้ในไดเร็กทอรี dist fs.writeFileSync(filePath,bundle,'utf-8')
- 
ขั้นตอนที่ 4: วิเคราะห์ลำดับการดำเนินการ

เราสามารถเรียกใช้ผลลัพธ์ที่จัดทำแพ็คเกจได้ในคอนโซลของเบราว์เซอร์ หากทำงานได้ตามปกติ ควรพิมพ์ hello Webpack

ข้างต้น เราควรมีความเข้าใจพื้นฐานเกี่ยวกับกระบวนการทั่วไปของ Webpack การใช้ AST เพื่อแยกวิเคราะห์โค้ดเป็นเพียงวิธีการสาธิตนี้ ไม่ใช่การใช้งานจริงของ Webpack มีวิธีแยกวิเคราะห์ AST ของตัวเอง ซึ่งก็คือ เปลี่ยนแปลงตลอดเวลา ระบบนิเวศของ Webpack สมบูรณ์มาก เด็ก ๆ ที่สนใจสามารถพิจารณาคำถามสามข้อต่อไปนี้: