webpack export 函数-webpack打包后的bundle文件分析

2023-08-30 0 4,011 百度已收录

### 1.一个入口,一个档案

webpack.config.js

````

模块. 导出 = {

Entry: './main.js', // 一个条目

输出: {

文件名:'bundle.js'

};

````

main.js

````

document.write('你好世界'); // 一份文件

````

捆绑包.js

````

/*****/ (函数(模块) { // webpackBootstrap

/*****/ // 模块缓存对象

/ ***** / var installModules = {};

/*****/

/*****/ // 需要函数

/*****/ 函数 __webpack_require__(moduleId) {

/*****/

/*****/ // 检查模块是否在缓存中,如果在,则返回exports对象

/*****/ if(installedModules[moduleId]) {

/ ***** /返回installedModules [moduleId] .exports;

/*****/ }

/*****/ // 如果不存在,则创建一个以 moduleId 为键的模块webpack export 函数,并将其加载到缓存中。

/*****/ var module =installedModules[moduleId] = {

/*****/ i: 模块Id,

/ ***** / l:假,

/*****/ 导出:{}

/*****/ };

/*****/

/*****/ //执行模块函数

/*****/ 模块[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/*****/

/*****/ // 标志模块已加载

/******/ module.l = true;

/*****/

/*****/ // 返回 module 导入的模块

webpack export 函数-webpack打包后的bundle文件分析

/*****/ 返回模块.exports;

/*****/ }

/*****/

/*****/

/*****/ // 公开模块对象 (__webpack_modules__)

/*****/ __webpack_require__.m = 模块;

/*****/

/*****/ // 暴露模块缓存

/*****/ __webpack_require__.c =InstalledModules;

/*****/

/*****/ // 验证 Harmony 导出模块是否具有正确上下文的函数

/*****/ __webpack_require__.i = 函数(值) { 返回值; };

/*****/

/*****/ // 为 Harmony 导出模块定义 getter 函数

/*****/ __webpack_require__.d = 函数(导出、名称、getter){

/*****/ if(!__webpack_require__.o(exports, name)) {

/ ***** / Object.defineProperty(导出,名称,{

/ ***** /可配置:假,

/ ***** /可枚举:true,

/*****/ 获取:吸气剂

/*****/ });

/*****/ }

/*****/ };

/*****/

/*****/ // 兼容非和谐模块的getDefaultExport函数

/*****/ __webpack_require__.n = 函数(模块){

/*****/ var getter = module && module.__esModule ?

/*****/ function getDefault() { return module['default']; } } :

/******/ 函数 getModuleExports() { 返回模块; };

/*****/ __webpack_require__.d(getter, 'a', getter);

/*****/ 返回吸气剂;

/*****/ };

/*****/

/*****/ // Object.prototype.hasOwnProperty.call

/*****/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); } };

/*****/

/*****/ // 设置webpack公共路径 __webpack_public_path__

/*****/ __webpack_require__.p = "";

/*****/

/*****/ // 读取入口模块并返回exports import

/*****/ 返回 __webpack_require__(__webpack_require__.s = 0);

/*****/ })

/******************************************************** ***** *************************/

/*****/([

/* 0 */

/***/ (function(module,exports) { // 模块 ID 为 0

document.write('你好世界');

/***/ })

/*****/]);

````

整体分析

整个bundle.js是一个立即执行的函数表达式(IIFE),传入的参数modules是一个字段,数组中的每一项都是一个匿名函数,代表一个模块。 这里,数组的第一个参数是一个函数,里面的内容是main.js中的原始内容。

IIFE 已关闭。 _webpack_require__ 是模块加载函数。 它的作用是声明对其他模块的依赖并返回导出。 参数为模块的Id(每个模块都有唯一的id),不需要提供模块的相对路径,可以省去模块标识符的解析过程(准确的说,webpack提前了解析将需求模块的流程转移到构建期),从而获得更好的运行性能。

执行模块功能:

````

模块[moduleId].call(module.exports, module, module.exports, __webpack_require__);

````

通过借用调用,函数的 this 始终是模块本身。 参数__webpack_require__是让模块有能力加载其他模块。

程序流程图

该包通过 __webpack_require__(__webpack_require__.s = 0) 启动整个程序。 首先检查缓存中是否存在ID为0的模块。 如果存在,则返回缓存中exports暴露的对象; 如果不存在,则创建一个新的模块对象并将其加载到缓存中。 此时模块对象和模块的缓存对象installedModules[moduleId]还没有数据,所以需要执行该模块来返回具体需要的其他模块的数据。 传入的上下文是 module.exports (等于installedModules[moduleId].exports)。

### 2. 一个条目,多个文件

webpack.config.js

````

