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
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 = () => { // module -> importName -> updater[]
_rootImportsMap.set('react', new Map(Object.entries(React))); export const _rootImportsMap = new Map<string, Map<string, any>>();
_rootImportsMap.set( const rootImportsMapSetupPromise = setupImportsMap(_rootImportsMap, {
'react/jsx-runtime', react: import('react'),
new Map(Object.entries(ReactJSXRuntime)) 'react/jsx-runtime': import('react/jsx-runtime'),
); 'react-dom': import('react-dom'),
_rootImportsMap.set('react-dom', new Map(Object.entries(ReactDom))); 'react-dom/client': import('react-dom/client'),
_rootImportsMap.set( jotai: import('jotai'),
'react-dom/client', 'jotai/utils': import('jotai/utils'),
new Map(Object.entries(ReactDomClient)) swr: import('swr'),
); '@affine/component': import('@affine/component'),
_rootImportsMap.set('@blocksuite/icons', new Map(Object.entries(Icons))); '@blocksuite/icons': import('@blocksuite/icons'),
_rootImportsMap.set( '@affine/sdk/entry': {
'@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, rootStore: rootStore,
currentWorkspaceAtom: currentWorkspaceAtom, currentWorkspaceAtom: currentWorkspaceAtom,
currentPageAtom: currentPageAtom, currentPageAtom: currentPageAtom,
contentLayoutAtom: contentLayoutAtom, contentLayoutAtom: contentLayoutAtom,
}) },
) '@blocksuite/blocks/std': import('@blocksuite/blocks/std'),
); '@blocksuite/global/utils': import('@blocksuite/global/utils'),
_rootImportsMap.set('swr', new Map(Object.entries(SWR))); '@toeverything/infra/atom': import('@toeverything/infra/atom'),
}; });
// module -> importName -> updater[]
export const _rootImportsMap = new Map<string, Map<string, any>>();
setupRootImportsMap();
// 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: {