网站首页 > 技术文章 正文
概述
import-html-entry 是一个用于动态加载和处理 HTML 和 JavaScript 文件的库,主要应用于微前端架构中。
它通过从远程服务器获取 HTML 内容,解析其中的 JavaScript 和 CSS,支持在主应用中无缝集成和执行。
作为 qiankun 微前端框架的核心依赖之一,import-html-entry 提供了强大的动态加载与执行功能。
在 qiankun 框架中,它通过 HTML Entry 的方式解决了 JS Entry 的问题,使得集成微应用变得像嵌入 iframe 一样简单。
使用方法
安装
可以通过 npm 或 yarn 安装 import-html-entry:
npm install import-html-entry
或:
yarn add import-html-entry
基本用法
以下是一个简单的示例,演示如何使用 import-html-entry 加载远程 HTML 文件。官方示例中,index.html 使用 import-html-entry 加载 ./template.html:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<script type="module">
window.onerror = (e) => console.log('error', e.message);
window.onunhandledrejection = (e) => console.log('unhandledrejection', e.reason.message);
import('./dist/index.js').then(({ importEntry }) => {
importEntry('./template.html')
.then((res) => {
console.log(res);
return res.execScripts().then((exports) => {
console.log(exports);
});
})
.catch((e) => console.log('importEntry failed', e.message));
});
</script>
</body>
</html>
template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<link href="https://unpkg.com/antd@3.13.6/dist/antd.min.css" rel="stylesheet">
<link href="https://unpkg.com/bootstrap@4.3.1/dist/css/bootstrap-grid.min.css" rel="stylesheet">
</head>
<body>
<script src="./a.js"></script>
<script ignore>alert(1)</script>
<script src="./b.js"></script>
<script src="./c.js"></script>
<script src="https://unpkg.com/react@16.4.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/mobx@5.0.3/lib/mobx.umd.js"></script>
<script src="https://www.baidu.com"></script>
</body>
</html>
import-html-entry 处理后的template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<style>
/* antd styles inlined */
</style>
<style>
/* bootstrap styles inlined */
</style>
</head>
<body>
<!-- script http://127.0.0.1:7001/a.js replaced by import-html-entry -->
<!-- ignore asset js file replaced by import-html-entry -->
<!-- script http://127.0.0.1:7001/b.js replaced by import-html-entry -->
<!-- script http://127.0.0.1:7001/c.js replaced by import-html-entry -->
<!-- script https://unpkg.com/react@16.4.2/umd/react.production.min.js replaced by import-html-entry -->
<!-- script https://unpkg.com/mobx@5.0.3/lib/mobx.umd.js replaced by import-html-entry -->
<!-- script https://www.baidu.com/ replaced by import-html-entry -->
</body>
</html>
经过处理,HTML 文件中的 CSS 被转换为内联样式,而 <script> 标签被注释。
importEntry 返回值包括以下内容:
- template:处理后的 HTML 内容。
- assetPublicPath:资源路径。
- getExternalScripts:返回外部脚本信息的函数。
- getExternalStyleSheets:返回外部样式表信息的函数。
- execScripts:执行 HTML 中脚本的 JavaScript 执行器,可通过传入代理对象实现 JavaScript 沙箱化。
通过上述处理,import-html-entry 能够访问 HTML 中的 CSS 和 JavaScript 内容,其中 CSS 被内联化,而 JavaScript 可以通过 execScripts 在隔离环境中执行,实现沙箱化效果。
在 qiankun 中的使用
观察 qiankun 源代码中 import-html-entry 的使用:
// src/loader.js 第 266 行
const { template, execScripts, assetPublicPath, getExternalScripts } = await importEntry(entry, importEntryOpts);
// 第 347 行
const scriptExports: any = await execScripts(global, sandbox && !useLooseSandbox, {
scopedGlobalVariables: speedySandbox ? cachedGlobals : [],
});
// 从模块导出中提取生命周期钩子
const { bootstrap, mount, unmount, update } = getLifecyclesFromExports(
scriptExports,
appName,
global,
sandboxContainer?.instance?.latestSetProp,
);
可以看到:
- 使用 importEntry 获取处理后的 HTML,包括 JS 执行器。
- 使用 execScripts 执行脚本,传递全局上下文。
- 从模块导出中提取生命周期函数(如 bootstrap、mount、unmount 等)。
核心功能
import-html-entry 的核心功能如下:
- 获取并处理 HTML:通过 fetch 获取 HTML 内容,解析模板并提取 HTML、CSS 和 JS,移除外部链接的 CSS 和 JS 文件。
- 内嵌 CSS:将 <style> 标签中的 CSS 内联到 HTML。
- 执行 JavaScript:支持执行页面级 JavaScript,并加载所有外部 JS 文件,同时确保 JavaScript 在隔离环境中运行,避免污染全局作用域。
在微前端场景下,import-html-entry 能够从指定 URL 加载子应用的 HTML 文件,嵌入对应的 CSS,并在受控环境中执行所有 JavaScript,确保其不干扰全局作用域。
execScripts 的实现
通过 getExecutableScript 实现 JS 沙箱:
function getExecutableScript(scriptSrc, scriptText, opts = {}) {
const { proxy, strictGlobal, scopedGlobalVariables = [] } = opts;
const sourceUrl = isInlineCode(scriptSrc) ? '' : `//# sourceURL=${scriptSrc}\n`;
const scopedGlobalVariableDefinition = scopedGlobalVariables.length
? `const {${scopedGlobalVariables.join(',')}}=this;`
: '';
const globalWindow = (0, eval)('window');
globalWindow.proxy = proxy;
return strictGlobal
? `;(function(){with(this){${scopedGlobalVariableDefinition}${scriptText}\n${sourceUrl}}}).bind(window.proxy)();`
: `;(function(window, self, globalThis){${scriptText}\n${sourceUrl}}).bind(window.proxy)(window.proxy, window.proxy, window.proxy);`;
}
processTpl
通过 processTpl 方法,import-html-entry 实现以下功能:
- 替换 HTML。
- 提供 JS 入口点列表。
- 提供样式表列表。
- 确定入口文件。
这一切为微前端应用的动态加载与执行提供了高效解决方案。
猜你喜欢
- 2024-12-28 3步教你,百度网盘下载不限速,比SVIP速度还要快
- 2024-12-28 魔兽怀旧服,重复交任务宏,冲声望必备
- 2024-12-28 「安卓按键」怎么让脚本可以领取免费测试卡
- 2024-12-28 写作4年挣50万,推荐6个新手容易过稿的投稿平台
- 2024-12-28 黑客大神用什么杀毒?Windows自带的就够,只是加了亿点微小强化
- 2024-12-28 微软阻止第三方下载 Windows 镜像?
- 2024-12-28 B站视频下载详细教程 b站咋样下载视频
- 2024-12-28 从0开始学习Jmeter脚本编写 jmeter打开脚本报错
- 2024-12-28 网站渗透总结之Getshell用法大全 网站渗透技术
- 2024-12-28 如何通过C脚本在WinCC画面中的“文本”不再那么单调?
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)