webpack联邦模块之consumes方法

对于使用联邦模块的项目会有两个依赖,一个是远程模块,一个是共享模块。上一篇文章解释了远程模块的加载和安装并初始化共享作用域。consumes则是共享模块的解决方案,用于在运行时加载并安装依赖的共享模块。

为什么叫consumes?我理解是因为共享模块的获取是在__webpack_require__.I中完成的,而consumes只是使用__webpack_require__.S中的数据来安装对应模块。所以consumes是在消费__webpack_require__.S中的数据。

__webpack_require__S.default = {react: {version: {get() {}, ...}}}

以上信息并没有在__webpack_require__.m上,所以当前环境并不能使用共享作用域中的内容

var versionLt = (a, b) => {// see webpack/lib/util/semver.js for original codea=parseVersion(a),b=parseVersion(b);for(var r=0;;){if(r>=a.length)return r<b.length&&"u"!=(typeof b[r])[0];var e=a[r],n=(typeof e)[0];if(r>=b.length)return"u"==n;var t=b[r],f=(typeof t)[0];if(n!=f)return"o"==n&&"n"==f||("s"==f||"u"==n);if("o"!=n&&"u"!=n&&e!=t)return e<t;r++}
}var findSingletonVersionKey = (scope, key) => {var versions = scope[key];return Object.keys(versions).reduce((a, b) => {return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;}, 0);
};var satisfy = (range, version) => {// see webpack/lib/util/semver.js for original codeif(0 in range){version=parseVersion(version);var e=range[0],r=e<0;r&&(e=-e-1);for(var n=0,i=1,a=!0;;i++,n++){var f,s,g=i<range.length?(typeof range[i])[0]:"";if(n>=version.length||"o"==(s=(typeof(f=version[n]))[0]))return!a||("u"==g?i>e&&!r:""==g!=r);if("u"==s){if(!a||"u"!=g)return!1}else if(a)if(g==s)if(i<=e){if(f!=range[i])return!1}else{if(r?f>range[i]:f<range[i])return!1;f!=range[i]&&(a=!1)}else if("s"!=g&&"n"!=g){if(r||i<=e)return!1;a=!1,i--}else{if(i<=e||s<g!=r)return!1;a=!1}else"s"!=g&&"n"!=g&&(a=!1,i--)}}var t=[],o=t.pop.bind(t);for(n=1;n<range.length;n++){var u=range[n];t.push(1==u?o()|o():2==u?o()&o():u?satisfy(u,version):!o())}return!!o();
}var getSingletonVersion = (scope, scopeName, key, requiredVersion) => {var version = findSingletonVersionKey(scope, key);if (!satisfy(requiredVersion, version)) typeof console !== "undefined" && console.warn && console.warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));return get(scope[key][version]);
};var get = (entry) => {entry.loaded = 1;return entry.get()
};// 给入参函数注入依赖项共享作用域scope,封装的是scope的获取,
// 因为scope可能在初始化中,也可能初始化完成
var init = (fn) => (function(scopeName, a, b, c) {var promise = __webpack_require__.I(scopeName);// 等待共享作用域初始化完成if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], a, b, c));return fn(scopeName, __webpack_require__.S[scopeName], a, b, c);
});var loadSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => {if(!scope || !__webpack_require__.o(scope, key)) return fallback();return getSingletonVersion(scope, scopeName, key, version);
});var installedModules = {};
var moduleToHandlerMapping = {"webpack/sharing/consume/default/react/react?5e40": () => (loadSingletonVersionCheckFallback("default", "react", [1,17,0,2], () => (Promise.all([__webpack_require__.e("vendors-node_modules_react_index_js"), __webpack_require__.e("node_modules_object-assign_index_js")]).then(() => (() => (__webpack_require__(/*! react */ "../node_modules/react/index.js"))))))),"webpack/sharing/consume/default/react-dom/react-dom": () => (loadSingletonVersionCheckFallback("default", "react-dom", [1,17,0,2], () => (Promise.all([__webpack_require__.e("vendors-node_modules_react-dom_index_js"), __webpack_require__.e("webpack_sharing_consume_default_react_react")]).then(() => (() => (__webpack_require__(/*! react-dom */ "../node_modules/react-dom/index.js"))))))),"webpack/sharing/consume/default/react/react?7071": () => (loadSingletonVersionCheckFallback("default", "react", [4,17,0,2], () => (__webpack_require__.e("vendors-node_modules_react_index_js").then(() => (() => (__webpack_require__(/*! react */ "../node_modules/react/index.js")))))))
};
// no consumes in initial chunks
var chunkMapping = {"src_bootstrap_js": ["webpack/sharing/consume/default/react/react?5e40","webpack/sharing/consume/default/react-dom/react-dom"],"webpack_sharing_consume_default_react_react": ["webpack/sharing/consume/default/react/react?7071"]
};
__webpack_require__.f.consumes = (chunkId, promises) => {if(__webpack_require__.o(chunkMapping, chunkId)) {chunkMapping[chunkId].forEach((id) => {if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]);var onFactory = (factory) => {installedModules[id] = 0;__webpack_require__.m[id] = (module) => {delete __webpack_require__.c[id];module.exports = factory();}};var onError = (error) => {delete installedModules[id];__webpack_require__.m[id] = (module) => {delete __webpack_require__.c[id];throw error;}};try {var promise = moduleToHandlerMapping[id]();if(promise.then) {promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));} else onFactory(promise);} catch(e) { onError(e); }});}
}

