news 2026/10/15 17:50:31

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 等),可以告诉我,我可以继续展开说明。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 2:31:55

基于MATLAB的单相接地故障自动重合闸仿真系统设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

基于MATLAB的单相接地故障自动重合闸仿真系统设计(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码 本设计包括设计报告&#xff0c;仿真工程。 目前我国的远距离输配电系统&#xff08;220~1000kv&#xff09;架空线路上&#…

作者头像 李华
网站建设 2026/10/11 1:22:43

数据库存储引擎与索引技术深度解析

数据库存储引擎概述 数据库存储引擎&#xff08;Storage Engine&#xff09;是数据库管理系统&#xff08;DBMS&#xff09;中负责数据存储、检索和管理的核心组件。它决定了数据如何在磁盘或内存中组织、如何处理读写操作&#xff0c;以及如何支持事务、并发控制等特性。不同…

作者头像 李华
网站建设 2026/10/11 0:27:12

C#字典(Dictionary)全面解析:从基础用法到实战优化

C# Dictionary<TKey, TValue> 全面解析 从基础用法 → 内部原理 → 常见陷阱 → 性能优化 → 实战场景选择 1. Dictionary 基础用法速览&#xff08;最常用写法&#xff09; // 声明与初始化&#xff08;最推荐的几种写法&#xff09; var dict1 new Dictionary<st…

作者头像 李华
网站建设 2026/10/12 3:58:28

2026国产运维监控系统新格局--深度解析与选型指南

在信创产业全面替代与数字化转型深度耦合的2026年&#xff0c;中国企业运维监控系统的战略价值已从“技术支撑工具”跃升为“业务连续性保障中枢”。随着国产化生态从“可用”向“好用”进化&#xff0c;企业选型逻辑正经历根本性转变&#xff1a;既要满足信创合规的硬性门槛&a…

作者头像 李华