React Native打包JS文件中_$$_REQUIRE函数工作机制问询
React Native打包后
__d与_$$_REQUIRE的工作原理解析 先看你提供的打包后模块代码:
__d(function (global, _$$_REQUIRE, _$$_IMPORT_DEFAULT, _$$_IMPORT_ALL, module, exports, _dependencyMap) { 'use strict'; _$$_REQUIRE(_dependencyMap[0], "whatwg-fetch"); module.exports = { fetch: fetch, Headers: Headers, Request: Request, Response: Response }; },115,[116],"node_modules/react-native/Libraries/Network/fetch.js");
1. _$$_REQUIRE如何加载符号到作用域?
这是React Native的Metro打包器的模块加载逻辑:
_$$_REQUIRE的第一个参数是_dependencyMap里的模块ID(示例中是116,对应whatwg-fetch模块),第二个参数是模块路径(仅用于调试)。- 调用
_$$_REQUIRE时,它会找到对应ID的模块,执行该模块的__d包裹函数完成初始化。 - 对于
whatwg-fetch这类本身会向全局挂载符号的库,Metro不会让它真的污染全局,而是会把这些挂载的符号(fetch、Headers等)捕获并注入到当前模块的局部作用域中,所以你能直接在当前模块里引用这些符号。 - 如果是普通ES模块,
_$$_REQUIRE会返回模块的exports对象,你可以通过解构或直接引用获取导出内容。
2. 符号挂载到全局还是局部作用域?
这些符号仅存在于当前模块的局部作用域。
Metro的模块系统会为每个__d包裹的函数创建独立的模块作用域,所有依赖加载的符号都被限制在这个局部作用域内,不会污染全局对象。示例里看起来直接用了全局符号,实际是Metro的运行时做了映射,把依赖模块的符号注入到了当前模块的局部作用域中。
3. _$$_REQUIRE的定义与运作逻辑
_$$_REQUIRE是Metro打包时自动注入的运行时核心函数,通常会放在整个bundle文件的最开头部分,你需要在bundle的起始位置查找它的定义。它的核心逻辑:
- 维护一个模块缓存表,记录已加载完成的模块,避免重复执行。
- 当传入模块ID时,先检查缓存:如果模块已加载,直接返回缓存的
exports;如果未加载,找到对应ID的__d模块定义,执行其包裹的函数完成初始化,然后将结果存入缓存。 - 对于非ES模块(比如CommonJS或全局挂载型的库),会做特殊处理:捕获模块运行时产生的全局符号,映射到当前模块的局部作用域,同时避免污染真正的全局对象。
内容的提问来源于stack exchange,提问作者Fee
相关产品推荐
相关产品推荐