chunkMapping中存着chunk对应共享模块的依赖,而moduleToHandlerMapping中存着共享模块的获取方式,通过方法__webpack_require__.f.consumes入参这两个数据就能解析chunk依赖的模块,并对模块进行安装。

(loadSingletonVersionCheckFallback("default", "react", [1,17,0,2], fallback))

这一行表达的是在共享作用域default上寻找版本为1.17.0.2的react,如果找不到使用自带的模块fallback。

var init = (fn) => (function(scopeName, a, b, c) {var promise = __webpack_require__.I(scopeName);// 等待共享作用域初始化完成if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], a, b, c));return fn(scopeName, __webpack_require__.S[scopeName], a, b, c);
});var loadSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => {if(!scope || !__webpack_require__.o(scope, key)) return fallback();return getSingletonVersion(scope, scopeName, key, version);
});

init方法用于初始化对应共享作用域,共享作用域加载完成后将相关作用域信息作为入参调用init的入参函数。

拿到作用域信息后调用方法getSingletonVersion(scope, scopeName, key, version)

getSingletonVersion

function getSingletonVersion(scope, scopeName, key, requiredVersion) {...return get(scope[key][version]);
}var get = (entry) => {entry.loaded = 1;return entry.get();
};

get方法的返回值会作为方法onFactory的入参

var onFactory = (factory) => {installedModules[id] = 0;__webpack_require__.m[id] = (module) => {delete __webpack_require__.c[id];module.exports = factory();}
};

onFactory执行完成后__webpack_require__.m上就会出现对应的模块信息。到这里共享模块也安装完成了。

等待chunk src_bootstrap_js文件加载完成,外部依赖准备完成,共享模块准备完成后chunk src_bootstrap_js 则表示加载完成可以开始执行业务代码了。

名字的翻译

在源码中使用的名字是 import React from ‘react’,而通过webpack编译后变成了”webpack/sharing/consume/default/react/react?5e40”,并且在__webpack_require__.S上的名字也是react,这些是怎么关联起来的呢?

该问题同样存在于远程模块加载场景中。

”webpack/sharing/consume/default/react/react?5e40”是怎么和共享作用域中的”react”关联起来的?

在上面源码中

var moduleToHandlerMapping = {"webpack/sharing/consume/default/react/react?5e40": () => (loadSingletonVersionCheckFallback("default", "react", [1,17,0,2], () => (Promise.all([__webpack_require__.e("vendors-node_modules_react_index_js"), __webpack_require__.e("node_modules_object-assign_index_js")]).then(() => (() => (__webpack_require__(/*! react */ "../node_modules/react/index.js"))))))),
}