模块. 导出 = {

条目:'./main1.js',

输出: {

文件名:'bundle.js'

````

main1.js

````

var main = require('./main2.js')

document.write('你好世界');

main.webpack();

````

main2.js

````

导出.webpack = 函数() {

document.write('Hello Webpack');

````

捆绑包.js

````

/*****/ (函数(模块) { // webpackBootstrap

/*****/ 这部分与上部分相同

/*****/ // 加载入口模块并返回导出

/*****/ 返回 __webpack_require__(__webpack_require__.s = 1);

/*****/ })

/******************************************************** ***** *************************/

/*****/([

/* 0 */

/***/(函数(模块webpack export 函数,导出){

导出.webpack = 函数() {

document.write('Hello Webpack');

/***/ }),

/* 1 */

/***/ (函数(模块, 导出, __webpack_require__) {

var main = __webpack_require__(0)

document.write('你好世界');

主要的。 网页包();

/***/ })

/*****/]);

````

![]()

**整体分析**

webpack打包时,会分析模块之间的依赖关系,并对导出和导入模块相关的内容进行替换。 例如,在main1.js文件中,如果遇到var main = require('./main2.js'),则会转化为var __WEBPACK_IMPORTED_MODULE_0__main__ = __webpack_require__(0)。

由于有两个文件,所以IIFE的参数是一个宽度为2的链表,按照require的顺序排列。

**程序流程**

该包通过 __webpack_require__(__webpack_require__.s = 1) 启动整个程序。 与第一种情况不同的是,这里首先检查缓存中是否有ID为1的模块,因为main1.js依赖于main2.js,所以在main.js中调用了模块加载函数。 执行 var main = __webpack_require__(0) 时,会执行 module[0].call (这里的调用是为了保证每个模块中的 this 指向模块本身),然后执行 document.write('Hello World' ); ,最后执行 document.write('Hello Webpack'); 。 至此,__webpack_require__(1)已经执行完毕,这是一个递归的过程。

### 3.两个入口和两个导出文件

main1 包含inner1; main2 包含inner1 和inner2。

webpack.config.js

````

模块. 导出 = {

入口: {

Bundle1: './main1.js',

Bundle2: './main2.js'

},

输出: {

文件名:'[名称].js'

};

````

webpack export 函数-webpack打包后的bundle文件分析

main1.js

````

var inner1 = require('./inner1.js');

内部1。 内部1();

document.write("我是main1")

````

main2.js

````

var inner1 = require('./inner1.js');

var inner2 = require('./inner2.js');

内部1。 内部1();

内部2。 内部2();

document.write("我是main2");

````

捆绑包1.js

````

/*****/ (函数(模块) { // webpackBootstrap

/*****/ 这部分与上部分相同

/*****/ // 加载入口模块并返回导出

/*****/ 返回 __webpack_require__(__webpack_require__.s = 2);

/*****/ })

/******************************************************** *** **************************/

/*****/([

/* 0 */

/***/(函数(模块,导出){

导出.inner1 = 函数() {

document.write('我是inner1');

/***/ }),

/* 1 */,

/* 2 */

/***/ (函数(模块, 导出, __webpack_require__) {

var inner1 = __webpack_require__(0);

内部1.内部1();

document.write("我是main1")

/***/ })

/*****/]);

````

Bundle2.js

````

/*****/ (函数(模块) { // webpackBootstrap

webpack export 函数-webpack打包后的bundle文件分析

/*****/ 这部分与上部分相同

/*****/ // 加载入口模块并返回导出

/*****/ 返回 __webpack_require__(__webpack_require__.s = 3);

/*****/ })

/******************************************************** *** **************************/

/*****/([

/* 0 */

/***/(函数(模块,导出){

导出.inner1 = 函数() {

document.write('我是inner1');

/***/ }),

/* 1 */

/***/(函数(模块,导出){

导出.inner2 = 函数() {

document.write('我是inner2');

/***/ }),

/* 2 */,

/* 3 */

/***/ (函数(模块, 导出, __webpack_require__) {

var inner1 = __webpack_require__(0);

var inner2 = __webpack_require__(1);

内部1.内部1();

内部2.内部2();

document.write("我是main2");

/***/ })

/*****/]);

````

![]()

整体分析

对于多个条目文件的情况,如果单个条目独立执行,则各个条目文件不会互相干扰。

从里面可以看到,main1.js和main2.js这两个入口文件的module id都是0,所以可以知道每个入口文件对应的模块id都是0。而且由于每个模块id都是全局的唯一,main1中没有1; main2中没有2。

静态分析打包预先生成chunk,重复包含inner1.js文件。 如果需要消除模块冗余,可以通过CommonsChunkPlugin插件提取公共依赖模块。

![]()

四。 概括

-bundle.js文件是一个立即执行的函数表达式,传入的参数是一个模块的链表。 真正执行module的是modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);。

- Modules链表用于保存模块初始化函数,里面存储了实际使用的模块内容和一些ID信息。

-installedModules对象用于保存模块缓存对象,方便其他模块使用。

- __webpack_require__ 模块加载函数,require时获取的对象,参数为模块id。

-InstalledModules[moduleId].exports === module.exports === __webpack_exports__

- 一般情况下,webpack会解析获取所有必需的模块并合并它们; 为这些模块有序执行提供一个环境。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 webpack webpack export 函数-webpack打包后的bundle文件分析 https://www.wkzy.net/game/184915.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务