Skip to content

Commit

Permalink
fix: 修复window被proxy导致作用域错误 (#106)
Browse files Browse the repository at this point in the history
close #102 

* fix: 修复window被proxy,导致作用域错误

* test: add proxy test case

Co-authored-by: fanzehong <[email protected]>
  • Loading branch information
Heath1998 and fanzehong authored Sep 2, 2022
1 parent 841385f commit 4895297
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/wujie-core/__test__/integration/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export const reactMainAppInfoMap = {
},
};
export const reactMainAppInfoList = Object.entries(reactMainAppInfoMap).map((item) => item[1]);
export const reactMainAppNameList = Object.entries(reactMainAppInfoMap).map((item) => item[0]);

export const vueMainAppInfoMap = {
react16: {
name: "react16",
Expand Down Expand Up @@ -275,3 +277,4 @@ export const vueMainAppInfoMap = {
},
};
export const vueMainAppInfoList = Object.entries(vueMainAppInfoMap).map((item) => item[1]);
export const vueMainAppNameList = Object.entries(vueMainAppInfoMap).map((item) => item[0]);
62 changes: 62 additions & 0 deletions packages/wujie-core/__test__/integration/proxy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { awaitConsoleLogMessage } from "./utils";
import { reactMainAppInfoMap, vueMainAppInfoMap, vueMainAppNameList, reactMainAppNameList } from "./common";

const generateTest = (
AppInfoMap: typeof reactMainAppInfoMap | typeof vueMainAppInfoMap,
AppNameList: typeof vueMainAppNameList | typeof reactMainAppNameList
) => {
AppNameList.slice(0, 5).forEach((appName) => {
it("proxy test", async () => {
const childApplicationMountedPromise = awaitConsoleLogMessage(page, AppInfoMap[appName].mountedMessage);
await page.click(AppInfoMap[appName].linkSelector);
await childApplicationMountedPromise;

// 测试boundValue缓存,及作用域
const { targetCurrentAttribute, isSameBoundFn } = await page.evaluate((childName) => {
const childWindowCollection = [window[0], window[1], window[2], window[3], window[4], window[5]];
const childWindow: any = childWindowCollection.find((itemWindow) => itemWindow.name === childName);
const currentObject: any = {};
const childProxyWindow = childWindow.__WUJIE.proxy;
childProxyWindow.addAttributeToObject = function addAttributeToObject() {
this.currentAttribute = "Add attribute";
};
childProxyWindow.addAttributeToObject.call(currentObject);
return {
targetCurrentAttribute: currentObject.currentAttribute,
isSameBoundFn: childProxyWindow.setTimeout === childProxyWindow.setTimeout,
};
}, appName);

expect(targetCurrentAttribute).toBe("Add attribute");
expect(isSameBoundFn).toBe(true);
});
});
};

describe("main react startApp", () => {
beforeAll(async () => {
await page.evaluateOnNewDocument(() => {
// 关闭预加载
localStorage.clear();
localStorage.setItem("preload", "false");
localStorage.setItem("degrade", "false");
});
await page.goto("http://localhost:7700/");
});

generateTest(reactMainAppInfoMap, reactMainAppNameList);
});

describe("main vue startApp", () => {
beforeAll(async () => {
await page.evaluateOnNewDocument(() => {
// 关闭预加载
localStorage.clear();
localStorage.setItem("preload", "false");
localStorage.setItem("degrade", "false");
});
await page.goto("http://localhost:8000/");
});

generateTest(vueMainAppInfoMap, vueMainAppNameList);
});
10 changes: 9 additions & 1 deletion packages/wujie-core/src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { renderElementToContainer } from "./shadow";
import { pushUrlToWindow } from "./sync";
import { documentProxyProperties, rawDocumentQuerySelector } from "./common";
import { WUJIE_TIPS_RELOAD_DISABLED } from "./constant";
import { getTargetValue, anchorElementGenerator, getDegradeIframe, isCallable, warn } from "./utils";
import {
getTargetValue,
anchorElementGenerator,
getDegradeIframe,
isCallable,
checkProxyFunction,
warn,
} from "./utils";

/**
* location href 的set劫持操作
Expand Down Expand Up @@ -58,6 +65,7 @@ export function proxyGenerator(
},

set: (target: Window, p: PropertyKey, value: any) => {
checkProxyFunction(value);
target[p] = value;
return true;
},
Expand Down
13 changes: 13 additions & 0 deletions packages/wujie-core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,23 @@ export function isConstructable(fn: () => any | FunctionConstructor) {
return constructable;
}

const setFnCacheMap = new WeakMap<CallableFunction, CallableFunction>();
export function checkProxyFunction(value: any) {
if (isCallable(value) && !isBoundedFunction(value) && !isConstructable(value)) {
if (!setFnCacheMap.has(value)) {
setFnCacheMap.set(value, value);
}
}
}

export function getTargetValue(target: any, p: any): any {
const value = target[p];
if (setFnCacheMap.has(value)) {
return setFnCacheMap.get(value);
}
if (isCallable(value) && !isBoundedFunction(value) && !isConstructable(value)) {
const boundValue = Function.prototype.bind.call(value, target);
setFnCacheMap.set(value, boundValue);

for (const key in value) {
boundValue[key] = value[key];
Expand Down

0 comments on commit 4895297

Please sign in to comment.