表示模块"webpack/sharing/consume/default/react/react?5e40"需要在共享作用域default中的1.17.0.2版本的react,这里这两个名字就关联起来了。

源码中的 import React from ‘react’ 是怎么和 "webpack/sharing/consume/default/react/react?5e40" 关联起来的?

源码中的

import React from 'react'

经过编译变成

var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "webpack/sharing/consume/default/react/react?5e40");
var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);

这样源码中的名字 ”react”就和"webpack/sharing/consume/default/react/react?5e40"关联起来了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361914.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue-cli使用说明

一、安装npm install -g vue-cli 推荐使用国内镜像 先设置cnpm npm install -g cnpm --registryhttps://registry.npm.taobao.org 如果安装失败&#xff0c;可以使用 npm cache clean 清理缓存&#xff0c;然后再重新安装 然后使用 cnpm 安装 vue-cli 和 webpack cnpm inst…

OptaPlanner –具有真实道路距离的车辆路线

在现实世界中&#xff0c;车辆路径问题&#xff08;VRP&#xff09;中的车辆必须走这条路&#xff1a;它们不能在客户之间直线行驶。 大多数VRP研究论文和演示都乐于忽略此实现细节。 和我一样&#xff0c;过去。 尽管使用道路距离&#xff08;而不是空中距离&#xff09;不会对…

自旋锁

什么是自旋锁&#xff1f; 自旋锁&#xff08;spinlock&#xff09;&#xff1a;是指当一个线程在获取锁的时候&#xff0c;如果锁已经被其它线程获取&#xff0c;那么该线程将循环等待&#xff0c;然后不断的判断锁是否能够被成功获取&#xff0c;直到获取到锁才会退出循环。 …

关于如何在PSA众多请求号中查找数据是属于哪一条。

其中有两个TCODE: RSTSODS与RSTSODS&#xff0c;我们可以查找数据源的PSA表&#xff0c;然后在SE16中可以看到。 另外我们对PSA点击管理&#xff0c;一般会出现在窗口上面出现PSA的表名。 当然有些不在的话&#xff0c;那就去查找那两个TCODE。转载于:https://www.cnblogs.com/…

TCP握手为什么需要三次通信

TCP三步握手three way (or three message) handshake 是TCP核心知识点&#xff0c;很长一段时间内我无法理解为什么TCP建立连接需要三次通信&#xff0c;而不是两次或者四次或者更多次。我翻了很多问答和博客&#xff0c;他们说的都很有道理&#xff0c;但是借来的火&#xff0…

小程序用户拒绝授权解决方法

众所周知&#xff0c;小程序进入首先都要进行微信授权的&#xff0c;那万一用户不小心点了拒绝按钮怎么办呢&#xff1f;不要慌&#xff0c;官方早已预料到此情况&#xff0c;并提供了api供开发者使用&#xff0c;下面就一起来研究下api吧 一、API接口 wx.openSetting(OBJECT)…

揭示垃圾收集暂停的时间长度

有几种方法可以改善您的产品。 一种方法是仔细跟踪用户的体验并在此基础上进行改进。 我们确实自己应用了此技术&#xff0c;并再次花了一些时间查看不同的数据 除了我们追求的许多其他方面之外&#xff0c;我们还提出了一个问题“延迟GC触发应用程序的最坏情况是什么”。 为了…

异步导致UI句柄增加的解决办法

在很多操作中&#xff0c;都会使用到异步线程&#xff0c;具体怎样使用在这不说了&#xff0c;网上有很好的说明&#xff1b;本人通过Delegate.BeginInvoke实现异步调用&#xff0c;完成后对UI控件进行设值等&#xff0c;还有System.Timers.Timer都一样&#xff0c;使用的是线程…

[转]android ListView详解

本文转自&#xff1a;http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html 由于google doc 很多人都打不开&#xff0c;故更新了源码下载地址 【源码下载】----2011-01-18 在android开发中ListView是比较常用的组件&#xff0c;它以列表的形式展示具体内容&#xff…

