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