当前位置: 首页 > news >正文

JavaScript之Webpack的模块加载机制

目录

目标

概述

IIFE语法分析

无参数的IIFE

有参数的IIFE

Webpack语法分析

基本结构

缓存加载过的模块

ES5的格式

ES6的格式


目标

        本文站在js逆向的角度总结知识,所以不讲解Webpack打包技术,只分析模块加载机制。


概述

Webpack

        Webpack是一个基于模块化的构建工具,它不仅支持JavaScript,还能将CSS、图片、字体等资源统一视作模块,通过Loader转换各种类型的文件,通过Plugin插件机制扩展构建过程,最终生成适合上线部署的静态资源文件。语法结构的特点是:通过自执行函数(IIFE)将所有模块封装起来。这样可以避免全局变量污染,并且确保模块化的封装和依赖的管理。

IIFE(Immediately Invoked Function Expression)

        翻译过来叫做立即执行函数表达式(正式名称),也常常叫它自执行函数。意思是将函数变成表达式,从而达成立刻执行该函数的目的。


IIFE语法分析

无参数的IIFE

//形式一
(function () {console.log("hello world!");
})();
//形式二
!function () {console.log("hello python!");
}();
//形式三
(()=>{console.log("箭头函数!")}
)()

语法分析

        以形式一为案例讲解。它的结构是(function(){……})(),其中:

  • function(){……}是普通的js函数,只是声明并没有执行;
  • 该函数外层括号将其变成了函数表达式;
  • 最右边的括号表示执行垓表达式,同时也可以用它来传递参数。

有参数的IIFE

//形式一
(function (name,age,sex) {console.log(`name:${name};age:${age};sex:${sex}`);
})("张三",14,"男");
//形式二
!function (name,age,sex) {console.log(`name:${name};age:${age};sex:${sex}`);
}("张三",14,"男");
//形式三
((name,age,sex)=>{console.log(`name:${name};age:${age};sex:${sex}`);}
)("张三",14,"男")

Webpack语法分析

基本结构

数组传参

(function fun(e) {//加载器(调用模块的方法)function tx(t) {return e[t].call()}//执行tx方法,tx(1)}
)(//模块[function () {console.log("Java")},function () {console.log("Python")},function () {console.log("Html")},]
)

对象传参

(function fun(e) {//加载器(调用模块的方法)function tx(t) {return e[t].call()}//执行tx方法,tx("py")}
)(//模块{java: function () {console.log("Java")},py: function () {console.log("Python")},html: function () {console.log("Html")},}
)

代码分析

        以数组形式为案例,结构是:(function fun(e){function tx(t){return e[t].call()}tx(1)})([fun1,fun2,fun3……]),其中:

  • 外层是一个自执行函数。结构是:(function(){……})()
  • 这个自执行函数的实际参数是数组或对象,我们叫它模块或者插件。比如:[fun1,fun2,fun3……]
  • 内层函数是加载器,用于执行模块。比如:function tx(t){……}
  • 执行模块的方式是传递数组下标或对象的属性名称。比如:tx(1)
  • 外层函数实际上就是一个闭包,目的就是为了保证各个模块之间互不干扰。想了解闭包的同学,可以进入我的主页查看关于js闭包的文章。

缓存加载过的模块

ES5的格式

(function (e) {var c = {}function fun(t) {//是否是第一次调用if (c[t]) {return c[t].exports}//如果是第一次调用,需要保存到缓存对象c中var o = c[t] = {i: t,l: !1,exports: {}};e[t].call(o.exports, o, o.exports, fun)return o.exports.exports}fun(0)}
)([function () {console.log(1)},function () {console.log(2)},function () {console.log(3)},]
)

ES6的格式

module1.mjs

export function run() {console.log(1);
}

module2.mjs

export function run() {console.log(2);
}

module3.mjs

export function run() {console.log(3);
}

调用文件

import { run as run1 } from './module1.mjs';
import { run as run2 } from './module2.mjs';
import { run as run3 } from './module3.mjs';// 模拟调用模块
const modules = [run1, run2, run3];// 调用第0个模块
modules[1]();

思考:为什么ES6模块不需要手动缓存?

:因为ES6模块天然自带缓存机制。也就是说同一个模块只会被加载一次,第二次import的时候直接复用已经加载的模块实例。

相关文章:

  • es数据导出
  • Unity Post Processing 小记 【使用泛光实现灯光亮度效果】
  • 第2讲、Tensor高级操作与自动求导详解
  • gradle eclipse [.project .classpath .settings]
  • 【有啥问啥】深入理解 Layer Normalization (LayerNorm):深度学习的稳定基石
  • 【物理学】电磁学——电动势
  • 说一下Drop与delete区别
  • Kafka批量消费部分处理成功时的手动提交方案
  • 页面需要重加载才能显示的问题修改
  • openstack热迁移、冷迁移、疏散
  • SQL注入原理及防护方案
  • 基于BenchmarkSQL的OceanBase数据库tpcc性能测试
  • Java异常处理全面指南:从基础到高级实践
  • [MCU]SRAM
  • 路由协议基础
  • 【JS-Leetcode】2621睡眠函数|2629复合函数|2665计数器||
  • 2025上海车展 | 移远通信重磅发布AR脚踢毫米波雷达,重新定义“无接触交互”尾门
  • C++之异常
  • (云计算HCIP)HCIP全笔记(九)本篇介绍操作系统基础,内容包含:操作系统组成、分类和定义,Linux的特性结构和Linux版本分类
  • 使用Three.js搭建自己的3Dweb模型(从0到1无废话版本)
  • 中国公民免签赴马来西亚的停留天数如何计算?使馆明确
  • 《黎明的一切》:与正常世界脱轨后,我选择不再回去
  • 一季度全国30强城市出炉:谁能更进一步?谁掉队了?
  • 五一假期上海境外来沪消费4.55亿元,同比增长211.6%
  • 繁荣活跃!“五一”假期全国重点零售和餐饮企业销售额同比增长6.3%
  • 晒被子最大的好处,其实不是杀螨虫,而是……