JS对象操作

一、String常用操作 1.截取 substr(start,length) //返回从指定位置开始的指定长度的字符串。 substring(start,end) //返回两个指定的位置之间的字符串。 slice(start,end) //包括字符串 stringObject 从 start 开始&#xff08;包括 start&#xff09;到 end 结束&#xff0…

JBoss BPM Suite 6.0.3版本的5个实用技巧

上周&#xff0c;红帽发布了标记为6.0.3的JBoss BPM Suite的下一版本&#xff0c;已订阅的用户可以在其客户门户中使用。 如果您对该版本的新增功能感到好奇&#xff0c;请在客户门户网站上在线查看版本说明和其余文档 。 我们正在寻找一些简单的方法来开始使用此新版本&…

package-lock.json

package.json确定依赖的范围&#xff0c;package-lock.json将这个范围精确到具体版本。主要是为了解决在各个环境中得到确定的node_modules&#xff0c;如果只依赖package.json因为该文件声明的是直接依赖的范围&#xff0c;它无法将直接依赖固定在某个特定版本&#xff0c;也无…

Linux启动管理

启动管理系统运行级别 运行级别&#xff1a;含义0 &#xff1a;关机1 &#xff1a;但用户模式&#xff0c;可以想象为windows的安全模式&#xff0c;主要用于系统修复2 &#xff1a;不完全的命令行模式&#xff0c;不含NFS服务3 &#xff1a;完全的命令行模式&#xff0c;就是标…

VB网站收集

1.vb源码 http://hi.baidu.com/aboutvb/home转载于:https://www.cnblogs.com/sode/archive/2011/11/05/2236883.html

Django学习---原生ajax

Ajax 原生ajax Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作&#xff0c;该对象在主流浏览器中均存在(除早起的IE)&#xff0c;Ajax首次出现IE5.5中存在&#xff08;ActiveX控件&#xff09;。 XmlHttpRequest对象的主要方法&#xff1a; a. void open(String …

The Little Schemer-周而复始之Y组合子由来

什么是递归&#xff1f; (define length(lambda (l)(cond((null? l) 0)(else (add1 (length (cdr l)))))))以上是length函数的实现用递归的形式计算出数据集合l的长度。 如果没有define这种赋值操作我们怎么定义length函数&#xff1f;换句话说我们怎么使用匿名函数完成递归…

霸主–统治和管理API的地方

今天我们生活在一个越来越分散的世界中。 如今的计算机系统不再是在随机桌子下面的某些硬件上运行单个部门项目&#xff0c;而是大规模&#xff0c;集中甚至分散地运行。 监视和管理的需求从未改变&#xff0c;但是随着时间的推移变得越来越复杂。 如果将所有这些跨功能功能都放…

Django操作与内容

一、路由系统 1.如何实现伪静态 在cnblogs中&#xff1a;https://www.cnblogs.com/wangwei5979/p/11160708.html 而我们自己写的&#xff1a; http://127.0.0.1:8000/up_studnet/?id12同样是网页 为何cnblogs这样设计 原因&#xff1a; 1就是因为比较美观 2由于使用搜索引擎来…

监控 SQL Server 的运行状况

Microsoft SQL Server 2005 提供了一些工具来监控数据库。方法之一是动态管理视图。动态管理视图 (DMV) 和动态管理函数 (DMF) 返回的服务器状态信息可用于监控服务器实例的运行状况、诊断问题和优化性能。 常规服务器动态管理对象包括&#xff1a; dm_db_*&#xff1a;数据库和…

RFC2616-HTTP1.1-Header Field Definitions(头字段规定部分—单词注释版)

part of Hypertext Transfer Protocol -- HTTP/1.1RFC 2616 Fielding, et al. 14 Header Field Definitions(规定) This section(部分&#xff0c;章节) defines(规定定义) the syntax(语法) and semantics(语意) of all standard(标准) HTTP/1.1 header fields. For entity-…