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

Webpack 在异步请求 JS 文件时获取 JS Bundle 的机制

Webpack 在异步请求 JS 文件时获取 JS Bundle 的机制

Webpack 在处理代码分割(Code Splitting)后产生的异步 chunk(通常是import()动态导入)时,浏览器最终是怎么知道要去请求哪个 .js 文件,以及**请求回来后怎么正确执行**,这个过程主要依赖以下几个核心机制:

核心机制概览(2024~2025 主流方式)

机制主要文件作用谁负责生成当前主流方式
manifestruntime chunkchunkId → 文件名映射表webpack(内置)绝大多数项目都有
publicPathruntime 或配置决定请求的 URL 前缀用户配置 + runtime 推断非常重要
webpack_require.pruntime就是 publicPath 的运行时变量runtime 注入核心变量
webpack_require.uruntimechunkId → chunk 文件名 的函数webpack(新版本更智能)现代主流
webpack_require.eruntime真正发起 chunk 加载的函数webpack异步加载入口
JSONP / script tag浏览器实际发起 .js 请求的方式浏览器仍然是默认(2025年)

详细流程(以最常见的 JSONP + webpackChunkName 方式为例)

1. 代码里写: import(/* webpackChunkName: "user-detail" */ './user-detail.js') 2. 打包后生成的文件大致如下: - main.js ← 入口文件 + runtime - 123.user-detail.js ← 异步 chunk(chunkId=123) - 456.other-page.js ← 另一个异步 chunk 3. webpack 在 main.js(或单独的 runtime chunk)中注入了一段类似这样的代码: // 简化的伪代码 var installedChunks = { 0: 0 }; // 已加载的 chunk 标记 __webpack_require__.e = function requireEnsure(chunkId) { var promises = []; // 检查是否已经加载过 if (!installedChunks[chunkId]) { var promise = new Promise(function(resolve, reject) { // 记录 promise,后面 onload 会 resolve var callbacks = installedChunks[chunkId] = [resolve, reject]; // 重要!决定文件名的地方 ↓↓↓ var filename = __webpack_require__.u(chunkId); // ← 得到 "123.user-detail.js" var fullUrl = __webpack_require__.p + filename; // ← publicPath + 文件名 // 创建 script 标签 var script = document.createElement('script'); script.charset = 'utf-8'; script.timeout = 120; script.src = fullUrl; // 错误处理 script.onerror = script.onload = function(event) { // ... 处理成功/失败,把 promise resolve/reject }; document.head.appendChild(script); }); promises.push(promise); } return Promise.all(promises); } 4. 当代码执行到 import() 时,实际上调用的是: __webpack_require__.e("123").then(function() { // chunk 已经加载完成,可以使用模块了 var module = __webpack_require__("./src/user-detail.js"); // ... })

几个关键问题解答

问题答案来源说明
文件名是怎么知道的?__webpack_require__.u(chunkId)webpack 打包时把 chunkId → 文件名映射写死或生成函数
请求路径前缀从哪来?__webpack_require__.p(publicPath)通常来自 output.publicPath 配置
publicPath 是相对路径怎么办?runtime 会尝试推断(script.src 位置)现代 webpack 5 有比较智能的推断逻辑
CDN + 版本号怎么办?output.publicPath = ‘https://cdn.com/v1.2.3/’直接写死或通过环境变量注入
如何知道 chunk 加载成功了?script.onload + JSONP 回调chunk 内部会调用 webpackJsonp.push
多个 chunk 同时加载会不会冲突?webpackJsonp 是全局数组,push 的时候带 chunkId基本不会冲突
开发环境和生产环境的区别?开发环境通常用 webpack-dev-server 的内存文件系统 + sockjs生产环境才是真正的 .js 文件请求

2024-2025 年现代趋势对比表

方式chunk 名控制方式publicPath 处理推荐场景备注
JSONP(默认)webpackChunkName / id自动推断 + 配置绝大多数项目兼容性最好
importScripts基本不用Service Worker特殊场景
SystemJS/Federation远程模块名由 host 决定Module Federation微前端
ESM + import()浏览器原生type=“module”实验性、全 ESM 项目未来方向,但目前还需 polyfill

总结一句话

Webpack 异步 chunk 的加载机制本质上是:
通过运行时注入的__webpack_require__.e函数 + chunkId → 文件名映射 + publicPath 前缀,动态创建<script>标签去请求对应的 js 文件,文件执行后通过全局 webpackJsonp 回调通知 webpack 该 chunk 已就绪。

如果你想深入了解某个特殊场景(CDN 部署、Module Federation、publicPath 动态计算、chunk loading 错误重试、预加载 prefetch/preload 等),可以告诉我,我可以继续展开说明。

http://www.jsqmd.com/news/254708/

相关文章:

  • OLAP在大数据营销分析中的关键作用
  • 常量
  • 2026年口碑好的市政路灯,新农村路灯,锂电太阳能路灯厂家实力品牌推荐榜 - 品牌鉴赏师
  • ArkTS问题:怎么提升代码的优先级呢?
  • 2026年有实力的草坪灯,景观灯,景观灯厂家口碑品牌推荐榜 - 品牌鉴赏师
  • LeeCode_476 数字的补数
  • 51单片机_SPI
  • 2026国内最新爆款裤料品牌top10推荐!广东广州等地优质裤料供应商权威榜单发布,创新工艺与品质保障助力服饰产业升级 - 品牌推荐2026
  • 零成本搭建全球加速后端!Cloudflare Workers + 国内优化,小白也能30分钟搞定
  • 轮廓系数(Silhouette Score)量化K-Means聚类效果的核心指标
  • BeautifulSoup-cnblog
  • 方框标定代码
  • 揭秘TCP/IP协议栈:网络通信的核心架构
  • 揭秘TCP/IP协议栈:网络通信的核心架构
  • 捕捉瞬息万变的电信号世界:Waverunner力科610Zi示波器深度解读
  • vscode的几个版本说明
  • 存储技术全景:从基础原理到未来趋势
  • 存储技术全景:从基础原理到未来趋势
  • C++跨平台开发:挑战与解决方案
  • C++跨平台开发:挑战与解决方案
  • Java性能优化实战:从原理到技巧
  • Photoshop 图形与图像处理技术——第9章:实践训练3——图像修饰和色彩色调的调整
  • 闲置京东e卡回收新选择,让沉睡的购物卡焕发新生机 - 京顺回收
  • 5G、雷达、航天研发的“心脏”利器:是德N5182B 信号发生器全面解析
  • 不同版本的 chrome 开发者工具 CSS 属性变为斜体无法修改,如何解决?
  • Photoshop 图形与图像处理技术——第9章:实践训练4——图层和蒙版
  • 提示系统没人用?架构师教你3步打造爆款互动体验
  • Nvidia H100 算力服务器 Cuda、FabricManager、Container 安装和升级 - 教程
  • 2026年1月档案机构公司权威推荐:档案储存机构公司、档案整理机构公司、档案数字化机构公司、电子档案机构公司、整理卷宗档案机构公司、销毁档案机构公司等选择指南,智慧管理解决方案 - 海棠依旧大
  • Java基础补缺5:异常处理、常用工具类