webpack源碼解析---addEntry

addEntry

EntryPlugin的注冊

webpack會從入口開始解析依賴。

  1. WebpackOptionsApply

    new WebpackOptionsApply().process(compiler, options);
    class WebpackOptionsApply {constructor () {}process () {// 注冊 EntryOptionPlugin new EntryOptionPlugin().apply(compiler);}
    }
    
  2. EntryOptionPlugin
    EntryOptionPlugin的作用是注冊compiler.hooks.entryOption鉤子,當鉤子被觸發的時候,調用EntryOptionPlugin.applyEntryOption方法注冊DynamicEntryPlugin或者EntryPlugin

    class EntryOptionPlugin {apply(compiler) {compiler.hooks.entryOption.tap("EntryOptionPlugin", (context, entry) => {// 調用靜態方法 applyEntryOptionEntryOptionPlugin.applyEntryOption(compiler, context, entry);return true;});}static applyEntryOption(compiler, context, entry) {if (typeof entry === "function") {// 動態入口const DynamicEntryPlugin = require("./DynamicEntryPlugin");new DynamicEntryPlugin(context, entry).apply(compiler);} else {// 普通入口const EntryPlugin = require("./EntryPlugin");for (const name of Object.keys(entry)) {               for (const entry of desc.import) {new EntryPlugin(context, entry, options).apply(compiler);}}}}
    }
    
  3. EntryPlugin

    • 訂閱了compiler.hooks.compilation鉤子,觸發時設置EntryDependency的ModuleFactory normalModuleFactory工廠,這個用于創建入口模塊
    • 訂閱compiler.hooks.make鉤子,觸發的時候調用compilation.addEntry方法,將入口模塊加載到factorizeQueue隊列,這樣依賴就啟動了以入口模塊為七點的模塊構建流程。
    class EntryPlugin {constructor(context, entry, options) {}apply(compiler) {compiler.hooks.compilation.tap("EntryPlugin",(compilation, { normalModuleFactory }) => {compilation.dependencyFactories.set(EntryDependency,normalModuleFactory);});const { entry, options, context } = this;const dep = EntryPlugin.createDependency(entry, options);compiler.hooks.make.tapAsync("EntryPlugin", (compilation, callback) => {compilation.addEntry(context, dep, options, err => {callback(err);});});}
    }
    
  4. EntryPlugin的觸發
    調用compiler.run() -> compiler.compile()方法觸發compiler.hooks.make鉤子,進而觸發EntryPlugin鉤子

class Compiler {compile(callback) {this.hooks.beforeCompile.callAsync(params, err => {this.hooks.compile.call(params);this.hooks.make.callAsync(compilation, err => {})})}
}

流程為: npm run build -> webpack -> webpack-cli -> compiler.run() -> compiler.compile() -> compiler.hooks.make.callAsync() -> EntryPlugin -> compilation.addEntry()

compilation.addEntry方法的講解

方法參數

  1. context: 上下文目錄,構建中就是當前目錄的項目目錄
  2. entry: 入口對象,結合EntryPlugin可以看到傳入的路由,Entryplugin.createDependency方法返回值對象
  3. optionsOrName: 選項或者名字
  4. callback: entry的回調函數,用于和compiler通信進行后續的流程
class Compilation {addEntry(context, entry, optionsOrName, callback) {const options =typeof optionsOrName === "object"? optionsOrName: { name: optionsOrName };this._addEntryItem(context, entry, "dependencies", options, callback);}_addEntryItem(context, entry, target, options, callback) {}
}

方法邏輯

  1. 標準化處理options,根據optionsOrName格式化成不同的對象
  2. 調用compilation._addEntryItem()方法
compilation._addEntryItem
  • context: webpack構建上下文目錄,以及項目目錄
  • entry: 入口對象,上文中的EntryPlugin.createDependency()返回的EntryDependency類型的實例對象
  • target: 目標類型,用于在entryData中分類類型進行緩存的標志
  • options: webpack的配置對象或者是nameOptions對象,由compilation.addEntry標準化
  • callback: 回調函數,用于和compiler進行通信使用
class Compilation {_addEntryItem(context, entry, target, options, callback) {// 根據options是否由name屬性或者是compilation.entries或者是compilation.globalEntry中嘗試獲取緩存的入口entryDataconst { name } = options;let entryData =name !== undefined ? this.entries.get(name) : this.globalEntry;// 沒有entryData的時候,會構建entryData對象,將其緩存到compilation.entries,另外entryData.dependency設置為初始的entry入口對象if (entryData === undefined) {entryData = {dependencies: [],includeDependencies: [],options: {name: undefined,...options}};entryData[target].push(entry);this.entries.set(name, entryData);} else {// 這里不成立,先忽略}    // 觸發this.hooks.addEntry鉤子this.hooks.addEntry.call(entry, options);// this.addModuleTree方法this.addModuleTree(/* ... */);}
}

callback回調 => _addEntryItem的回調

addEntry(context, entry, optionsOrName, callback) {this._addEntryItem(context, entry, "dependencies", options, callback);
}

compilation.addModuleTree

  • context: 上下文,當前項目的目錄
  • dependency: 依賴對象
  • contextInfo: 上下文對象
class Compilation {// ...addModuleTree({ context, dependency, contextInfo }, callback) {const Dep =  dependency.constructor;const moduleFactory = this.dependencyFactories.get(Dep);this.handleModuleCreation({factory: moduleFactory,dependencies: [dependency],originModule: null,contextInfo,context},(err, result) => {if (err && this.bail) {} else if (!err && result) {callback(null, result);} else {callback();}});}
}

執行模塊以及其依賴的子模塊的構建,構建工作

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37964.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37964.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37964.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于路徑長度的樣條插補算法(自動駕駛和路徑跟蹤控制適用)

以前在做車輛跟蹤控制的時候發現在針對有多個X和多個Y對應的路徑插補時候,總是報錯,因為MATLAB里面的interp1插補函數它要求x要唯一對應一個y,當路徑以單獨的x或者y來求插補時候的時候就報錯。由于在使用Matlab的interp1函數進行插值時&#…

怎樣才能更好地保護個人賬號的安全

怎樣才能更好地保護個人賬號的安全 保護個人賬號安全是網絡安全的重要組成部分,以下是一些有效的措施來增強賬號的安全性: 1. 使用強密碼 復雜性:創建包含大小寫字母、數字和特殊字符的密碼。長度:密碼至少應有12個字符長。唯一…

談談檢測瀏覽器類型

前幾天被問到如何檢測瀏覽器類型,我突然發現我對此并不了解,之前的項目中也沒有使用到過,只隱約記得通過一個自帶的方法即可獲取。所以今天特意來仔細補習一下。 核心:navigator.userAgent 1.正則表達式 2.引用外部庫 3.判斷瀏…

【Android面試八股文】你知道什么是冷啟動和熱啟動嗎?你知道應用冷啟動的全流程嗎?你知道如何解決啟動時候的黑白屏問題?

文章目錄 一、冷啟動、熱啟動的概念二、冷啟動的流程冷啟動啟動流程:流程細節三、如何解決啟動時候的黑白屏問題?一、冷啟動、熱啟動的概念 在Android開發中,冷啟動和熱啟動是兩個重要的概念,它們描述了應用程序啟動時不同的狀態和表現: 冷啟動(Cold Start): 冷啟動指…

記一次kafka使用不當導致的服務器異常

一、背景 1.運維反饋服務器cpu高&#xff0c;且高達80% 2.經過排查發現kafka出現消息積壓情況 3.使用的是springboot kafka框架 dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency…

Linux-網絡安全私房菜

文章目錄 前言入門基本指令篇章字符集設置cdlsdatemkdirtouch-d-m 修改主機名rmshredrename重命名mv移動tar打包與壓縮打包但是不壓縮打包且壓縮更新包文件解壓對應的包 zip壓縮文件命令cat查看顯示行號交互寫入&#xff08;追加&#xff09;顯示空行 more和lesshead和tailhead…

Android的懸浮時鐘(一)

在Android&#xff0c;如果要懸浮在其他應用上方顯示時鐘或者其他界面的話是需要申請權限的。 首先在manifest中我們就要寫自己要申請的權限SYSTEM_ALERT_WINDOW <uses-permission android:name"android.permission.SYSTEM_ALERT_WINDOW" /> 不同于請求照片或…

期末復習---程序填空

注意&#xff1a; 1.數組后移 *p *(p-1) //把前一個數賦值到后一個數的位置上來覆蓋后一個數 2.指針找最大字符 max *p while( *p){ if( max< *p) { max*p; qp;/ 用新的指針指向這個已經找到的最大位置&#xff1b;!!!!!!!!! } p; //因為開始沒有next &#xff…

Web工程化

1、webpack 1.1 概念 一個前端打包器。 webpack 只識別javascript. 所以需要安裝nodejs環境。 1.2 運行環境 Nodejs Nodejs 是運行JavaScript的環境。 因為nodejs發布了許多版本&#xff0c;在不同的技術棧下&#xff0c;需要使用不同的nodejs。 所以需要在電腦上安裝n…

web應用技術-第十一次課后作業

驗證過濾器進行權限驗證的原理。 Filter過濾器&#xff1a;可以把對資源的請求攔截下來&#xff0c;從而實現一些特殊的功能。一般完成登錄校驗、統一編碼處理、敏感字符處理等通用操作。 定義&#xff1a;實現Filter接口 配置&#xff1a;WebFilter(urlPatterns"/*&qu…

常見VPS主機術語有哪些?VPS術語解析

常見VPS主機術語有哪些&#xff1f;本期為大家解析一下我們常見到的聽到的VPS專業術語&#xff0c;幫助大家更輕松的了解VPS主機相關知識。 常見VPS主機術語 Apache – 世界上最流行的 Web 服務器軟件。 CentOS – 旨在提供基于 Red Hat Enterprise Linux 的企業級操作系統的…

mysql 主主HA高可用方案詳解

1.環境準備&#xff1a; 主機&#xff1a;1921.4,1921.5 操作系統&#xff1a;centos 7.3 mysql數據庫版本&#xff1a;mysql 5.7.13 浮動IP:1921.182 2.mysql 下載及解壓安裝配置 2.1 下載&#xff1a; #wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.13-linu…

easyexcel 模板填充Excel數據,實現自定義換行及動態調整行高,并保持列表格式一致

pom依賴&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.5</version> </dependency><dependency><groupId>com.alibaba</groupId><artifa…

數據結構-線性表的應用

目錄 前言一、有序表的合并1.1 順序表實現1.2 單鏈表實現 二、稀疏多項式的相加和相乘2.1 稀疏多項式的相加2.2 稀疏多項式的相乘 總結 前言 本篇文章介紹線性表的應用&#xff0c;分別使用順序表和單鏈表實現有序表的合并&#xff0c;最后介紹如何使用單鏈表實現兩個稀疏多項…

基于springboot+vue+uniapp的超市售貨管理平臺

開發語言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服務器&#xff1a;tomcat7數據庫&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;數據庫工具&#xff1a;Navicat11開發軟件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

考研生活day2--王道課后習題2.3.1、2.3.2、2.3.3

2.3.1 題目描述&#xff1a; 這題和曾經做過的LeetCode203.移除元素一模一樣&#xff0c;所以我們就使用LeetCode進行書寫&#xff0c;題目鏈接203. 移除鏈表元素 - 力扣&#xff08;LeetCode&#xff09; 解題思路 大家的第一反應肯定是根據書上所學的書寫方法一樣書寫&…

【PB案例學習筆記】-26制作一個帶浮動圖標的工具欄

寫在前面 這是PB案例學習筆記系列文章的第26篇&#xff0c;該系列文章適合具有一定PB基礎的讀者。 通過一個個由淺入深的編程實戰案例學習&#xff0c;提高編程技巧&#xff0c;以保證小伙伴們能應付公司的各種開發需求。 文章中設計到的源碼&#xff0c;小凡都上傳到了gite…

爬蟲cookie是什么意思

“爬蟲 cookie”指的是網絡爬蟲在訪問網站時所使用的cookie&#xff0c;網絡爬蟲是一種自動化程序&#xff0c;用于在互聯網上收集信息并進行索引&#xff0c;這些信息可以用于搜索引擎、數據分析或其他目的。 本教程操作系統&#xff1a;Windows10系統、Dell G3電腦。 “爬蟲…

51-1 內網信息收集 - 內網資源探測

導語 在內網滲透過程中,通常需要利用各種技術來探測內網資源,為后續的橫向滲透做準備。發現內網存活的主機及其詳細信息可以幫助確定攻擊方向和潛在的漏洞。 一、基于 ICMP 發現存活主機 ICMP(Internet Control Message Protocol,因特網控制消息協議)是 TCP/IP 協議簇的…

一段式、二段式和三段式狀態機的特點及適用情況:

在FPGA設計中,狀態機的選擇主要取決于具體應用場景和設計需求。 一段式狀態機: 優點: 結構簡單,易于理解和實現占用資源少時序邏輯簡單,延遲小 缺點: 組合邏輯復雜度高可能存在毛刺問題不易于大規模狀態機的設計 適用場景: 簡單的控制邏輯狀態數量較少的場合對時序要求較…