webpack cjs运行时分析示例详解

 更新时间:2022年12月28日 16:19:53   作者:豆芽不吃豆  
这篇文章主要介绍了webpack cjs运行时分析,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

准备工作(接上篇文章的示例也可以):

1. 在index.js文件中引入任一js文件

import sum from './sum';

const result = sum(1,2);
console.log(result);

2. sum文件

const sum = (a, b) => {
  return a+b;
}

export default sum

3. build.js文件

const path = require('path');
const webpack = require('webpack');

function wrapBuild() {
  return webpack({
    entry: './index.js',
    mode: 'none',
    output: {
      path: path.resolve(__dirname, 'build'),
      filename: '[name].js'
    },
    infrastructureLogging: {
      debug: true,
      level: 'log',
    }
  })
}

wrapBuild().run((err, stat) => {
  const startTime = stat.startTime;
  const endTime = stat.endTime;
  console.log('构建时间: ', endTime - startTime);
})

4. 命令行执行node ./build.js 生成打包产物main.js。

(截图未完整, 共87行)

5. 什么是运行时代码?

通过webpack打包得到的文件(如/build/main.js的骨架代码), 其中包含了一些webpack如何将多个模块集合在一起的代码, 可粗暴理解为webpack runtime 打包过后的代码。可通过node build/main.js可直接调试。

6. 示例打包js资源后的运行时代码分析:(含注解)

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ([
/* 0 */,    // ---模块0, 入口模块 可以理解为index.js模块
/* 1 */    // ---模块1,打包过后的sum.js
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
const sum = (a, b) => {
  return a+b;
}

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (sum);

/***/ })
/******/ 	]);
/************************************************************************/
/******/ 	// 模块缓存
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// 模块加载器, 模拟实现common.js的require
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// 根据moduleId从缓存中读取module
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
            // 若缓存中存在该模块,则返回当前的module.exports
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// 缓存中不存在该模块,则去__webpack_modules__里取。
                // 创建一个新的模块,  写入cache对象, key为moduleId, value 为 exports对象
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// 调用包裹函数,计算模块信息,解析出相关模块内容(如:exports)
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// 返回当前解析过后的module.exports
/******/ 		return module.exports;
/******/ 	}

var __webpack_exports__ = {};
// 加载入口函数
(() => {
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _sum__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
const result = (0,_sum__WEBPACK_IMPORTED_MODULE_0__["default"])(1,2);
console.log(result);
})();

/******/ })()
;

该运行时代码一共做了三件事:

  • __webpack_modules__ : 维护一个所有模块的数组,通过深度优先遍历将其全部转换为AST,以供给后面的包裹函数解析
  • __webpack_require__: 手动实现一个模块加载器;优先从缓存列表__webpack_module_cache__中读取模块,并返回其exports内容。如果缓存中没有,则调用包裹函数解析出模块exports等重要内容,存入缓存列表中并返回exports。
  • 调用__webpack_require_(0): 运行入口模块.

7. 疑问?

  • 如果不对模块进行缓存,会有什么问题?
  • 模块内容重复计算,消耗性能。
  • 每个模块只在第一次引用的时候产生一个对象,后面都是引用该对象,减少代码复杂度。
  • module.exports和exports有什么区别?
  • 默认情况下,Node准备的exports变量和module.exports变量实际上是同一个变量,并且初始化为空对象,我们可以把要输出的东西直接加入在这个空对象里面;但是,如果我们要输出的是一个函数或数组,那么,只能给module.exports赋值,给exports赋值是无效的,因为赋值后,module.exports仍然是空对象。
  • 结论:
  • 如果要输出一个键值对象{},可以利用exports这个已存在的空对象{},并继续在上面添加新的键值;
  • 如果要输出一个函数或数组,必须直接对module.exports对象赋值。
  • 建议直接对module.exports赋值,可以应对任何情况;

参考文献

详细的可移步大佬的文章

到此这篇关于webpack cjs运行时分析的文章就介绍到这了,更多相关webpack cjs运行时内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 编写高性能的JavaScript 脚本的加载与执行

    编写高性能的JavaScript 脚本的加载与执行

    把脚本放在body中,当浏览器遇见<script>标签时, 浏览器不知道脚本会插入文本还是html标签,因此浏览器会停止分析html页面而去执行脚本。
    2010-04-04
  • GoJs中的动画使用示例详解

    GoJs中的动画使用示例详解

    这篇文章主要为大家介绍了GoJs中的动画使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • BootStrap selectpicker

    BootStrap selectpicker

    这篇文章主要介绍了BootStrap selectpicker 的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定

    KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定

    Knockout是一个以数据模型(data model)为基础的能够帮助你创建富文本,响应显示和编辑用户界面的JavaScript类库。这篇文章介绍了KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定的相关知识,感兴趣的朋友一起看看吧
    2016-10-10
  • JS实现访问DOM对象指定节点的方法示例

    JS实现访问DOM对象指定节点的方法示例

    这篇文章主要介绍了JS实现访问DOM对象指定节点的方法,结合实例形式分析了javascript针对DOM元素节点属性相关操作技巧,需要的朋友可以参考下
    2018-04-04
  • JS canvas实现画板和签字板功能

    JS canvas实现画板和签字板功能

    这篇文章主要为大家详细介绍了JS canvas实现画板和签字板功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • JavaScript实现按Ctrl键打开新页面

    JavaScript实现按Ctrl键打开新页面

    这篇文章主要介绍了JavaScript实现按Ctrl键打开新页面的例子,本文方法适用HTML5环境中,需要的朋友可以参考下
    2014-09-09
  • 微信小程序实现文本输入弹窗

    微信小程序实现文本输入弹窗

    这篇文章主要为大家详细介绍了微信小程序实现文本输入弹窗,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • JavaScript图像放大镜效果实现方法详解

    JavaScript图像放大镜效果实现方法详解

    这篇文章主要介绍了JavaScript图像放大镜效果实现方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • JavaScript实现信用卡校验方法

    JavaScript实现信用卡校验方法

    这篇文章主要介绍了JavaScript实现信用卡校验方法,涉及javascript使用Luhn算法进行校验的技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04

最新评论