天天看點

Webpack打封包件之乞丐版學習

開始學習,當然是從最簡單的開始,首先是搭建項目結構,具體操作如下

開始搭建項目

  • 建立一個目錄study_webpack
  • 進入進入study_webpack,

    npm init -y

    初始化項目
  • 建立src目錄,并進入src,建立檔案
    • index.js
    • index.html
  • 建立webpack.congfig.js檔案

配置webpack和完成簡單的代碼結構

  • webpack.config.js
    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: './src/index.js',
        output: {
            path: path.join(__dirname, 'dist'),
            filename: 'boundle.js'
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: path.join(__dirname, './src/index.html'),
                filename: 'index.html',
                hash: true
            })
        ]
    }
               
  • inde.js
    document.getElementById('btn').addEventListener('click', function () {
        alert('click btn')
    }, false)
               
  • index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <div id="root">
    
        </div>
        <button id="btn">test</button>
        <script src="./boundle.js"></script>
    </body>
    </html>
               
  • 在package.json中的scripts中添加一句指令
    {
      "scripts": {
        "build": "webpack --mode development"
      },
    }
    
               

打封包件

需要注意的是,這裡的代碼和打包後的代碼并不是完全一樣的,删除了部分目前沒有使用到的邏輯,友善自己閱讀
  • 使用cmd進入目前目錄,然後輸入如下指令
    num run build
               
  • /dist

    目錄檢視打包後的檔案

    boundle.js

    , 一下是簡單的檔案結構和解釋
    (function(modules) { // webpackBootstrap webpack啟動入口
        debugger
     	// The module cache webpack緩存對象
     	var installedModules = {};
    
     	// The require function webpack加載函數
     	function __webpack_require__(moduleId) {
    
     		// Check if module is in cache 檢查子產品是否被緩存
     		if(installedModules[moduleId]) {
                //  如果被緩存,則直接傳回緩存中子產品的exports導出的對象
     			return installedModules[moduleId].exports;
     		}
     		// Create a new module (and put it into the cache) 建立一個子產品
     		var module = installedModules[moduleId] = {
     			i: moduleId, // 子產品id
     			l: false, // 是否被加載
     			exports: {} // 子產品導出對象,預設為空
     		};
    
     		// Execute the module function 執行子產品方法
     		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    
     		// Flag the module as loaded 标記子產品已經被加載
     		module.l = true;
    
     		// Return the exports of the module 傳回子產品module.exports導出的對象
     		return module.exports;
     	}
    
    
     	// expose the modules object (__webpack_modules__) 将module挂載到__webpack_require__函數上
     	__webpack_require__.m = modules;
    
     	// expose the module cache 将緩存子產品挂載到__webpack_require__函數上
     	__webpack_require__.c = installedModules;
    
    
     	// __webpack_public_path__ // 公共路徑
     	__webpack_require__.p = "";
    
    
     	// Load entry module and return exports // 加載入口檔案
     	return __webpack_require__(__webpack_require__.s = "./src/index.js");
     })
    /************************************************************************/
     ({
    
    /***/ "./src/index.js":
    /*!**********************!*\
      !*** ./src/index.js ***!
      \**********************/
    /*! no static exports found */
    /***/ (function(module, exports) {
    
    eval("doucment.addEventListener('click', function () {\r\n    alert('click btn')\r\n}, false)\n\n//# sourceURL=webpack:///./src/index.js?");
    
    /***/ })
    
     });
               

分析代碼執行過程

這個過程很簡單,就是自己在代碼的最頂端加一個

debugger

然後一步一步的看,到底在做什麼,一直到最後完成檔案加載
  • 代碼為一個自執行函數,我們的入口檔案被作為一個參數傳遞給webpack的入口啟動程式
  • 将入口檔案挂載到

    __webpack_require__

    函數上
  • 将緩存個對象挂載到

    __webpack_require__

    函數上
  • 調用

    __webpack_require__

    加載入口檔案,并将結果傳回
  • 進入

    __webpack_require__

    函數
    • moduleID = ‘./src/index.js’,拿到形參
    • 檢測是否已經被加載
    • 建立一個新的子產品module,并将moduleId指派給該對象
    • 使用module為執行上下文加載該函數,并傳入如下參數,子產品導出對象,子產品,__webpack_require__作為require函數傳入,友善我們在子產品内部加載其他子產品

總結

以上是最簡單的webpack包後的檔案加載邏輯,看起來也是一目了然,下一步學習一下異步加載元件的代碼執行邏輯,完整代碼在這裡 傳送門