webpack4.x CommonJS模块化浅析(2)

➜  webpack-test webpack app/main.js --output public/bundle.js --mode development
Hash: a4e2f9ecc51b64891624
Version: webpack 4.25.1
Time: 90ms
Built at: 2018-11-08 17:11:01
    Asset      Size  Chunks             Chunk Names
bundle.js  5.16 KiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/bye.js] 165 bytes {main} [built]
[./app/hello.js] 173 bytes {main} [built]
[./app/main.js] 144 bytes {main} [built]
[./app/to.js] 30 bytes {main} [built]
➜  webpack-test

浏览器打开 index.html 文件,即可看到结果

Say Hello to 小明
Say Bye to 小明

但是 webpack 作为一个能简化我们开发难度和使用便捷的工具,显然像上面那样通过敲很多命令来打包,并不方便,所以下面采用配置文件的方式再来一次:

根目录创建 webpack.config.js 文件,并配置下打包入口和出口:

// webpack-test/webpack.config.js module.exports = { mode: "development",//webpack.0之后需要声明环境 entry: __dirname + "/app/main.js",//唯一入口文件 output: { path: __dirname + "/public",//打包后的文件存放目录 filename: "bundle.js"//打包后输出文件名 } }

再次打包的时候,只需要使用命令 webpack 就可以了,webpack 默认读取当前路径下的 webpack.config.js 文件。

最终打包好的 bundle.js 文件,去除了多余注释,调整了代码格式,内容如下:

// 自执行函数,参数为所有模块组成的,形势为key:value,key是模块名 (function(modules) { // webpackBootstrap // 已加载模块的缓存,记录模块的加载情况,也是为了避免重复打包,节省资源 var installedModules = {}; // webpack 使用 require 方式加载模块的方法(模拟ConmmonJS reqiure()),作用为根据传进来的模块id来处理对应的模块,加入已加载缓存,执行,标记,返回exports function __webpack_require__(moduleId) { // moduleId 为模块路径 // 检测模块是否已加载,已加载的话直接返回该模块 if(installedModules[moduleId]) { return installedModules[moduleId].exports; } // 当前模块未加载的话,新建,并存于缓存 var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} }; // 在当前模块的 exports 下,也就是模块的内部执行模块代码,突出作用域 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // 标记模块已经加载 module.l = true; // 返回模块的导出内容 return module.exports; } // 挂载属性,该模块 (__webpack_modules__) __webpack_require__.m = modules; // 挂载属性,模块加载缓存 __webpack_require__.c = installedModules; // 本代码中未执行,暂时不分析 // 在 exports 中定义 getter 方法 __webpack_require__.d = function(exports, name, getter) { // 当 name 属性不是定义在对象本身,而是继承自原型链,则在在 exports 中定义 getter 方法 if(!__webpack_require__.o(exports, name)) { Object.defineProperty(exports, name, { enumerable: true, get: getter }); } }; // 本代码中未执行,暂时不分析 // 在 exports 中定义 __esModule,定义key为Symbol的属性(在__webpack_require__.t中被调用) // define __esModule on exports __webpack_require__.r = function(exports) { if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); } Object.defineProperty(exports, '__esModule', { value: true }); }; // 本代码中未执行,暂时不分析 // 创建一个伪命名空间的对象 // create a fake namespace object // mode & 1: value is a module id, require it // mode & 2: merge all properties of value into the ns // mode & 4: return value when already ns object // mode & 8|1: behave like require __webpack_require__.t = function(value, mode) { if(mode & 1) value = __webpack_require__(value); if(mode & 8) return value; if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; var ns = Object.create(null); __webpack_require__.r(ns); Object.defineProperty(ns, 'default', { enumerable: true, value: value }); if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); return ns; }; // 本代码中未执行,暂时不分析 // getDefaultExport function for compatibility with non-harmony modules __webpack_require__.n = function(module) { var getter = module && module.__esModule ? function getDefault() { return module['default']; } : function getModuleExports() { return module; }; __webpack_require__.d(getter, 'a', getter); return getter; }; // Object.prototype.hasOwnProperty.call // 判断一个属性是定义在对象本身而不是继承自原型链 __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; // __webpack_public_path__ __webpack_require__.p = ""; // 加载入口模块 main.js ,返回 exports,从而从入口文件开始执行,以递归的方式,将所有依赖执行并返回 return __webpack_require__(__webpack_require__.s = "./app/main.js"); })({ "./app/bye.js": (function(module, exports, __webpack_require__) { eval("const to = __webpack_require__(/*! ./to.js */ \"./app/to.js\");\nmodule.exports = function() {\n var bye = document.createElement('div');\n bye.textContent = \"Say Bye to \" + to.name;\n return bye;\n};\n\n//# sourceURL=webpack:///./app/bye.js?"); }), "./app/hello.js": (function(module, exports) { eval("module.exports = function() {\n var hello = document.createElement('div');\n hello.textContent = \"Say Hello!\";\n return hello;\n};\n\n//# sourceURL=webpack:///./app/hello.js?"); }), "./app/main.js": (function(module, exports, __webpack_require__) { eval("const hello = __webpack_require__(/*! ./hello.js */ \"./app/hello.js\");\nconst bye = __webpack_require__(/*! ./bye.js */ \"./app/bye.js\");\n\ndocument.querySelector(\"#root\").appendChild(hello()).appendChild(bye());;\n\n//# sourceURL=webpack:///./app/main.js?"); }), "./app/to.js": (function(module, exports) { eval("module.exports = {name: \"小明\"};\n\n//# sourceURL=webpack:///./app/to.js?"); }) });

分析

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ebeaf56fe5732d92f07706298b252ecc.html