Skip to content

Commit

Permalink
perf: add VueDemi as default globalVariables
Browse files Browse the repository at this point in the history
  • Loading branch information
hubert committed Dec 30, 2024
1 parent 8be9c7b commit 7fc7d95
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 30 deletions.
8 changes: 5 additions & 3 deletions packages/module-loader/src/core/componentLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { promisify } from '../utils/promisify';

// Types
import { isVue2, Vue2, App, Component } from 'vue-demi';
import { ModuleLoader } from '../types';
import { Resolver } from '../types';

/** 验证组件导出是否正确 */
function validateExportComponent(exports: any) {
Expand Down Expand Up @@ -48,12 +48,14 @@ function getComponentFromExport(scriptExports: any, componentName: string, globa
* create module loader
* @param resolver resolver
*/
export function createComponentLoader(App: App | typeof Vue2, resolver: ModuleLoader['resolver']) {
export function createComponentLoader<Context>(App: App | typeof Vue2, resolver: Resolver<Context>) {
return async function loader<T = any>(
componentName: string,
src: string,
styles?: string | string[],
): Promise<Component<T>> {
const context = resolver.getContext();

// load styles
if (styles) {
if (typeof styles === 'string') {
Expand All @@ -64,6 +66,6 @@ export function createComponentLoader(App: App | typeof Vue2, resolver: ModuleLo

// exec script
const scriptExports = await promisify(resolver.execScript<object>(src));
return getComponentFromExport(scriptExports, componentName, resolver.context);
return getComponentFromExport(scriptExports, componentName, context);
};
}
9 changes: 5 additions & 4 deletions packages/module-loader/src/core/moduleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
InnerRegisterSubModule,
Lifecycle,
RegisterProperties,
ModuleLoader,
Resolver,
} from '../types';
import { Bootstrap, Mount, Unmount } from '../sub/types';

Expand Down Expand Up @@ -74,7 +74,7 @@ function execLifecycle(lifecycles: Lifecycle | Lifecycle[], module: InnerRegistr
* @param App instance from 'createApp' in Vue3, Vue constructor in Vue2
* @param resolver resolver
*/
export function createModuleLoader(App: App | typeof Vue2, resolver: ModuleLoader['resolver']) {
export function createModuleLoader<Context>(App: App | typeof Vue2, resolver: Resolver<Context>) {
return function loader(
/**
* @internal
Expand All @@ -92,7 +92,8 @@ export function createModuleLoader(App: App | typeof Vue2, resolver: ModuleLoade
},
): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const _self = this;
const _self = this,
context = resolver.getContext();

return new Promise((resolve) => {
// 按顺序同步执行
Expand Down Expand Up @@ -169,7 +170,7 @@ export function createModuleLoader(App: App | typeof Vue2, resolver: ModuleLoade
bootstrap,
mount: exportMount,
unmount: exportUnmount,
} = getLifecyclesFromExports(scriptExports, name, resolver.context);
} = getLifecyclesFromExports(scriptExports, name, context);
// bootstrap only exec in the first time
await promisify(bootstrap?.call(_self, App));
// exec in unmount
Expand Down
18 changes: 12 additions & 6 deletions packages/module-loader/src/createLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T
* create module loader
*/
export function createLoader<Props extends Record<string, any> = any, Context = any>(
options: XOR<
options: {
globalVariables?: Record<string, any>;
} & XOR<
{
/**
* remote module resolver, default to umd resolver
Expand All @@ -24,17 +26,21 @@ export function createLoader<Props extends Record<string, any> = any, Context =
ResolverCreatorOptions<WindowProxy>
> = {},
) {
const { resolver, ...resolverOptions } = options;
const _resolver = resolver ?? (createUmdResolver(resolverOptions) as Resolver<any>);
const { resolver: customResolver, globalVariables, ...resolverOptions } = options;
const resolver = customResolver ?? (createUmdResolver(resolverOptions) as Resolver<any>);
resolver.setGlobalVariables({
...globalVariables,
VueDemi,
});

const loader: ModuleLoader<Props, Context> = VueDemi.markRaw({
install(app) {
// this allows calling registerSubModules() outside of a component setup after
setActiveLoader(loader);

if (!VueDemi.isVue2) {
const moduleLoader = createModuleLoader(app, _resolver);
const componentLoader = createComponentLoader(app, _resolver);
const moduleLoader = createModuleLoader(app, resolver);
const componentLoader = createComponentLoader(app, resolver);

loader._a = app;
loader._moduleLoader = moduleLoader;
Expand All @@ -55,7 +61,7 @@ export function createLoader<Props extends Record<string, any> = any, Context =
removeErrorHandler.call(null, handler);
return this;
},
resolver: Object.freeze(_resolver),
resolver: Object.freeze(resolver),
// it's actually undefined here
// @ts-expect-error set in install when using Vue 3
_a: null,
Expand Down
14 changes: 8 additions & 6 deletions packages/module-loader/src/resolvers/cjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import { Context as vmContext } from 'vm';
import { ClientRequest, IncomingMessage } from 'http';
import { ResolverCreatorOptions, Resolver } from '../types';

function createSandbox(globalVariables: Record<string, any> = {}) {
function createSandbox() {
const sandbox: Record<string, any> = {
...globalVariables,
Buffer: Buffer,
require: require,
console: console,
Expand All @@ -24,7 +23,7 @@ function createSandbox(globalVariables: Record<string, any> = {}) {
sandbox.exports = {};
sandbox.module = {};

return {};
return sandbox;
}

function tryGetCwd(path: any) {
Expand All @@ -44,10 +43,13 @@ function tryGetCwd(path: any) {
return cwd;
}

export function createCjsResolver({ globalVariables }: ResolverCreatorOptions): Resolver<vmContext> {
const proxy = createSandbox(globalVariables);
export function createCjsResolver(_: ResolverCreatorOptions): Resolver<vmContext> {
const proxy = createSandbox();
return {
context: proxy,
getContext: () => proxy,
setGlobalVariables(variables) {
proxy.global = { ...proxy.global, ...variables };
},
execScript(entry) {
return new Promise((resolve, reject) => {
const http = require('http');
Expand Down
11 changes: 6 additions & 5 deletions packages/module-loader/src/resolvers/umd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,21 @@ function noteGlobalProps(global: WindowProxy) {
const scriptsCache = new Map<string, any>();
const stylesCache = new Map<string, HTMLLinkElement>();

function createSandbox(globalVariables: Record<string, any> = {}) {
function createSandbox() {
// TODO: load in sandbox
const global: WindowProxy = window;
Object.assign(global, globalVariables);
return global;
}

export function createUmdResolver({
container = (proxy) => proxy.document.body,
globalVariables,
}: ResolverCreatorOptions): Resolver<WindowProxy> {
const proxy = createSandbox(globalVariables);
const proxy = createSandbox();
return {
context: proxy,
getContext: () => proxy,
setGlobalVariables(variables) {
Object.assign(proxy, variables);
},
execScript(entry) {
if (scriptsCache.has(entry)) return Promise.resolve(scriptsCache.get(entry)); // 从 catch 中获取

Expand Down
13 changes: 7 additions & 6 deletions packages/module-loader/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,14 @@ export type ErrorHandler = (error: Error, module: InnerRegistrableModule) => voi
*/
export interface Resolver<Context = any> {
/**
* execution context
* get execution context
*/
context: Context;
getContext: () => Context;
/**
* set global variables to extend to resolver context
* @param variables global variables
*/
setGlobalVariables(variables: Record<string, any>): void;
/**
* execute script
* @param entry remote script src
Expand All @@ -240,8 +245,4 @@ export interface ResolverCreatorOptions<Context = any> {
* container container to append script, default is append to body in client side
*/
container?: string | ((proxy: Context) => Element);
/**
* global variables to extend to resolver context
*/
globalVariables?: Record<string, any>;
}

0 comments on commit 7fc7d95

Please sign in to comment.