在本文中,我们分析了 React 源代码如何绕过捆绑器对 require 语句的检测。
通过将字符串“require”与随机数(Math.random())连接起来,代码会生成一个看起来像“require”的字符串,但在静态分析期间捆绑器无法直接识别。然后对字符串进行切片以获取前 7 个字符,确保结果始终为“require”(因为“require”Math.random() 将生成类似“require0.123456”的结果,该结果被切片为“require”) .
所有这些麻烦都是为了调用 Node 环境中可用的名为 setImmediate 的 MacroTask。
当你想异步执行某段代码时,
但尽快,一种选择是使用 Node.js 提供的 setImmediate() 函数:
setImmediate(() => { // run something });
作为 setImmediate() 参数传递的任何函数都是在事件循环的下一次迭代中执行的回调。
在 Nodejs 文档中了解有关 setImmediate 的更多信息。
React 需要区分 Node.js 环境(使用 setImmediate)和浏览器环境(使用 MessageChannel)。如果捆绑器检测到 require,它可能会自动在浏览器捆绑包中包含 Node.js polyfill,这是不必要的,并且会使代码变得臃肿。
Bundlers,如 Webpack,通常在检测到需要时包含 Node.js API 的 polyfill。这对于像 React 这样的轻量级库来说是有问题的,因为这样的 polyfill 是不必要的,并且可能会干扰 React 自己处理环境的逻辑(浏览器与 Node.js)。
这个 enqueueTask 是 ReactAct.js 中使用的后备方法
// $FlowFixMe[invalid-computed-prop] const nodeRequire = module && module[requireString]; // assuming we're in node, let's try to get node's // version of setImmediate, bypassing fake timers if any. enqueueTaskImpl = nodeRequire.call(module, 'timers').setImmediate;
timers 是 Node.js 中的核心模块。它提供了一组计时器函数,可用于安排代码在特定时间间隔或延迟后执行。这些函数与
中的全局定时器函数类似
JavaScript(如 setTimeout 和 setInterval),但它们作为计时器模块的一部分提供,以实现额外的控制和精度。
<p>nodeRequire.call(module, 'timers')</p>
在 Think Throo,我们的使命是教授开源项目中使用的高级代码库架构概念。
通过在 Next.js/React 中练习高级架构概念,将您的编码技能提高 10 倍,学习最佳实践并构建生产级项目。
我们是开源的 — https://github.com/thinkthroo/thinkthroo (请给我们一颗星!)
通过我们基于代码库架构的高级课程来提高您的团队的技能。请通过 hello@thinkthroo.com 联系我们以了解更多信息!
https://github.com/facebook/react/blob/5d19e1c8d1a6c0b5cd7532d43b707191eaf105b7/packages/shared/enqueueTask.js#L23
https://nodejs.org/en/learn/asynchronous-work/understanding-setimmediate
https://nodejs.org/api/timers.html#setimmediatecallback-args
以上是绕过捆绑程序对 require 语句的检测的详细内容。更多信息请关注PHP中文网其他相关文章!