本文主要说明Webpack模块构建和加载的原理,对构建后的源码进行分析。
一 说明
本文以一个简单的示例,通过对构建好的bundle.js源码进行分析,说明Webpack的基础构建原理。
本文使用的Webpack版本是4.32.2版本。
注意:之前也分析过Webpack3.10.0版本构建出来的bundle.js,通过和这次的Webpack 4.32.2版本对比,核心的构建原理基本一致,只是将模块索引id改为文件路径和名字、模块代码改为了eva l(moduleString)执行的方式等一些优化改造。
二 示例
1)Webpack.config.js文件内容:
1 const path = require('path'); 2 3 module.exports = { 4 entry: './src/index.js', 5 output: { 6 filename: 'bundle.js', 7 path: path.resolve(__dirname, 'dist') 8 }, 9 mode: 'development' // 'production' 用于配置开发还是发布模式 10 };
2)创建src文件夹,添加入口文件index.js:
1 import moduleLog from './module.js'; 2 3 document.write('index.js loaded.'); 4 5 moduleLog();
3)在src目录下创建module.js文件:
1 export default function () { 2 document.write('module.js loaded.'); 3 }
4)package.json文件内容:
1 { 2 "name": "webpack-demo", 3 "version": "1.0.0", 4 "description": "", 5 "main": "index.js", 6 "scripts": { 7 "test": "echo \"Error: no test specified\" && exit 1", 8 "webpack": "webpack" 9 }, 10 "keywords": [], 11 "author": "", 12 "license": "ISC", 13 "devDependencies": { 14 "webpack": "^4.32.2", 15 "webpack-cli": "^3.3.2" 16 }, 17 "dependencies": { 18 "lodash": "^4.17.4" 19 } 20 }
三 执行构建
执行构建命令:npm run webpack
在dist目录下生成的bundle.js源码如下(下边代码是将注释去掉、压缩的代码还原后的代码):
1 (function (modules) { 2 // The module cache 3 var installedModules = {}; 4 // The require function 5 function __webpack_require__(moduleId) { 6 // Check if module is in cache 7 if (installedModules[moduleId]) { 8 return installedModules[moduleId].exports; 9 } 10 // Create a new module (and put it into the cache) 11 var module = installedModules[moduleId] = { 12 i: moduleId, 13 l: false, 14 exports: {} 15 }; 16 17 // Execute the module function 18 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 19 20 // Flag the module as loaded 21 module.l = true; 22 23 // Return the exports of the module 24 return module.exports; 25 } 26 27 28 // expose the modules object (__webpack_modules__) 29 __webpack_require__.m = modules; 30 31 // expose the module cache 32 __webpack_require__.c = installedModules; 33 34 // define getter function for harmony exports 35 __webpack_require__.d = function (exports, name, getter) { 36 if (!__webpack_require__.o(exports, name)) { 37 Object.defineProperty(exports, name, {enumerable: true, get: getter}); 38 } 39 }; 40 41 // define __esModule on exports 42 __webpack_require__.r = function (exports) { 43 if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { 44 Object.defineProperty(exports, Symbol.toStringTag, {value: 'Module'}); 45 } 46 Object.defineProperty(exports, '__esModule', {value: true}); 47 }; 48 49 // create a fake namespace object 50 // mode & 1: value is a module id, require it 51 // mode & 2: merge all properties of value into the ns 52 // mode & 4: return value when already ns object 53 // mode & 8|1: behave like require 54 __webpack_require__.t = function (value, mode) {