@ray-core/runtime
Version:
Ray 是一个全新的基于 React 的小程序开发框架
127 lines (126 loc) • 5.18 kB
JavaScript
import { bindBlendedAppInstance, getNativeAppInstance } from './utils/blendedAppInstance';
import { typeOf } from './utils/typeOf';
import { nativeRequire } from './utils/nativeRequire';
var requireBlendedRuntimeOptions = (function (retries) {
var i = 0;
function r(m) {
try {
return nativeRequire(m);
}
catch (e) {
if (i++ === retries)
return;
return r("../".concat(m));
}
}
return r;
})(7);
var lifecycleCbs = [
'onLaunch',
'onUnlaunch',
'onShow',
'onHide',
'onError',
'onPageNotFound',
'onUnhandledRejection',
'onThemeChange',
];
function copyAndSetProto(obj, proto) {
function cp(o, p) {
if (!p || !Object.getPrototypeOf(p)) {
return Object.create(proto, Object.getOwnPropertyDescriptors(o));
}
return Object.create(cp(p, Object.getPrototypeOf(p)), Object.getOwnPropertyDescriptors(o));
}
return cp(obj, Object.getPrototypeOf(obj));
}
var blendedConfigFilename = 'blended.config.js';
export function overloadNativeAppConstructor(config) {
var hasRun = false;
function appWrapper(subPkgRoot) {
hasRun = true;
var runtimeOptions;
var t = typeOf(subPkgRoot);
if (t === 'string') {
var options = requireBlendedRuntimeOptions(blendedConfigFilename);
var t_1 = typeOf(options);
if (t_1 === 'array') {
runtimeOptions = options.find(function (o) { return subPkgRoot === o.subPackageRoot; });
}
else if (t_1 === 'object') {
runtimeOptions = options;
}
}
else if (t === 'object') {
runtimeOptions = subPkgRoot;
}
// subPkgRoot 未传,当成主包使用;传了,当成子包使用
var _a = runtimeOptions || { packageType: 'main' }, independent = _a.independent, _b = _a.packageType, packageType = _b === void 0 ? 'sub' : _b;
var wrapped = false;
// @ts-ignore
var nativeApp = App;
var isSubPkg = packageType === 'sub';
config.asSubPackageRuntimeOptions = runtimeOptions;
// 作为非独立分包,需依赖主包,所以生命周期在主包App中触发
if (isSubPkg && !independent) {
// TODO 作为子包时,在主包注入子包的 app.js 会导致主包体积大增,需优化
// @ts-ignore
App = function (options) {
console.log('》》》》 用作普通分包,由 App() 触发生命周期');
wrapped = true;
var appConfig = copyAndSetProto(options, config);
lifecycleCbs.forEach(function (name) {
var oldFn = config[name];
var newFn = options[name];
appConfig[name] = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (typeof oldFn === 'function')
oldFn.apply(this, args);
if (typeof newFn === 'function')
newFn.apply(this, args);
};
});
return nativeApp(appConfig);
};
}
// 此处加Promise.resolve目的是为了判断原生小程序app.js(Ray构建的小程序项目做为主包,引入另一个Ray构建的小程序) 是否加了 require('./ray/app')
Promise.resolve().then(function () {
if (wrapped)
return;
if (isSubPkg) {
bindBlendedAppInstance(config);
if (independent) {
console.log('》》》》 用作独立分包');
config.onLaunch();
}
else {
console.log("\u300B\u300B\u300B\u300B \u7528\u4F5C\u666E\u901A\u5206\u5305\uFF0C\u4F46\u672A\u5728\u4E3B\u5305\u7684 app.js \u5BFC\u5165 ".concat(config.asSubPackageRuntimeOptions.subPackageRoot, "/app.js"));
}
return;
}
bindBlendedAppInstance(null);
console.log('》》》》 用作主包');
// 有可能在主包的非 app.js 中导入了子包的 app.js
// 所以需要判断是否已经初始化了 App
var nativeAppInst = getNativeAppInstance();
if (nativeAppInst) {
console.warn('已初始化 App,有可能在主包的非app.js文件中导入了子包的 app.js');
return;
}
// 混合模式构建的小程序用作主包运行
nativeApp(config);
});
return config;
}
// 内部自执行
Promise.resolve().then(function () {
// 外部已经调用过,跳过内部自执行
console.log(hasRun ? '》》》》 外部被动执行' : '》》》》 内部主动执行');
!hasRun && appWrapper();
});
// 返回给外部调用
return appWrapper;
}