按需执行脚本需解析HTML后动态调度:用DOMParser提取script/style,对data-ignore或/async/路径的脚本延迟加载,内联脚本须沙箱包装执行;Webpack子应用需设__webpack_public_path__确保import()正确。

HTML Entry 拉取后怎么按需执行脚本,而不是全量加载?
主应用 fetch 到子应用 index.html 后,不能直接 innerHTML 注入——那只会渲染 DOM,但所有 <script> 标签(无论外链还是内联)都不会执行。真正的“按需”,是指只加载当前路由所需 JS、跳过非关键资源(比如未访问的 tab 对应的模块),这靠的是解析后的动态调度,不是 HTML 本身的能力。
- 用
DOMParser解析 HTML 字符串,拿到doc对象,再遍历doc.scripts和doc.styles,区分哪些是入口脚本(如main.js)、哪些是异步 chunk(如chunk-abc.js) - qiankun 的
import-html-entry默认会加载全部<script>,但你可以拦截:对带data-ignore="true"或路径含/async/的 script,先不执行,等用户触发对应功能时再fetch + evalInSandbox - 内联脚本(
<script>xxx</script>)必须由沙箱包装后执行,否则直接污染window;qiankun 的execScripts函数默认做这事,但若你手写加载逻辑,漏掉这步就会出错 - 注意:Webpack 构建的子应用若启用了 code splitting,
import()动态导入的代码仍会走主应用的沙箱,但前提是子应用构建时设了__webpack_public_path__,否则import()内部的相对路径请求会 404
为什么 DOM 快照 + 卸载移除不能解决所有样式逃逸?
HTML Entry 模式下,子应用卸载时移除整个根节点 DOM,浏览器自动重建 CSSOM,确实能回收大部分样式表。但这只是“快照隔离”的起点,不是终点——很多逃逸发生在卸载之后、或根本不在快照范围内。
- 子应用挂载后调用
document.head.appendChild(document.createElement('style')),这个<style>不在子应用容器内,卸载时不会被删,样式永久残留 - Ant Design 的
Modal、Tooltip默认挂载到document.body,其生成的<style>标签也脱离容器,沙箱快照无法覆盖 - HTML 中写的全局样式(如
<style>body { margin: 0 }</style>)会被快照捕获,但若子应用启用getPublicPath()+ CSS Modules,这类内联 style 仍会生效,因为快照机制不重写选择器作用域 - qiankun 的样式沙箱默认开启
snapshot模式,但如果你手动关了(sandbox: { strictStyleIsolation: false }),连快照都失效,只剩 DOM 移除这一层防护
JS 沙箱里 window 被代理了,但为什么 document.write 还是危险?
document.write 是少数几个绕过 Proxy 拦截的原生方法之一——它不走 window.document 的 getter/setter,而是直接触发浏览器底层 parser,往当前 document 流里写内容。一旦执行,就可能覆盖主应用 DOM,甚至注入恶意脚本。
- qiankun 在沙箱初始化时会重写
document.write和document.writeln,替换成抛错或静默丢弃,但前提是子应用没在沙箱创建前就提前执行了这些调用 - 常见踩坑点:子应用 HTML 中有内联
<script>document.write('<div>xxx</div>')</script>,且该 script 标签没加defer或type="module",会在 DOMParser 解析阶段就被浏览器预执行,早于沙箱建立 - 解决方案不是禁用
document.write,而是从源头约束:子应用构建时用 webpack 的ignoreWarnings: [/document\.write/]报警,CI 流水线卡住含该调用的提交 - 更稳妥的做法是子应用完全不用
document.write,改用el.innerHTML或框架的渲染 API;主应用侧可 patchdocument.write为 noop,但仅限开发环境,生产环境靠规范卡控
子应用 HTML 里写绝对路径 vs 相对路径,哪个更容易出问题?
绝对路径看似可控,实则更脆弱——它把资源定位权交给了子应用自己的部署位置,而微前端要求资源路径由主应用统一掌控。
立即学习“前端免费学习笔记(深入)”;
- 子应用 HTML 中写
<script src="https://sub1.example.com/main.js"></script>:主应用无法劫持该请求,无法注入沙箱、无法做资源预加载、无法 fallback 到 CDN 备份,且跨域策略稍有偏差就 404 - 写相对路径
<script src="./main.js"></script>:主应用 fetch HTML 后,必须同步注入__webpack_public_path__ = 'https://sub1.example.com/',否则子应用内部import()或图片src仍会 404 - 最佳实践是子应用构建时设
publicPath: ''(空字符串),让所有资源路径保持相对;主应用在加载前,用正则或 DOMParser 替换 HTML 中所有src/href属性值,补上前缀,再执行后续流程 - 注意:HTML 中的
<base href="/app1/">会影响所有相对路径解析,但 qiankun 默认不处理它,需子应用自己删掉或主应用解析时主动移除
bootstrap/mount/unmount、不操作 document.head、不依赖全局变量、所有 UI 渲染限定在传入的 container 内。这些约束不写在 HTML 里,也不体现在打包产物中,只存在于人脑和 CI 检查规则里。



















