diff --git a/examples/main-react/src/index.css b/examples/main-react/src/index.css
index 8c3ac7e3..0bfb68d0 100644
--- a/examples/main-react/src/index.css
+++ b/examples/main-react/src/index.css
@@ -73,7 +73,7 @@ h3 {
.content {
flex: 1;
height: 100vh;
- overflow: scroll;
+ overflow: hidden scroll;
width: 1px;
}
diff --git a/examples/main-vue/src/App.vue b/examples/main-vue/src/App.vue
index d91e2b44..e30e4808 100644
--- a/examples/main-vue/src/App.vue
+++ b/examples/main-vue/src/App.vue
@@ -117,7 +117,7 @@ h3 {
.content {
flex: 1;
height: 100vh;
- overflow: scroll;
+ overflow: hidden scroll;
width: 1px;
}
diff --git a/examples/react16/src/Font.js b/examples/react16/src/Font.js
index ef6009fe..b739a64c 100644
--- a/examples/react16/src/Font.js
+++ b/examples/react16/src/Font.js
@@ -3,7 +3,7 @@ import { IconFont } from "tdesign-icons-react";
export default class Font extends React.Component {
componentDidMount() {
- console.log("react16 font mounted")
+ console.log("react16 font mounted");
}
render() {
return (
@@ -24,9 +24,17 @@ export default class Font extends React.Component {
IconFont 图标示例
TDesign icon
-
-
-
+
+
+
+
+
+ 相对地址
+ 框架会将子应用的 css 文件中的相对地址换成绝对地址
+ 比如 TDesign icon 的 css 文件地址为:
+ https://tdesign.gtimg.com/icon/0.1.1/fonts/index.css
+ index.css 文件中 @font-face 中 url('./t.woff') 最终转换为:
+ https://tdesign.gtimg.com/icon/0.1.1/fonts/t.woff
);
diff --git a/examples/react16/src/styles.css b/examples/react16/src/styles.css
index 8ec0ff46..a77f6a71 100644
--- a/examples/react16/src/styles.css
+++ b/examples/react16/src/styles.css
@@ -45,6 +45,7 @@ nav .active {
text-align: left;
max-width: 740px;
margin: 0 auto;
+ overflow: hidden;
}
p, div.p {
diff --git a/packages/wujie-core/__test__/integration/font.test.ts b/packages/wujie-core/__test__/integration/font.test.ts
index ce8b3a70..68a86285 100644
--- a/packages/wujie-core/__test__/integration/font.test.ts
+++ b/packages/wujie-core/__test__/integration/font.test.ts
@@ -23,7 +23,7 @@ describe("main react startApp", () => {
// 等待字体加载
await page.waitForResponse((response) => response.url().includes("https://tdesign.gtimg.com/icon/0.1.1/fonts"));
// 等待字体装载
- await new Promise((resolve) => setTimeout(resolve, 100));
+ await new Promise((resolve) => setTimeout(resolve, 1000));
// 检查字体是否生效
expect(await page.evaluate(() => document.fonts.check("12px t", "E07F"))).toBe(true);
});
@@ -50,7 +50,7 @@ describe("main vue startApp", () => {
// 等待字体加载
await page.waitForResponse((response) => response.url().includes("https://tdesign.gtimg.com/icon/0.1.1/fonts"));
// 等待字体装载
- await new Promise((resolve) => setTimeout(resolve, 100));
+ await new Promise((resolve) => setTimeout(resolve, 1000));
// 检查字体是否生效
expect(await page.evaluate(() => document.fonts.check("12px t", "E07F"))).toBe(true);
});
diff --git a/packages/wujie-core/src/effect.ts b/packages/wujie-core/src/effect.ts
index 13ad1a97..95cccfcc 100644
--- a/packages/wujie-core/src/effect.ts
+++ b/packages/wujie-core/src/effect.ts
@@ -10,7 +10,6 @@ import {
isFunction,
isHijackingTag,
requestIdleCallback,
- compose,
error,
warn,
nextTick,
@@ -21,6 +20,7 @@ import {
import { insertScriptToIframe } from "./iframe";
import Wujie from "./sandbox";
import { getPatchStyleElements } from "./shadow";
+import { getCssLoader } from "./plugin";
import { WUJIE_DATA_ID, WUJIE_DATA_FLAG, WUJIE_TIPS_REPEAT_RENDER } from "./constant";
import { ScriptObject } from "./template";
@@ -56,13 +56,9 @@ function manualInvokeElementEvent(element: HTMLLinkElement | HTMLScriptElement,
/**
* 样式元素的css变量处理
*/
-function handleStylesheetElementPatch(stylesheetElement: HTMLStyleElement, sandbox: Wujie, baseUrl?: string) {
+function handleStylesheetElementPatch(stylesheetElement: HTMLStyleElement, sandbox: Wujie) {
if (!stylesheetElement.innerHTML || sandbox.degrade) return;
- const curUrl = getCurUrl(sandbox.proxyLocation as Location);
- const [hostStyleSheetElement, fontStyleSheetElement] = getPatchStyleElements(
- [stylesheetElement.sheet],
- baseUrl ? baseUrl : curUrl
- );
+ const [hostStyleSheetElement, fontStyleSheetElement] = getPatchStyleElements([stylesheetElement.sheet]);
if (hostStyleSheetElement) {
sandbox.shadowRoot.head.appendChild(hostStyleSheetElement);
}
@@ -76,8 +72,9 @@ function handleStylesheetElementPatch(stylesheetElement: HTMLStyleElement, sandb
*/
function patchStylesheetElement(
stylesheetElement: HTMLStyleElement,
- cssLoader: (code: string) => string,
- sandbox: Wujie
+ cssLoader: (code: string, url: string, base: string) => string,
+ sandbox: Wujie,
+ curUrl: string
) {
const innerHTMLDesc = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML");
const innerTextDesc = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerText");
@@ -88,7 +85,7 @@ function patchStylesheetElement(
return innerHTMLDesc.get.call(stylesheetElement);
},
set: function (code: string) {
- innerHTMLDesc.set.call(stylesheetElement, cssLoader(code));
+ innerHTMLDesc.set.call(stylesheetElement, cssLoader(code, "", curUrl));
nextTick(() => handleStylesheetElementPatch(this, sandbox));
},
},
@@ -97,7 +94,7 @@ function patchStylesheetElement(
return innerTextDesc.get.call(stylesheetElement);
},
set: function (code: string) {
- innerTextDesc.set.call(stylesheetElement, cssLoader(code));
+ innerTextDesc.set.call(stylesheetElement, cssLoader(code, "", curUrl));
nextTick(() => handleStylesheetElementPatch(this, sandbox));
},
},
@@ -106,7 +103,7 @@ function patchStylesheetElement(
return textContentDesc.get.call(stylesheetElement);
},
set: function (code: string) {
- textContentDesc.set.call(stylesheetElement, cssLoader(code));
+ textContentDesc.set.call(stylesheetElement, cssLoader(code, "", curUrl));
nextTick(() => handleStylesheetElementPatch(this, sandbox));
},
},
@@ -116,7 +113,7 @@ function patchStylesheetElement(
if (node.nodeType === Node.TEXT_NODE) {
return rawAppendChild.call(
stylesheetElement,
- stylesheetElement.ownerDocument.createTextNode(cssLoader(node.textContent))
+ stylesheetElement.ownerDocument.createTextNode(cssLoader(node.textContent, "", curUrl))
);
} else return rawAppendChild(node);
},
@@ -141,8 +138,9 @@ function rewriteAppendOrInsertChild(opts: {
return rawDOMAppendOrInsertBefore.call(this, element, refChild) as T;
}
- const { styleSheetElements, replace, fetch, plugins, iframe, lifecycles } = sandbox;
+ const { styleSheetElements, replace, fetch, plugins, iframe, lifecycles, proxyLocation } = sandbox;
const iframeDocument = iframe.contentDocument;
+ const curUrl = getCurUrl(proxyLocation);
// TODO 过滤可以开放
if (element.tagName) {
@@ -164,14 +162,12 @@ function rewriteAppendOrInsertChild(opts: {
// 记录js插入样式,子应用重新激活时恢复
const stylesheetElement = iframeDocument.createElement("style");
// 处理css-loader插件
- stylesheetElement.innerHTML = compose(plugins.map((plugin) => plugin.cssLoader))(
- replace ? replace(content) : content,
- src
- );
+ const cssLoader = getCssLoader({ plugins, replace });
+ stylesheetElement.innerHTML = cssLoader(content, src, curUrl);
styleSheetElements.push(stylesheetElement);
rawDOMAppendOrInsertBefore.call(this, stylesheetElement, refChild);
// 处理样式补丁
- handleStylesheetElementPatch(stylesheetElement, sandbox, href);
+ handleStylesheetElementPatch(stylesheetElement, sandbox);
manualInvokeElementEvent(element, "load");
element = null;
},
@@ -190,10 +186,9 @@ function rewriteAppendOrInsertChild(opts: {
const stylesheetElement: HTMLLinkElement | HTMLStyleElement = newChild as any;
styleSheetElements.push(stylesheetElement);
const content = stylesheetElement.innerHTML;
- const cssLoader = (content) =>
- compose(plugins.map((plugin) => plugin.cssLoader))(replace ? replace(content) : content);
- content && (stylesheetElement.innerHTML = cssLoader(content));
- patchStylesheetElement(stylesheetElement, cssLoader, sandbox);
+ const cssLoader = getCssLoader({ plugins, replace });
+ content && (stylesheetElement.innerHTML = cssLoader(content, "", curUrl));
+ patchStylesheetElement(stylesheetElement, cssLoader, sandbox, curUrl);
const res = rawDOMAppendOrInsertBefore.call(this, element, refChild);
// 处理样式补丁
handleStylesheetElementPatch(stylesheetElement, sandbox);
diff --git a/packages/wujie-core/src/entry.ts b/packages/wujie-core/src/entry.ts
index 31bb58c4..dc966129 100644
--- a/packages/wujie-core/src/entry.ts
+++ b/packages/wujie-core/src/entry.ts
@@ -5,7 +5,15 @@ import processTpl, {
ScriptBaseObject,
StyleObject,
} from "./template";
-import { defaultGetPublicPath, getInlineCode, requestIdleCallback, error, compose, getExcludes } from "./utils";
+import {
+ defaultGetPublicPath,
+ getInlineCode,
+ requestIdleCallback,
+ error,
+ compose,
+ getExcludes,
+ getCurUrl,
+} from "./utils";
import { WUJIE_TIPS_NO_FETCH, WUJIE_TIPS_SCRIPT_ERROR_REQUESTED, WUJIE_TIPS_CSS_ERROR_REQUESTED } from "./constant";
import Wujie from "./sandbox";
import { plugin, loadErrorHandler } from "./index";
@@ -51,11 +59,12 @@ export async function processCssLoader(
template: string,
getExternalStyleSheets: () => StyleResultList
): Promise {
+ const curUrl = getCurUrl(sandbox.proxyLocation);
/** css-loader */
const composeCssLoader = compose(sandbox.plugins.map((plugin) => plugin.cssLoader));
const processedCssList: StyleResultList = getExternalStyleSheets().map(({ src, contentPromise }) => ({
src,
- contentPromise: contentPromise.then((content) => composeCssLoader(content, src)),
+ contentPromise: contentPromise.then((content) => composeCssLoader(content, src, curUrl)),
}));
const embedHTML = await getEmbedHTML(template, processedCssList);
return sandbox.replace ? sandbox.replace(embedHTML) : embedHTML;
diff --git a/packages/wujie-core/src/iframe.ts b/packages/wujie-core/src/iframe.ts
index 0f589f19..d75342c4 100644
--- a/packages/wujie-core/src/iframe.ts
+++ b/packages/wujie-core/src/iframe.ts
@@ -9,8 +9,8 @@ import {
isMatchSyncQueryById,
warn,
error,
- compose,
execHooks,
+ getCurUrl,
} from "./utils";
import {
documentProxyProperties,
@@ -23,6 +23,7 @@ import {
windowProxyProperties,
windowRegWhiteList,
} from "./common";
+import { getJsLoader } from "./plugin";
import { WUJIE_TIPS_EMPTY_CALLBACK, WUJIE_TIPS_SCRIPT_ERROR_REQUESTED, WUJIE_DATA_FLAG } from "./constant";
import { ScriptObjectLoader } from "./index";
@@ -611,8 +612,9 @@ export function insertScriptToIframe(scriptResult: ScriptObject | ScriptObjectLo
const { src, module, content, crossorigin, crossoriginType, callback } = scriptResult as ScriptObjectLoader;
const scriptElement = iframeWindow.document.createElement("script");
const nextScriptElement = iframeWindow.document.createElement("script");
- const { replace, plugins } = iframeWindow.__WUJIE;
- let code = compose(plugins.map((plugin) => plugin.jsLoader))(replace ? replace(content) : content, src);
+ const { replace, plugins, proxyLocation } = iframeWindow.__WUJIE;
+ const jsLoader = getJsLoader({ plugins, replace });
+ let code = jsLoader(content, src, getCurUrl(proxyLocation));
// 内联脚本
if (content) {
diff --git a/packages/wujie-core/src/index.ts b/packages/wujie-core/src/index.ts
index 35c9e3a3..2c3fe869 100644
--- a/packages/wujie-core/src/index.ts
+++ b/packages/wujie-core/src/index.ts
@@ -32,7 +32,7 @@ export interface plugin {
/** 处理js加载前的loader */
jsBeforeLoaders?: Array;
/** 处理js的loader */
- jsLoader?: (code: string, url: string) => string;
+ jsLoader?: (code: string, url: string, base: string) => string;
/** 处理js加载后的loader */
jsAfterLoaders?: Array;
/** css排除列表 */
@@ -40,7 +40,7 @@ export interface plugin {
/** 处理css加载前的loader */
cssBeforeLoaders?: Array;
/** 处理css的loader */
- cssLoader?: (code: string, url: string) => string;
+ cssLoader?: (code: string, url: string, base: string) => string;
/** 处理css加载后的loader */
cssAfterLoaders?: Array;
/** 子应用 window addEventListener 钩子回调 */
diff --git a/packages/wujie-core/src/plugin.ts b/packages/wujie-core/src/plugin.ts
new file mode 100644
index 00000000..b7a8b92f
--- /dev/null
+++ b/packages/wujie-core/src/plugin.ts
@@ -0,0 +1,81 @@
+import { plugin } from "./index";
+import { compose, getAbsolutePath } from "./utils";
+
+interface loaderOption {
+ plugins: Array;
+ replace: (code: string) => string;
+}
+
+/**
+ * 获取柯里化 cssLoader
+ */
+export function getCssLoader({ plugins, replace }: loaderOption) {
+ return (code: string, src: string = "", base: string): string =>
+ compose(plugins.map((plugin) => plugin.cssLoader))(replace ? replace(code) : code, src, base);
+}
+
+/**
+ * 获取柯里化 jsLoader
+ */
+export function getJsLoader({ plugins, replace }: loaderOption) {
+ return (code: string, src: string = "", base: string): string =>
+ compose(plugins.map((plugin) => plugin.jsLoader))(replace ? replace(code) : code, src, base);
+}
+
+/**
+ * 获取有效的 cssBeforeLoaders
+ */
+export function getCssBeforeLoaders(plugins: Array) {
+ return plugins
+ .map((plugin) => plugin.cssBeforeLoaders)
+ .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
+ .filter((cssLoader) => typeof cssLoader === "object")
+ .reverse();
+}
+
+/**
+ * 获取有效的 cssAfterLoaders
+ */
+export function getCssAfterLoaders(plugins: Array) {
+ return plugins
+ .map((plugin) => plugin.cssAfterLoaders)
+ .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
+ .filter((afterLoader) => typeof afterLoader === "object");
+}
+
+/**
+ * 获取有效的 jsBeforeLoaders
+ */
+export function getJsBeforeLoaders(plugins: Array) {
+ return plugins
+ .map((plugin) => plugin.jsBeforeLoaders)
+ .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
+ .filter((preLoader) => typeof preLoader === "object");
+}
+
+/**
+ * 获取有效的 jsAfterLoaders
+ */
+export function getJsAfterLoaders(plugins: Array) {
+ return plugins
+ .map((plugin) => plugin.jsAfterLoaders)
+ .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
+ .filter((afterLoader) => typeof afterLoader === "object");
+}
+
+/**
+ * 转换子应用css内的相对地址成绝对地址
+ */
+function cssRelativePathResolve(code: string, src: string, base: string) {
+ const baseUrl = src ? getAbsolutePath(src, base) : base;
+ const urlReg = /(url\()([^)]*)(\))/g;
+ return code.replace(urlReg, (_m, pre, url, post) => {
+ const urlString = url.replace(/["']/g, "");
+ const absoluteUrl = getAbsolutePath(urlString, baseUrl);
+ return pre + "'" + absoluteUrl + "'" + post;
+ });
+}
+
+export default {
+ cssLoader: cssRelativePathResolve,
+};
diff --git a/packages/wujie-core/src/sandbox.ts b/packages/wujie-core/src/sandbox.ts
index caaa78a0..0b761a3c 100644
--- a/packages/wujie-core/src/sandbox.ts
+++ b/packages/wujie-core/src/sandbox.ts
@@ -17,6 +17,7 @@ import {
} from "./shadow";
import { proxyGenerator, localGenerator } from "./proxy";
import { ScriptResultList } from "./entry";
+import defaultPlugin, { getJsBeforeLoaders, getJsAfterLoaders } from "./plugin";
import {
idToSandboxMap,
addSandboxIdMap,
@@ -25,7 +26,7 @@ import {
rawDocumentQuerySelector,
} from "./common";
import { EventBus, appEventObjMap, EventObj } from "./event";
-import { isFunction, wujieSupport, appRouteParse, requestIdleCallback, getCurUrl } from "./utils";
+import { isFunction, wujieSupport, appRouteParse, requestIdleCallback } from "./utils";
import { WUJIE_DATA_ATTACH_CSS_FLAG } from "./constant";
import { plugin, ScriptObjectLoader, loadErrorHandler } from "./index";
@@ -242,15 +243,9 @@ export default class Wujie {
// 标志位,执行代码前设置
iframeWindow.__POWERED_BY_WUJIE__ = true;
// 用户自定义代码前
- const beforeScriptResultList: ScriptObjectLoader[] = this.plugins
- .map((plugin) => plugin.jsBeforeLoaders)
- .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
- .filter((preLoader) => typeof preLoader === "object");
+ const beforeScriptResultList: ScriptObjectLoader[] = getJsBeforeLoaders(this.plugins);
// 用户自定义代码后
- const afterScriptResultList: ScriptObjectLoader[] = this.plugins
- .map((plugin) => plugin.jsAfterLoaders)
- .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
- .filter((afterLoader) => typeof afterLoader === "object");
+ const afterScriptResultList: ScriptObjectLoader[] = getJsAfterLoaders(this.plugins);
// 同步代码
const syncScriptResultList: ScriptResultList = [];
// async代码无需保证顺序,所以不用放入执行队列
@@ -404,14 +399,12 @@ export default class Wujie {
* 2、将@font-face定义到shadowRoot外部
*/
public patchCssRules(): void {
- const curUrl = getCurUrl(this.proxyLocation as Location);
if (this.degrade) return;
if (this.shadowRoot.host.hasAttribute(WUJIE_DATA_ATTACH_CSS_FLAG)) return;
const [hostStyleSheetElement, fontStyleSheetElement] = getPatchStyleElements(
Array.from(this.iframe.contentDocument.querySelectorAll("style")).map(
(styleSheetElement) => styleSheetElement.sheet
- ),
- curUrl
+ )
);
if (hostStyleSheetElement) {
this.shadowRoot.head.appendChild(hostStyleSheetElement);
@@ -456,7 +449,7 @@ export default class Wujie {
this.styleSheetElements = [];
this.execQueue = [];
this.lifecycles = lifecycles;
- this.plugins = Array.isArray(plugins) ? plugins : [];
+ this.plugins = Array.isArray(plugins) ? [defaultPlugin, ...plugins] : [defaultPlugin];
// 创建目标地址的解析
const { urlElement, appHostPath, appRoutePath } = appRouteParse(url);
diff --git a/packages/wujie-core/src/shadow.ts b/packages/wujie-core/src/shadow.ts
index 68cfc5fd..ba81bd27 100644
--- a/packages/wujie-core/src/shadow.ts
+++ b/packages/wujie-core/src/shadow.ts
@@ -4,7 +4,8 @@ import { getExternalStyleSheets } from "./entry";
import Wujie from "./sandbox";
import { patchElementEffect } from "./iframe";
import { patchRenderEffect } from "./effect";
-import { getContainer, compose } from "./utils";
+import { getCssLoader, getCssBeforeLoaders, getCssAfterLoaders } from "./plugin";
+import { getContainer, getCurUrl } from "./utils";
const cssSelectorMap = {
":root": ":host",
@@ -72,18 +73,12 @@ export function renderElementToContainer(element: Element, selectorOrElement: st
*/
async function processCssLoaderForTemplate(sandbox: Wujie, html: HTMLHtmlElement): Promise {
const document = sandbox.iframe.contentDocument;
- const { plugins, replace } = sandbox;
- const cssLoader = (content, src) =>
- compose(plugins.map((plugin) => plugin.cssLoader))(replace ? replace(content) : content, src);
- const cssBeforeLoaders = sandbox.plugins
- .map((plugin) => plugin.cssBeforeLoaders)
- .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
- .filter((cssLoader) => typeof cssLoader === "object")
- .reverse();
- const cssAfterLoaders = sandbox.plugins
- .map((plugin) => plugin.cssAfterLoaders)
- .reduce((preLoaders, curLoaders) => preLoaders.concat(curLoaders), [])
- .filter((afterLoader) => typeof afterLoader === "object");
+ const { plugins, replace, proxyLocation } = sandbox;
+ const cssLoader = getCssLoader({ plugins, replace });
+ const cssBeforeLoaders = getCssBeforeLoaders(plugins);
+ const cssAfterLoaders = getCssAfterLoaders(plugins);
+ const curUrl = getCurUrl(proxyLocation);
+
return await Promise.all([
Promise.all(
getExternalStyleSheets(cssBeforeLoaders, sandbox.fetch, sandbox.lifecycles.loadError).map(
@@ -94,7 +89,7 @@ async function processCssLoaderForTemplate(sandbox: Wujie, html: HTMLHtmlElement
if (!content) return;
const styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
- styleElement.appendChild(document.createTextNode(content ? cssLoader(content, src) : content));
+ styleElement.appendChild(document.createTextNode(content ? cssLoader(content, src, curUrl) : content));
const head = html.querySelector("head");
head?.insertBefore(styleElement, html.querySelector("head")?.firstChild);
});
@@ -108,7 +103,7 @@ async function processCssLoaderForTemplate(sandbox: Wujie, html: HTMLHtmlElement
if (!content) return;
const styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
- styleElement.appendChild(document.createTextNode(content ? cssLoader(content, src) : content));
+ styleElement.appendChild(document.createTextNode(content ? cssLoader(content, src, curUrl) : content));
html.appendChild(styleElement);
});
}),
@@ -221,14 +216,10 @@ export function clearChild(root: ShadowRoot | Node): void {
* 获取修复好的样式元素
* 主要是针对对root样式和font-face样式
*/
-export function getPatchStyleElements(
- rootStyleSheets: Array,
- baseUrl: string
-): Array {
+export function getPatchStyleElements(rootStyleSheets: Array): Array {
const rootCssRules = [];
const fontCssRules = [];
const rootStyleReg = /:root/g;
- const fontStyleReg = /(url\()([^)]*)(\))/g;
// 找出root的cssRules
for (let i = 0; i < rootStyleSheets.length; i++) {
@@ -241,14 +232,7 @@ export function getPatchStyleElements(
}
// 如果是font-face的cssRule
if (cssRules[j].type === CSSRule.FONT_FACE_RULE) {
- fontCssRules.push(
- // 相对地址改绝对地址
- cssRuleText.replace(fontStyleReg, (_m, pre, url, post) => {
- const urlString = url.replace(/["']/g, "");
- const absoluteUrl = new URL(urlString, baseUrl).href;
- return pre + "'" + absoluteUrl + "'" + post;
- })
- );
+ fontCssRules.push(cssRuleText);
}
}
}
diff --git a/packages/wujie-core/src/template.ts b/packages/wujie-core/src/template.ts
index e1374e7a..8ecb22be 100644
--- a/packages/wujie-core/src/template.ts
+++ b/packages/wujie-core/src/template.ts
@@ -245,7 +245,7 @@ export default function processTpl(tpl: String, baseURI: String, postProcessTemp
if (!isPureCommentBlock && code) {
scripts.push({
- src: null,
+ src: "",
content: code,
module: isModuleScript,
crossorigin: !!isCrossOriginScript,
diff --git a/packages/wujie-core/src/utils.ts b/packages/wujie-core/src/utils.ts
index 05b5c13f..87a97908 100644
--- a/packages/wujie-core/src/utils.ts
+++ b/packages/wujie-core/src/utils.ts
@@ -170,10 +170,18 @@ export function fixElementCtrSrcOrHref(
// TODO: innerHTML的处理
}
-export function getCurUrl(proxyLocation: Location): string {
- return proxyLocation.protocol + "//" + proxyLocation.host + proxyLocation.pathname;
+export function getCurUrl(proxyLocation: Object): string {
+ const location = proxyLocation as Location;
+ return location.protocol + "//" + location.host + location.pathname;
}
+export function getAbsolutePath(url: string, base: string): string {
+ try {
+ return new URL(url, base).href;
+ } catch {
+ return url;
+ }
+}
/**
* 获取需要同步的url
*/
diff --git a/packages/wujie-doc/docs/api/startApp.md b/packages/wujie-doc/docs/api/startApp.md
index cd9ea09f..cf3bfa2c 100644
--- a/packages/wujie-doc/docs/api/startApp.md
+++ b/packages/wujie-doc/docs/api/startApp.md
@@ -224,13 +224,13 @@ interface plugin {
/** 处理js加载前的loader */
jsBeforeLoaders: Array;
/** 处理js的loader */
- jsLoader: (code: string, url: string) => string;
+ jsLoader: (code: string, url: string, base: string) => string;
/** 处理js加载后的loader */
jsAfterLoaders: Array;
/** 处理css加载前的loader */
cssBeforeLoaders: Array;
/** 处理css的loader */
- cssLoader: (code: string, url: string) => string;
+ cssLoader: (code: string, url: string, base: string) => string;
/** 处理css加载后的loader */
cssAfterLoaders: Array;
/** 子应用 window addEventListener 钩子回调 */
diff --git a/packages/wujie-doc/docs/guide/plugin.md b/packages/wujie-doc/docs/guide/plugin.md
index 5ad5861b..ce28b540 100644
--- a/packages/wujie-doc/docs/guide/plugin.md
+++ b/packages/wujie-doc/docs/guide/plugin.md
@@ -75,7 +75,8 @@ const plugins = [
const plugins = [
{
// 将url为aaa.js的脚本中的aaa替换成bbb
- jsLoader: (code, url) => {
+ // code 为脚本代码、url为脚本的地址(内联脚本为'')、base为子应用当前的地址
+ jsLoader: (code, url, base) => {
if (url === "aaa.js") return code.replace("aaa", "bbb");
},
},
@@ -163,7 +164,8 @@ const plugins = [
const plugins = [
{
// 对css脚本动态的进行替换
- cssLoader: (code, url) => {
+ // code 为样式代码、url为样式的地址(内联样式为'')、base为子应用当前的地址
+ cssLoader: (code, url, base) => {
console.log("css-loader", url, code.slice(0, 50) + "...");
return code;
},
diff --git a/packages/wujie-doc/docs/question/README.md b/packages/wujie-doc/docs/question/README.md
index 37e7db18..44c0516b 100644
--- a/packages/wujie-doc/docs/question/README.md
+++ b/packages/wujie-doc/docs/question/README.md
@@ -38,7 +38,7 @@ ctx.set("Access-Control-Allow-Origin", ctx.headers.origin);
**原因:** `@font-face`不会在`shadow`内部加载,[详见](https://github.com/mdn/interactive-examples/issues/887)
-**解决方案:** 框架已解决,会将子应用的`@font-face`放到`shadow`外部执行,注意子应用的自定义字体名和主应用的自定义字体名不能重复,否则可能存在覆盖问题
+**已解决:** 框架会将子应用的`@font-face`放到`shadow`外部执行,注意子应用的自定义字体名和主应用的自定义字体名不能重复,否则可能存在覆盖问题
## 4、冒泡系列组件(比如下拉框)弹出位置不正确
@@ -55,9 +55,7 @@ ctx.set("Access-Control-Allow-Origin", ctx.headers.origin);
## 6、css 样式内部的相对地址相对的是主应用的域名
-**原因:** 由于框架没有处理子应用样式内部的相对地址,而子应用样式是挂载在主应用容器中,导致相对地址错误
-
-**解决方案:** 使用插件中的[css-loader](/guide/plugin.html#css-loader)在运行时将相对地址代码替换成绝对地址。
+**已解决:** 框架已处理,默认将相对地址转换成绝对地址
## 7、子应用使用 module federation 引用远程模块报错