support for react hot load (#999)

This commit is contained in:
Kuitos 2020-10-15 20:46:48 +08:00 committed by GitHub
parent 73979e3f5b
commit 157cba7a44
2 changed files with 32 additions and 38 deletions

View File

@ -1,35 +0,0 @@
/**
* @author Kuitos
* @since 2020-04-26
*/
export function interceptSystemJsProps(p: PropertyKey, value: any) {
// FIXME System.js used a indirect call with eval, which would make it scope escape to global
// To make System.js works well, we write it back to global window temporary
// see https://github.com/systemjs/systemjs/blob/457f5b7e8af6bd120a279540477552a07d5de086/src/evaluate.js#L106
if (p === 'System') {
// @ts-ignore
window.System = value;
}
// see https://github.com/systemjs/systemjs/blob/457f5b7e8af6bd120a279540477552a07d5de086/src/instantiate.js#L357
if (p === '__cjsWrapper') {
// @ts-ignore
window.__cjsWrapper = value;
}
}
// FIXME see interceptSystemJsProps function
export function clearSystemJsProps(global: Window, allInactive: boolean) {
if (!allInactive) return;
if (global.hasOwnProperty('System')) {
// @ts-ignore
delete window.System;
}
if (global.hasOwnProperty('__cjsWrapper')) {
// @ts-ignore
delete window.__cjsWrapper;
}
}

View File

@ -6,7 +6,6 @@
import { SandBox, SandBoxType } from '../interfaces'; import { SandBox, SandBoxType } from '../interfaces';
import { nextTick } from '../utils'; import { nextTick } from '../utils';
import { attachDocProxySymbol, getTargetValue } from './common'; import { attachDocProxySymbol, getTargetValue } from './common';
import { clearSystemJsProps, interceptSystemJsProps } from './noise/systemjs';
/** /**
* fastest(at most time) unique array method * fastest(at most time) unique array method
@ -21,6 +20,26 @@ function uniq(array: PropertyKey[]) {
// zone.js will overwrite Object.defineProperty // zone.js will overwrite Object.defineProperty
const rawObjectDefineProperty = Object.defineProperty; const rawObjectDefineProperty = Object.defineProperty;
const variableWhiteListInDev =
process.env.NODE_ENV === 'development'
? [
// for react hot reload
// see https://github.com/facebook/create-react-app/blob/66bf7dfc43350249e2f09d138a20840dae8a0a4a/packages/react-error-overlay/src/index.js#L180
'__REACT_ERROR_OVERLAY_GLOBAL_HOOK__',
]
: [];
// who could escape the sandbox
const variableWhiteList: PropertyKey[] = [
// FIXME System.js used a indirect call with eval, which would make it scope escape to global
// To make System.js works well, we write it back to global window temporary
// see https://github.com/systemjs/systemjs/blob/457f5b7e8af6bd120a279540477552a07d5de086/src/evaluate.js#L106
'System',
// see https://github.com/systemjs/systemjs/blob/457f5b7e8af6bd120a279540477552a07d5de086/src/instantiate.js#L357
'__cjsWrapper',
...variableWhiteListInDev,
];
/* /*
variables who are impossible to be overwrite need to be escaped from proxy sandbox for performance reasons variables who are impossible to be overwrite need to be escaped from proxy sandbox for performance reasons
*/ */
@ -130,7 +149,14 @@ export default class ProxySandbox implements SandBox {
]); ]);
} }
clearSystemJsProps(this.proxy, --activeSandboxCount === 0); if (--activeSandboxCount === 0) {
variableWhiteList.forEach(p => {
if (this.proxy.hasOwnProperty(p)) {
// @ts-ignore
delete window[p];
}
});
}
this.sandboxRunning = false; this.sandboxRunning = false;
} }
@ -154,7 +180,10 @@ export default class ProxySandbox implements SandBox {
target[p] = value; target[p] = value;
updatedValueSet.add(p); updatedValueSet.add(p);
interceptSystemJsProps(p, value); if (variableWhiteList.indexOf(p) !== -1) {
// @ts-ignore
rawWindow[p] = value;
}
return true; return true;
} }