webpack cjs运行时分析示例详解
作者:豆芽不吃豆 发布时间:2024-04-19 09:51:56
准备工作(接上篇文章的示例也可以):
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赋值,可以应对任何情况;
参考文献
详细的可移步大佬的文章
来源:https://blog.csdn.net/lucky569/article/details/128444422


猜你喜欢
- 修改文件的名字 使用“FileSystemObject(文件系统对象)”的GetFile函数得到一个“文件对象”,然后修改这个“文件对象”的
- 一、 模块1、模块的概念模块是 Python 程序架构的一个核心概念每一个以扩展名 py 结尾的 Python 源代码文件都是一个 模块模块
- 在印刷排版中“point”是一个绝对的单位,它等于 1/72 英寸。可以用尺子丈量的,物理的英寸。但在CSS中pt的含义
- 爬取网址:http://www.ultramanclub.com/allultraman/使用工具:pycharm,requests进入网页
- 今天我们来学习,如何使用有趣的自定义标记来布局页面。有的朋友可能有这样的疑问,自己随便定义的标记浏览器怎么能正确的认识呢?这里我们就要用到文
- Git简单介绍Git是一个分布式版本控制软件,最初由Linus Torvalds创作,于2005年以GPL发布。最初目的是为更好地管理Lin
- 如题:我写入关键字到数据库,多的时候用|隔开了,我提取再做相关文章搜索的时候,我怎么提取用|隔开的文字啊,这样我就好用关键字做搜索啊 回复:
- PyTorch: https://github.com/shanglianlm0525/PyTorch-Networksimport tor
- 前言这是一个使用HttpRunner开发接口平台的简单Demo。新建Django项目安装依赖包pip install httprunner=
- 复合主键:create table index_test( a int not null, &nbs
- 目录连接池是什么?为什么需要连接池?连接池的原理是什么?使用python语言自制简易mysql连接池开始使用自定义配置文件名 & 配
- PyQt5图片显示控件QPixmap介绍QPixmap类用于绘图设备的图像显示,它可以作为一个QPainterDevice对象,也可以加载到
- 1. 概念1.1 基本概念时间,对于我们来说很重要,什么时候做什么?什么时候发生什么?没有时间的概念,生活就乱了。在日常的运维当中,我们更关
- 如下所示:#coding:utf-8 ''''' Created on 2014-7-24 @aut
- 随着网站访问量的加大,每次从数据库读取都是以效率作为代价的,很多用ACCESS作数据库的更会深有体会,静态页加在搜索时,也会被优先考虑。互联
- 压缩数据库文件可以提高数据库的性能,但是有些时候在压缩数据库时,系统会提醒用户该数据库不能压缩。如果在Access数据库中删除数据库对象,或
- python是支持多线程的, 主要是通过thread和threading这两个模块来实现的,本文主要给大家分享python实现多线程网页爬虫
- 1.安装pyenv https://github.com/pyenv/pyenv-instal
- 先来描述一下我遇到的问题,在进行matplotlib学习时, plot.show() 总是无法成功运行,总是会报一个错:RuntimeErr
- 提示:本文多图,请手机端注意流量。前言利用python做图片识别,识别提取图片中的文字会有很多方法,但是想要简单一点怎么办,那就可以使用te