摘要:本文討論模塊化方案時,的打包工作。省略省略這部分是這部分是這部分是在上面代碼中,我們的和被放進了一個數組中。入口文件的依賴和,會根據依賴的情況往后排。第一個函數也就是執行數組中的第二個函數。還有一個重要的變量。
注:本文重點不是怎樣配置webpack.config.js并實現相應的功能,而是通過對比webpack編譯前和編譯后文件,探究webpack打包后的文件是怎樣加載執行的。
本文討論commonJS模塊化方案時,webpack的打包工作。
為了便于討論,我們準備了一個非常簡單的例子,涉及三個文件,分別是
文件a.js
module.exports ={ say:function(){ console.log("A is saying."); } }
文件b.js
module.exports ={ say:function(){ console.log("B is saying."); } }
文件index.js
var a = require("./a"); var b = require("./b"); a.say(); b.say();
依賴關系非常簡單,即index.js文件依賴a.js和b.js兩個文件。而且是采用commonJS方式來引用的。
我的config文件也貼一下。
var htmlPlugin = require("html-webpack-plugin"); module.exports = { entry:{ index:"./src/index.js" }, output:{ path:"builds", filename:"[name].js", chunkFilename:"chunk.[name].js" }, plugins:[ new htmlPlugin({ filename:__dirname+"/builds/index.html", template:"./index.html" }) ], devServer:{ contentBase:"./builds", inline:true } }
還有一個非常簡單的index.html文件。
commonJS測試
另外,本問的示例代碼已經放到Github上,請 點擊這里查看。
我們在目錄下運行一下webpack命令,builds文件夾里的文件,就是被webpack處理過的文件,也是我們要討論的重點。
我們來看看文件目錄:
builds 里,是編譯后的文件,src里,是我們的原始文件。
那么a.js和b.js呢?打包進builds/index.js文件里面了。打包其實就是干這個的,把多個文件合并到一個或少數幾個文件里。
我們點開builds/index.js,發現我們的代碼被改的面目全非。大家點擊這里看完整的代碼,下面是部分片段。
(function(modules){ var installedModules = {}; function __webpack_require__(moduleId) {/*省略*/} /*省略*/ return __webpack_require__(0); })([ //這部分是index.js function(module, exports, __webpack_require__){ var a = __webpack_require__(1); var b = __webpack_require__(2); a.say(); b.say(); }, //這部分是a.js function(module, exports){ module.exports ={ say:function(){ console.log("A is saying."); } } }, //這部分是b.js function(module, exports){ module.exports ={ say:function(){ console.log("B is saying."); } } } ])
在上面代碼中,我們的index.js、a.js和b.js被放進了一個數組中。入口文件(index.js)都是在數組的0的位置。入口文件的依賴(a.js和b.js),會根據依賴的情況往后排。
這個數組作為IIFE中函數的參數modules傳入function中。注意匿名函數中的return __webpack_require__(0);,這句調用將執行數組中的第一個函數。
第一個函數:
function(module, exports, __webpack_require__) { var a = __webpack_require__(1); var b = __webpack_require__(2); a.say(); b.say(); }
__webpack_require__(1)也就是執行數組中的第二個函數。
第二個函數:
function(module, exports) { module.exports ={ say:function(){ console.log("A is saying."); } } }
第二個函數的執行后的結果,就是把module.exports中的內容賦給了變量a。到這里,大家對代碼的結構有了了解,但是關鍵的__webpack_require__方法是怎樣工作的呢?我們來分析下代碼:
function __webpack_require__(moduleId) { // Check if module is in cache if(installedModules[moduleId]) return installedModules[moduleId].exports; // Create a new module (and put it into the cache) var module = installedModules[moduleId] = { exports: {}, id: moduleId, loaded: false }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded module.loaded = true; // Return the exports of the module return module.exports; }
這里注意modules[moduleId].call(module.exports, module, module.exports, __webpack_require__)這行代碼。其中的modules就是我們剛才講的數組(modules不是module)。module.exports是模塊的上下文,也就是this。所以,如果我們在index.js里加一句this.name="jack",那么最終這個等價于module.exports.name="jack";
此外,我們還可以訪問到module.id這個屬性。這并沒有什么實際的作用,只是可以加深我們的理解。比如,我在a.js中:
module.exports ={ say:function(){ console.log("A is saying."); console.log(module.id); } }
是可以輸出該模塊的id的。多說一句,如果你用webpack-dev-server,它會打包進去其他的文件,這個id會變的比較大(我測試的是75)。有一個可能會用到的module.loaded屬性。我們的模塊在第一次執行的時候,module.loaded還是false,執行過后才被設置為true。
比如下面的代碼:
index.js
if (module.loaded) { var a = require("./a"); a.say(); } else { var b = require("./b"); b.say(); }
在我們的例子中,這個是每次執行的結果都是B is saying.因為每次執行index.js模塊中的代碼都是第一次執行。
在實際的開發中,有可能有要判斷當前代碼是不是第一次執行的需求。
還有一個重要的變量installedModules。我們加載過的模塊中的module.exports對象,會保存在installedModules[moduleId]中。這樣下次調用,就可以直接返回module.exports。
OK,這次就講到這里,希望對同學們學習理解webpack能有幫助。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/50150.html
摘要:全網最貼心系列教程和配套代碼歡迎關注個人技術博客。所以我花費了個多月整理了這份教程,一共分成節,每節都有講解,并且準備了配套代碼。奈何深感水平不夠,只有一腔熱情,所以直接開放了教程和源碼。 webpack-demos:全網最貼心 webpack 系列教程和配套代碼 歡迎關注個人技術博客:godbmw.com。每周 1 篇原創技術分享!開源教程(webpack、設計模式)、面試刷題(偏前...
學習的過程中收藏了這些優秀教程和的項目,希望對你有幫助。 github地址, 有不錯的就更新 官方文檔 中文指南 初級教程 webpack-howto 作者:Pete Hunt Webpack 入門指迷 作者:題葉 webpack-demos 作者:ruanyf 一小時包教會 —— webpack 入門指南 作者:VaJoy Larn webpack 入門及實踐 作者:...
摘要:本文討論模塊化方案時,的打包工作。省略省略這部分是這部分是這部分是在上面代碼中,我們的和被放進了一個數組中。入口文件的依賴和,會根據依賴的情況往后排。第一個函數也就是執行數組中的第二個函數。還有一個重要的變量。 注:本文重點不是怎樣配置webpack.config.js并實現相應的功能,而是通過對比webpack編譯前和編譯后文件,探究webpack打包后的文件是怎樣加載執行的。本文討...
摘要:是一個現代應用程序的靜態模塊打包器,前端模塊化的基礎。作為一個前端工程師切圖仔,非常有必要學習。官網的文檔非常的棒,中文文檔也非常給力,可以媲美的文檔。建議先看概念篇章,再看指南,然后看和配置總覽。 webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器,前端模塊化的基礎。作為一個前端工程師(切圖仔),非常有必要學習。 showImg(https://segment...
摘要:傳送門系列教程一初識系列教程二創建項目,打包第一個文件系列教程三自動生成項目中的文件系列教程四處理項目中的資源文件一系列教程五處理項目中的資源文件二系列教程六使用分割代碼系列教程七使用系列教程八使用審查代碼系列教程九開發環境和生產環境 在前端開發日益復雜的今天,我們需要一個工具來幫助我們管理項目資源,打包、編譯、預處理、后處理等等。webpack的出現無疑是前端開發者的福音,我的博文只...
閱讀 1700·2021-11-02 14:47
閱讀 3648·2019-08-30 15:44
閱讀 1334·2019-08-29 16:42
閱讀 1731·2019-08-26 13:53
閱讀 935·2019-08-26 10:41
閱讀 3458·2019-08-23 17:10
閱讀 597·2019-08-23 14:24
閱讀 1717·2019-08-23 11:59