中国石家庄网站,百度指数移动版,丝足网站的建设,公司运营计划书怎么写腾讯开源的 hel#xff0c;提供了一种运行时引入远程模块的能力#xff0c;模块部署在 CDN#xff0c;远程模块发布后#xff0c;不需要重新构建发布#xff0c;就能生效。
个人觉得它的实现原理非常的不错#xff0c;因此分享给大家。
远程模块可以作为微模块#xf…腾讯开源的 hel提供了一种运行时引入远程模块的能力模块部署在 CDN远程模块发布后不需要重新构建发布就能生效。
个人觉得它的实现原理非常的不错因此分享给大家。
远程模块可以作为微模块模块级别的微前端是页面级别的微前端的一种补充因为页面级别的微前端如 qiankun、无界等它们的粒度太粗了有时候需要更细粒度的微前端例如组件、函数级别的。这种场景就可以使用远程模块来实现微模块的效果。
远程模块使用示例
import helMicro from hel-micro;export async function callRemoteMethod() {const lib await helMicro.preFetchLib(hel-tpl-remote-lib);return lib.num.random(22);
} 1.引入 hel-micro 模块 2.通过 helMicro.preFetchLib 拉取远程模块 3.调用远程模块
整个使用过程非常的简单易懂但这样无法使用 TS 类型检查。
于是又有了以下的写法
需要先在项目入口调用
await helMicro.preFetchLib(hel-tpl-remote-lib); 然后代码中就可以这样使用了
import remoteLib from hel-tpl-remote-lib;function callRemoteMethod() {return remoteLib.num.random(19);
} TS 类型则是由 hel-tpl-remote-lib 这个 npm 仓库提供。
hel 核心原理
概念约定 远程模块发布 CDN在浏览器运行时调用 helMicro.preFetchLib 真正拉取代码* 代理模块用于开发时的类型提示上传到 npm。开发时安装并使用该 npm 包可以获得 TS 类型提示* 元数据 元数据是一份 json 配置清单是在远程模块构建完成后从构架产物中提取生成的。它记录了远程模块的名称、入口脚本路径等信息
hel 运行流程 1.当调用 helMicro.preFetchLib 时先拉取元数据从元数据中获取到入口脚本的 url然后拉取远程模块入口并执行最后 helMicro.preFetchLib 将模块返回代码中就可以直接使用了。 2.import 代理模块实际上是从远程模块的缓存中读取模块。因此必须要等待 helMicro.preFetchLib 拉取完成后import 的代理模块才能够获取到远程模块 hel 的默认拉取元数据的方式是根据远程模块名称到 unpkg CDN 对应的 npm 包下获取元数据 meta_data.json 文件。这个拉取元数据的过程也可以开发者自定义。 整个流程非常简单但难度在于如何构建打包出代理模块和远程模块
模块构建
代理模块
代理模块负责以下内容
在运行时读取远程模块的缓存用于提供 TS 类型支持
运行时读取远程模块的缓存
hel 提供了 exposeLib 函数用于读取远程模块的缓存
打包代理模块时参考以下代码作为构建入口
import type { LibProperties } from ./你真正的模块代码;
import { exposeLib } from hel-lib-proxy;// 读取远程模块缓存远程模块名为hel-tpl-remote-lib
export const lib exposeLibLibProperties(hel-tpl-remote-lib);// export 类型
export type Lib LibProperties;// export 远程模块的缓存代码
export default lib; 该入口文件主要做了以下事情
export 导出 TS 类型使用 exposeLib将远程模块的缓存暴露出来
以上述代码作为入口打包实际上并没有将模块真实代码打包到产物中。因此代理模块是一个非常小的模块没有任何的模块逻辑。
在项目中使用远程模块 hel-tpl-remote-lib最后打包只会打包代理模块这一小部分代码不会将真正的代码打包到项目的产物中因此还能提升项目的构建速度。
真正的代码是运行时在 preFetchLib 拉取远程模块时加载并运行的。
提供 TS 支持
只需要在 package.json 中声明 typing 字段
{ main: hel_proxy/entry.js, typings: typings/index.d.ts,
} typing 的值为构建时生成的 TS 类型声明文件的路径。* main 则用于声明代理模块的入口指向的是打包后的产物。### 发布
代理模块直接发布到 npm 即可按 npm 包的用法正常引入和使用即可
远程模块
远程模块的职责如下
提供远程模块的真实运行代码通知 hel 的 preFetchLib 函数远程模块加载完成提供 index.html用于提取元数据例如提取出远程模块的入口加载时需要首先拉取哪些代码
要做到以上的内容远程的模块也需要用一个入口文件再包一层伪代码如下
import { libReady } from tencent/hel-lib-proxy;async function main() {// 这里是 import 真正的模块代码了const lib await import(./你真正的模块代码);// 注意此处传递的是 defaultlibReady(hel-tpl-remote-lib, lib.default);
}main().catch(console.error); 加载入口时立即调用 main 函数
import 真正的模块代码调用 libReady 并传入远程模块的值该函数会通知 preFetchLib远程模块已经加载完成 如果一个远程模块依赖另外一个远程模块怎么办 假如hel-tpl-remote-lib 依赖 other-libother-lib 为另一个远程模块。即
// hel-tpl-remote-lib 的模块代码
import xxx from other-lib 那就 import other-lib 前先执行 preFetchLib拉取 other-lib。这样 other-lib 的代理模块就能正确获取到内容。
import { LIB_NAME } from ../src/configs/subApp;
import { libReady } from tencent/hel-lib-proxy;async function main() {// 如有其他远程包依赖并且需要在内部使用静态导入的语法可使用 preFetchLib 来加载这些包体const { preFetchLib } await import(tencent/hel-micro);await preFetchLib(other-lib);// 必须要用动态 import因为如果当前包还依赖其他的 hel 微前端依赖需要 preFetchLib 之后再进行引入。const lib await import(./你真正的模块代码);// 注意此处传递的是 defaultlibReady(hel-tpl-remote-lib, lib.default);
} 如果存在嵌套的远程模块就必须要用动态 import 引入真正的模块代码
await import(./你真正的模块代码) 元数据提取
hel 通过分析 index.html来提取元数据最重要的是要提取出模块的入口脚本因为打包产物可能会有多个文件要确定哪个才是入口。
假如有以下 HTML
!doctype html
html langen
script这是一串内联 script
/script
script srchttps://unpkg.com/hel-tpl-remote-lib2.0.0/hel_dist/static/js/main.5ab2b93c.chunk.js
/script
/html 那么会提取到两个入口脚本
内联脚本内联脚本会被提取出来存放到单独的文件该文件的路径会被记录到元数据main.5ab2b93c.chunk.js
上述 index.html 会得到以下元数据节选
{bodyAssetList: [{tag: script,attrs: {src: https://unpkg.com/hel-tpl-remote-lib2.0.0/hel_dist/hel_userChunk_1.js}},{tag: script,attrs: {src: https://unpkg.com/hel-tpl-remote-lib2.0.0/hel_dist/static/js/main.5ab2b93c.chunk.js}}]
} 注意这里的资源路径是完整的 url 了。
preFetchLib 函数会读取元数据然后拉取这些入口脚本。
发布
开源版本的 hel远程模块和元数据同样会发布到 npm。这样就可以从 unpkg 这个 CDN直接拉取到元数据和远程模块
从元数据的入口脚本可以看出入口脚本的路径已经是指向了 unpkg
小结
以上内容就是一个完整的 hel 的原理
在页面初始化前先 preFetchLib 拉取远程模块然后直接可以拿到远程模块的对象然后代理模块也能够从缓存中获取到远程模块的内容
难点则在于如何打包远程模块和代理模块需要遵守特定的规范
远程模块则需要处理嵌套的远程模块然后通知 preFetchLib 函数加载完成代理模块需要导出 TS 类型并读取远程模块的缓存并导出元数据需要根据 index.html 提取出入口脚本
但你觉得这就完了吗其实没有。
元数据的妙用
hel 提供了自定义拉取元数据的能力这意味着我们有了控制的返回元数据的能力元数据中有远程模块的入口因此能控制拉取的远程模块。
下面是一个例子 元数据通过版本管理平台的接口拉取。
通过在版本管理平台上配置可以返回的元数据的对应的远程模块版本从而做到控制远程模块的版本号能做到回滚灰度等能力。 上述版本管理平台其实在腾讯内部已经实现但目前仍未开源但从 github 上已经看到是计划中了 有了自定义拉取元数据的能力这个过程就会有非常大的自由度由此可以衍生出一个非常大的微模块生态。理论上可以做到但不限于以下的效果
控制全局的远程模块的版本快速回滚能力灰度能力、AB test 能力根据地域分布、用户等条件分发不同的元数据按项目维度进行版本控制不同的项目返回不同的元数据从而使用不同的远程模块版本……
总结
不过截止目前2022.12.13开源 hel 目前提供的部署方式只是部署到 unpkg CDN 上对于公司项目来说不太适合需要提供更多的最佳实践它的开源生态也有待完善。
但不得不承认的是hel 的整个思路的确是较为优秀值得学习和研究 能够作为一种优秀的远程模块/微模块方案。
最后也希望 hel 能越做越好吧~
最后
整理了一套《前端大厂面试宝典》包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法一共201道面试题并对每个问题作出了回答和解析。 有需要的小伙伴可以点击文末卡片领取这份文档无偿分享
部分文档展示
文章篇幅有限后面的内容就不一一展示了
有需要的小伙伴可以点下方卡片免费领取