feat(infra): lazy load plugin modules (#3604)

This commit is contained in:
Alex Yang 2023-08-07 13:06:44 -04:00 committed by GitHub
parent d9f323874d
commit 6d01495bc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 53 deletions

View File

@ -0,0 +1,22 @@
type ExportsPromiseOrExports =
| Promise<{ [key: string]: any }>
| { [key: string]: any };
export async function setupImportsMap(
map: Map<string, Map<string, any>>,
imports: Record<string, ExportsPromiseOrExports>
) {
for (const [key, value] of Object.entries(imports)) {
let module: { [key: string]: any };
if (value instanceof Promise) {
module = await value;
} else {
module = value;
}
const moduleMap = new Map();
map.set(key, moduleMap);
for (const [exportName, exportValue] of Object.entries(module)) {
moduleMap.set(exportName, exportValue);
}
}
}

View File

@ -1,12 +1,8 @@
import * as AFFiNEComponent from '@affine/component';
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import type { CallbackMap, PluginContext } from '@affine/sdk/entry'; import type { CallbackMap, PluginContext } from '@affine/sdk/entry';
import { FormatQuickBar } from '@blocksuite/blocks'; import { FormatQuickBar } from '@blocksuite/blocks';
import * as BlockSuiteBlocksStd from '@blocksuite/blocks/std';
import * as BlockSuiteGlobalUtils from '@blocksuite/global/utils';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
import { DisposableGroup } from '@blocksuite/global/utils'; import { DisposableGroup } from '@blocksuite/global/utils';
import * as Icons from '@blocksuite/icons';
import { import {
contentLayoutAtom, contentLayoutAtom,
currentPageAtom, currentPageAtom,
@ -17,67 +13,41 @@ import {
settingItemsAtom, settingItemsAtom,
windowItemsAtom, windowItemsAtom,
} from '@toeverything/infra/atom'; } from '@toeverything/infra/atom';
import * as Jotai from 'jotai/index';
import { Provider } from 'jotai/react'; import { Provider } from 'jotai/react';
import * as JotaiUtils from 'jotai/utils';
import * as React from 'react';
import { createElement, type PropsWithChildren } from 'react'; import { createElement, type PropsWithChildren } from 'react';
import * as ReactJSXRuntime from 'react/jsx-runtime';
import * as ReactDom from 'react-dom';
import * as ReactDomClient from 'react-dom/client';
import * as SWR from 'swr';
import { createFetch } from './endowments/fercher'; import { createFetch } from './endowments/fercher';
import { createTimers } from './endowments/timer'; import { createTimers } from './endowments/timer';
import { setupImportsMap } from './setup-imports-map';
const dynamicImportKey = '$h_import'; const dynamicImportKey = '$h_import';
const permissionLogger = new DebugLogger('plugins:permission'); const permissionLogger = new DebugLogger('plugins:permission');
const importLogger = new DebugLogger('plugins:import'); const importLogger = new DebugLogger('plugins:import');
const setupRootImportsMap = () => {
_rootImportsMap.set('react', new Map(Object.entries(React)));
_rootImportsMap.set(
'react/jsx-runtime',
new Map(Object.entries(ReactJSXRuntime))
);
_rootImportsMap.set('react-dom', new Map(Object.entries(ReactDom)));
_rootImportsMap.set(
'react-dom/client',
new Map(Object.entries(ReactDomClient))
);
_rootImportsMap.set('@blocksuite/icons', new Map(Object.entries(Icons)));
_rootImportsMap.set(
'@affine/component',
new Map(Object.entries(AFFiNEComponent))
);
_rootImportsMap.set(
'@blocksuite/blocks/std',
new Map(Object.entries(BlockSuiteBlocksStd))
);
_rootImportsMap.set(
'@blocksuite/global/utils',
new Map(Object.entries(BlockSuiteGlobalUtils))
);
_rootImportsMap.set('jotai', new Map(Object.entries(Jotai)));
_rootImportsMap.set('jotai/utils', new Map(Object.entries(JotaiUtils)));
_rootImportsMap.set(
'@affine/sdk/entry',
new Map(
Object.entries({
rootStore: rootStore,
currentWorkspaceAtom: currentWorkspaceAtom,
currentPageAtom: currentPageAtom,
contentLayoutAtom: contentLayoutAtom,
})
)
);
_rootImportsMap.set('swr', new Map(Object.entries(SWR)));
};
// module -> importName -> updater[] // module -> importName -> updater[]
export const _rootImportsMap = new Map<string, Map<string, any>>(); export const _rootImportsMap = new Map<string, Map<string, any>>();
setupRootImportsMap(); const rootImportsMapSetupPromise = setupImportsMap(_rootImportsMap, {
react: import('react'),
'react/jsx-runtime': import('react/jsx-runtime'),
'react-dom': import('react-dom'),
'react-dom/client': import('react-dom/client'),
jotai: import('jotai'),
'jotai/utils': import('jotai/utils'),
swr: import('swr'),
'@affine/component': import('@affine/component'),
'@blocksuite/icons': import('@blocksuite/icons'),
'@affine/sdk/entry': {
rootStore: rootStore,
currentWorkspaceAtom: currentWorkspaceAtom,
currentPageAtom: currentPageAtom,
contentLayoutAtom: contentLayoutAtom,
},
'@blocksuite/blocks/std': import('@blocksuite/blocks/std'),
'@blocksuite/global/utils': import('@blocksuite/global/utils'),
'@toeverything/infra/atom': import('@toeverything/infra/atom'),
});
// pluginName -> module -> importName -> updater[] // pluginName -> module -> importName -> updater[]
export const _pluginNestedImportsMap = new Map< export const _pluginNestedImportsMap = new Map<
string, string,
@ -213,6 +183,7 @@ export const createOrGetGlobalThis = (
Object.create(null), Object.create(null),
sharedGlobalThis, sharedGlobalThis,
{ {
// fixme: vite build output bundle will have this, we should remove it
process: Object.freeze({ process: Object.freeze({
env: { env: {
NODE_ENV: process.env.NODE_ENV, NODE_ENV: process.env.NODE_ENV,
@ -319,6 +290,7 @@ export const setupPluginCode = async (
pluginName: string, pluginName: string,
filename: string filename: string
) => { ) => {
await rootImportsMapSetupPromise;
if (!_pluginNestedImportsMap.has(pluginName)) { if (!_pluginNestedImportsMap.has(pluginName)) {
_pluginNestedImportsMap.set(pluginName, new Map()); _pluginNestedImportsMap.set(pluginName, new Map());
} }

View File

@ -144,7 +144,7 @@ await build({
build: { build: {
watch: isWatch ? {} : undefined, watch: isWatch ? {} : undefined,
minify: false, minify: false,
target: 'es2020', target: 'esnext',
outDir: coreOutDir, outDir: coreOutDir,
emptyOutDir: true, emptyOutDir: true,
lib: { lib: {