微前端沙箱有2种实现方式:快照与代理。

    代理实现沙箱

    1. class ProxySandbox {
    2. constructor() {
    3. const rawWindow = window;
    4. const fakeWindow = {}
    5. const proxy = new Proxy(fakeWindow, {
    6. set(target, p, value) {
    7. target[p] = value;
    8. return true
    9. },
    10. get(target, p) {
    11. return target[p] || rawWindow[p];
    12. }
    13. });
    14. this.proxy = proxy
    15. }
    16. }
    17. let sandbox1 = new ProxySandbox();
    18. let sandbox2 = new ProxySandbox();
    19. window.a = 1;
    20. ((window) => {
    21. window.a = 'hello';
    22. console.log(window.a)
    23. })(sandbox1.proxy);
    24. ((window) => {
    25. window.a = 'world';
    26. console.log(window.a)
    27. })(sandbox2.proxy);

    快照实现沙箱

    1. class SnapshotSandbox {
    2. constructor() {
    3. this.modifyPropsMap = {}; // 修改了那些属性
    4. }
    5. active() {
    6. this.windowSnapshot = {}; // window对象的快照
    7. for (const prop in window) {
    8. if (window.hasOwnProperty(prop)) {
    9. // 将window上的属性进行拍照
    10. this.windowSnapshot[prop] = window[prop];
    11. }
    12. }
    13. Object.keys(this.modifyPropsMap).forEach(p => {
    14. window[p] = this.modifyPropsMap[p];
    15. });
    16. }
    17. inactive() {
    18. for (const prop in window) { // diff 差异
    19. if (window.hasOwnProperty(prop)) {
    20. // 将上次拍照的结果和本次window属性做对比
    21. if (window[prop] !== this.windowSnapshot[prop]) {
    22. // 保存修改后的结果
    23. this.modifyPropsMap[prop] = window[prop];
    24. // 还原window
    25. window[prop] = this.windowSnapshot[prop];
    26. }
    27. }
    28. }
    29. }
    30. }
    31. let sandbox = new SnapshotSandbox();
    32. window.a = 1;
    33. sandbox.active();
    34. window.b = 2;
    35. window.c = 3
    36. console.log(a,b,c)
    37. sandbox.inactive();
    38. console.log(a,b,c)