微前端之 entry 加载工具
什么是 entry
微应用、微模块的入口
systemjs
SystemJS 是一个基于标准的模块加载器。
工作环境:
- 在不支持原生模块的浏览器环境中,提供以 System.register 的模块格式的模块加载代码
- single-spa 通过 systemjs 实现微模块、
特点:
- 支持动态导入、css js json wasm 模块类型、兼容 IE11
- 支持文件: js、css、json、wsm
- 支持模块规范: system、umd、amd(插件支持)
import-html-enry
qiankun 框架配套开发支持 html 作为入口(entry) 的资源加载器(loader)。
工作环境:
- qiankun 框架为了解决 JS Entry 的问题,采用更方便的 HTML Entry 方式,目的让微应用接入像 iframe 一样只需配置页面 html 的 url 地址
特点:
- 支持文件: js、css、html
- 支持模块规范: umd
调试 systemjs
为了方便 debugger 使用 Systemjs.import API 进行调试
useEffect(() => {
(async () => {
debugger
// 导入 js 资源
const mobx = await Systemjs.import('https://unpkg.com/mobx@5.0.3/lib/mobx.umd.js')
console.log(mobx);
// 导入 css 文件
Systemjs.import('https://unpkg.com/bootstrap@5.0.2/dist/css/bootstrap.min.css').then(module => {
const styleSheet = module.default; // A CSSStyleSheet object
document.adoptedStyleSheets = [...document.adoptedStyleSheets, styleSheet]; // now your css is available to be used.
// https://developers.google.com/web/updates/2019/02/constructable-stylesheets
})
})()
调用 api import
- systemJSPrototype.import 实例方法
- preimport - 处理 script 标签
-对 type 为 systemjs-module、systemjs-importmap 进行处理
getOrCreateLoad -> loader.instantiate(id, firstParentUrl) loader 就是 Systemjs -> systemInstantiate 判断 shouldFetch(js false, css true
进入 getOrCreateLoadgetOrCreateLoad 返回 load 对象
// Capital letter = a promise function
return load = loader[REGISTRY][id] = {
id: id,
// importerSetters, the setters functions registered to this dependency
// we retain this to add more later
i: importerSetters,
// module namespace object
n: ns, // import 导出的模块
// instantiate
I: instantiatePromise,
// link
L: linkPromise,
// whether it has hoisted exports
h: false,
// On instantiate completion we have populated:
// dependency load records
d: undefined, // 模块依赖,需提前加载
// execution function
e: undefined,
// On execution we have populated:
// the execution error if any
er: undefined,
// in the case of TLA, the execution promise
E: undefined,
// On execution, L, I, E cleared
// Promise for top-level completion
C: undefined,
// parent instantiator / executor
p: undefined
};
systemInstantiate 通过 shouldFetch 判断资源是否需要 fetch 来加载,js 文件类型通过 <script > 标签导入当前环境, css 文件类型返回 registersystemjs 导入其他类型文件
systemjs 除了对 js 也支持 css、json、wasm 文件资源,通过 systemJSPrototype.fetch 方法根据资源的类型判断调用 源生 fetch 获取资源包装成 systemjs 模块规范的对象返回
css 文件包装成 CSSStylesheet 对象返回
Systemjs.import('https://unpkg.com/bootstrap@5.0.2/dist/css/bootstrap.min.css').then(module => {
const styleSheet = module.default; // A CSSStyleSheet object
document.adoptedStyleSheets = [...document.adoptedStyleSheets, styleSheet]; // now your css is available to be used.
// https://developers.google.com/web/updates/2019/02/constructable-stylesheets
})
分析 import-html-entry
debugger
importHTML('http://localhost:8080/example/template.html')
.then(res => {
console.log(res);
console.log(res.template);
res.getExternalScripts().then(r => {
console.log('---getExternalScripts---');
console.log(r);
})
res.getExternalStyleSheets().then(g => {
console.log('---getExternalStyleSheets---');
console.log(g);
})
debugger
res.execScripts().then(exports => {
console.log('---execScripts---');
console.log(exports);
})
});
加载 template.html 并返回对象
import-html-entry 的源码简洁清晰,进入方法中第一眼就能看到返回值对象
{
template: String, // html 文本
assetPublicPath: String, // 资源的 public path
getExternalScripts: Function () => String[], // 解析 <script> 出来的 js 代码文本数组
getExternalStyleSheets: Function () => String[], // 解析 <style> 出来的 css 文本数组
execScripts: Function () => Object, // 返回远程导入的 entry 对象
}
importEntry 的返回
{
template // 返回被处理过的 html
assetPublichPath // 资源加载地址
getExternalScripts // 返回解析加载过的 script 数组,包括内嵌和外联的资源
getExternalStyleSheets // 返回解析加载过的 style 数组,包括内嵌和外联的资源
execScripts // 返回解析 html 后的 entry,一般是最后一个 script 或者标签标识为 entry 的 js
}
template, getExternalScripts, getExternalStyleSheets
execScripts
总结
相同点:都是运行时加载
不同点:systemjs 可以通过插件加载 amd udm commonjs es6Module,import html entry 只能加载 umd
package | 支持 js 模块规范 | 支持文件类型 | 工具类型 | entry 区别 |
---|---|---|---|---|
systemjs | system、umd | js、css、json、wsm | 基于标准的模块加载 | js entry |
import-html-entry | umd | js、css、html | 资源加载工具 | html entry |
systemjs 不仅是个模块加载工具更是有一套标准的模块规范,single-spa 依赖 systemjs 规范通过 js entry 实现微应用、微模块的加载。
importEntry 只支持 umd 的 js 文件,qiankun 通过 importHtml 解析 html 模板分析资源 实现 html entry 的方式加载 微应用。
import-html-entry 作为工具更适合,systemjs 是独立的模块规范 webpack rollup 打包工具都支持 systemjs 规范。
原理都是对 script 标签的资源进行 appendChild 再 remove 的方式加载到全局,对 style 标签的资源进行 fetch 获取和解析。
import-html-entry 源码方面设计的很清晰可以参考 HTML Entry 源码分析 也可以通过 debugger 的方式自己了解。
发表评论 (审核通过后显示评论):