Skip to content

Commit

Permalink
feat: change the code structure
Browse files Browse the repository at this point in the history
  • Loading branch information
imtaotao committed Jul 1, 2021
1 parent 7dbe693 commit 4174e14
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 179 deletions.
154 changes: 0 additions & 154 deletions packages/runtime/remote-component/src/apis.ts

This file was deleted.

58 changes: 58 additions & 0 deletions packages/runtime/remote-component/src/apis/loadComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { assert, isAbsolute } from '@garfish/utils';
import { Actuator } from '../actuator';
import {
loader,
LOADING,
purifyOptions,
ComponentInfo,
cacheComponents,
} from '../common';

export function loadComponent(
options: ComponentInfo | string,
): Promise<Record<string, any> | null> {
const info = purifyOptions(options);
const { url, env, cache, version, error, adapter } = info;

assert(url, 'Missing url for loading micro component');
assert(
isAbsolute(url),
'The loading of the micro component must be an absolute path.',
);

// `1.0@https://xx.js`
// `latest@https://xx.js`
const urlWithVersion = `${version || 'latest'}@${url}`;

const asyncLoadProcess = async () => {
let result = null;
try {
const component = cacheComponents[urlWithVersion];
if (cache && component) {
result = component;
} else {
const data = await loader.loadComponent(url);
const actuator = new Actuator(data.resourceManager, env);
let exports = actuator.execScript().exports;
if (typeof adapter === 'function') {
exports = adapter(exports);
}
result = exports;
cacheComponents[urlWithVersion] = result;
}
} catch (err) {
if (typeof error === 'function') {
result = error(err);
} else {
throw err;
}
} finally {
LOADING[urlWithVersion] = null;
}
return result;
};
if (!LOADING[urlWithVersion]) {
LOADING[urlWithVersion] = asyncLoadProcess();
}
return LOADING[urlWithVersion];
}
51 changes: 51 additions & 0 deletions packages/runtime/remote-component/src/apis/loadComponentSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { assert, isAbsolute } from '@garfish/utils';
import { Actuator } from '../actuator';
import {
purifyOptions,
ComponentInfo,
cacheComponents,
PRE_STORED_RESOURCES,
} from '../common';

export function loadComponentSync(
options: ComponentInfo | string,
): Record<string, any> {
const info = purifyOptions(options);
assert(info.url, 'Missing url for loading micro component');
assert(
isAbsolute(info.url),
'The loading of the micro component must be an absolute path.',
);

let result = null;
const { url, env, cache, version, error, adapter } = info;
const urlWithVersion = `${version || 'latest'}@${url}`;
const component = cacheComponents[urlWithVersion];

if (cache && component) {
result = component;
} else {
const manager = PRE_STORED_RESOURCES[url];
assert(
manager,
'Synchronously load components must load resources in advance.',
);

try {
const actuator = new Actuator(manager, env);
let exports = actuator.execScript().exports;
if (typeof adapter === 'function') {
exports = adapter(exports);
}
result = exports;
cacheComponents[urlWithVersion] = result;
} catch (err) {
if (typeof error === 'function') {
result = error(err);
} else {
throw err;
}
}
}
return result;
}
19 changes: 19 additions & 0 deletions packages/runtime/remote-component/src/apis/preload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { assert, isAbsolute } from '@garfish/utils';
import { loader, PRE_STORED_RESOURCES } from '../common';

// Preload the static resources of the component, so that the component can be loaded synchronously
export function preload(urls: string | Array<string>) {
if (!Array.isArray(urls)) urls = [urls];

return Promise.all(
urls.map((url) => {
assert(
isAbsolute(url || ''),
'The loading of the micro component must be an absolute path.',
);
return loader.loadComponent(url).then((data) => {
PRE_STORED_RESOURCES[url] = data.resourceManager;
});
}),
);
}
22 changes: 22 additions & 0 deletions packages/runtime/remote-component/src/apis/setExternal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { warn, assert, deepMerge, isAbsolute } from '@garfish/utils';
import { Actuator, EXTERNALS } from '../actuator';

export function setExternal(
nameOrExtObj: string | Record<string, any>,
value?: any,
) {
assert(nameOrExtObj, 'Invalid parameter.');
if (typeof nameOrExtObj === 'object') {
for (const key in nameOrExtObj) {
if (EXTERNALS[key]) {
__DEV__ &&
warn(
`The "${key}" will be overwritten in remote components external.`,
);
}
EXTERNALS[key] = nameOrExtObj[key];
}
} else {
EXTERNALS[nameOrExtObj] = value;
}
}
35 changes: 35 additions & 0 deletions packages/runtime/remote-component/src/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Loader } from '@garfish/loader';
import { deepMerge } from '@garfish/utils';

export interface ComponentInfo {
url: string;
cache?: boolean; // Whether the cache
version?: string;
env?: Record<string, any>;
error?: (err: Error) => any;
adapter?: (cjsModule: Record<string, any>) => Record<string, any>;
}

export const LOADING = Object.create(null);
export const PRE_STORED_RESOURCES = Object.create(null);
export const cacheComponents = Object.create(null);

export const loader = (() => {
if (window.Garfish) {
const loader = window.Garfish && window.Garfish.loader;
// Garfish loader will have an identifier
if (loader && loader.personalId === Symbol.for('garfish.loader')) {
return loader;
}
return new Loader();
}
})();

const defaultOptions: Pick<ComponentInfo, 'cache'> = {
cache: true,
};

export const purifyOptions = (options: ComponentInfo | string) => {
if (typeof options === 'string') options = { url: options };
return deepMerge(defaultOptions, options || {}) as ComponentInfo;
};
12 changes: 5 additions & 7 deletions packages/runtime/remote-component/src/garfishPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { warn } from '@garfish/utils';
import { interfaces } from '@garfish/core';
import {
preload,
setExternal,
loadComponent,
loadComponentSync,
cacheComponents,
} from './apis';
import { cacheComponents } from './common';
import { preload } from './apis/preload';
import { setExternal } from './apis/setExternal';
import { loadComponent } from './apis/loadComponent';
import { loadComponentSync } from './apis/loadComponentSync';

declare module '@garfish/core' {
export interface Garfish {
Expand Down
12 changes: 5 additions & 7 deletions packages/runtime/remote-component/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { preload } from './apis/preload';
import { setExternal } from './apis/setExternal';
import { loadComponent } from './apis/loadComponent';
import { loadComponentSync } from './apis/loadComponentSync';
import { cacheComponents } from './common';
import { remoteComponentPlugin } from './garfishPlugin';
import {
preload,
setExternal,
loadComponent,
loadComponentSync,
cacheComponents,
} from './apis';

// Micro component loader uses singleton mode
const loader = {
Expand Down
11 changes: 0 additions & 11 deletions packages/runtime/remote-component/src/loader.ts

This file was deleted.

0 comments on commit 4174e14

Please sign in to comment.