Skip to content

Commit b9711d1

Browse files
committed
feat: add code
1 parent fd06e52 commit b9711d1

File tree

10 files changed

+53
-114
lines changed

10 files changed

+53
-114
lines changed

packages/runtime/core/src/garfish.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ export class Garfish implements interfaces.Garfish {
3333
public channel = new EventEmitter();
3434
public options = createDefaultOptions();
3535
public externals: Record<string, any> = {};
36+
public appInfos: Record<string, interfaces.AppInfo> = {};
3637
public activeApps: Array<interfaces.App> = [];
3738
public cacheApps: Record<string, interfaces.App> = {};
38-
public appInfos: Record<string, interfaces.AppInfo> = {};
3939

40-
private allApps: WeakSet<interfaces.App> = new WeakSet();
40+
private registeredPlugins = new WeakSet();
4141
private loading: Record<string, Promise<any> | null> = {};
4242

4343
get props(): Record<string, any> {
@@ -110,14 +110,24 @@ export class Garfish implements interfaces.Garfish {
110110
...args: Array<any>
111111
) {
112112
assert(typeof plugin === 'function', 'Plugin must be a function.');
113-
if ((plugin as any)._registered) {
113+
if (this.registeredPlugins.has(plugin)) {
114114
__DEV__ && warn('Please do not register the plugin repeatedly.');
115115
return this;
116116
}
117-
(plugin as any)._registered = true;
118-
const allHooks = plugin.apply(this, [this, ...args]);
119-
// Distinguish between xx and xxx, in order to be compatible with the old api
120-
return this.hooks.usePlugin(allHooks);
117+
this.registeredPlugins.add(plugin);
118+
const pluginConfig = plugin.apply(this, [this, ...args]);
119+
120+
// Register app hooks, Compatible with the old api
121+
this.activeApps.forEach((app) => app.hooks.usePlugin(pluginConfig));
122+
for (const key in this.cacheApps) {
123+
const app = this.cacheApps[key];
124+
if (!this.activeApps.includes(app)) {
125+
app.hooks.usePlugin(pluginConfig);
126+
}
127+
}
128+
// Register global hooks
129+
this.hooks.usePlugin(pluginConfig);
130+
return this;
121131
}
122132

123133
run(options?: interfaces.Options) {
@@ -204,6 +214,7 @@ export class Garfish implements interfaces.Garfish {
204214
} else {
205215
this.externals[nameOrExtObj] = value;
206216
}
217+
return this;
207218
}
208219

209220
async loadApp(
@@ -270,8 +281,9 @@ export class Garfish implements interfaces.Garfish {
270281
this.options.customLoader,
271282
);
272283

273-
this.allApps.add(appInstance);
274-
this.cacheApps[appName] = appInstance;
284+
if (appInfo.cache) {
285+
this.cacheApps[appName] = appInstance;
286+
}
275287
} catch (e) {
276288
__DEV__ && error(e);
277289
this.hooks.lifecycle.errorLoadApp.emit(e, appInfo);
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
import { assert, isObject } from '@garfish/utils';
21
import { SyncHook, AsyncHook } from '@garfish/hooks';
2+
import { assert, isPlainObject } from '@garfish/utils';
33

44
type Plugin<T> = Partial<Record<keyof T, (...args: Array<any>) => void>> & {
55
name: string;
66
};
77

88
export class HooksSystem<T extends Record<string, SyncHook | AsyncHook>> {
9-
type: string;
109
lifecycle: T;
1110
lifecycleKeys: Array<keyof T>;
1211
private registerPlugins = new WeakSet<Plugin<T>>();
1312

14-
constructor(type: string, lifecycle: T) {
15-
this.type = type;
13+
constructor(lifecycle: T) {
1614
this.lifecycle = lifecycle;
1715
this.lifecycleKeys = Object.keys(lifecycle);
1816
}
@@ -21,7 +19,7 @@ export class HooksSystem<T extends Record<string, SyncHook | AsyncHook>> {
2119
// Plugin name is required and unique
2220
const pluginName = plugin.name;
2321
assert(pluginName, 'Plugin must provide a name');
24-
assert(isObject(plugin), 'Plugin must return object type.');
22+
assert(isPlainObject(plugin), 'Plugin must return object type.');
2523

2624
if (!this.registerPlugins.has(plugin)) {
2725
this.registerPlugins.add(plugin);
@@ -30,17 +28,16 @@ export class HooksSystem<T extends Record<string, SyncHook | AsyncHook>> {
3028
const pluginLife = plugin[key as string];
3129
if (pluginLife) {
3230
// Differentiate different types of hooks and adopt different registration strategies
33-
this.lifecycle[key].on(pluginName, pluginLife);
31+
this.lifecycle[key].on(pluginLife);
3432
}
3533
}
3634
}
3735
}
3836

3937
removePlugin(plugin: Plugin<T>) {
40-
const pluginName = plugin.name;
41-
assert(pluginName, 'Plugin must provide a name');
42-
for (const key in this.lifecycle) {
43-
this.lifecycle[key].remove(pluginName, plugin[key as string]);
38+
assert(isPlainObject(plugin), 'Invalid plugin configuration');
39+
for (const key in plugin) {
40+
this.lifecycle[key].remove(plugin[key as string]);
4441
}
4542
}
4643
}

packages/runtime/core/src/hooks/lifecycle.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@ import { HooksSystem } from './hooksSystem';
22
import { SyncHook, AsyncHook } from '@garfish/hooks';
33

44
export function globalLifecycle() {
5-
const hooks = {
5+
return new HooksSystem({
66
beforeBootstrap: new SyncHook(),
77
bootstrap: new SyncHook(),
88
beforeRegisterApp: new SyncHook(),
99
registerApp: new SyncHook(),
1010
beforeLoad: new AsyncHook(),
1111
afterLoad: new SyncHook(),
1212
errorLoadApp: new SyncHook(),
13-
};
14-
return new HooksSystem('global', hooks);
13+
});
1514
}
1615

1716
export function appLifecycle() {
18-
const hooks = {
17+
return new HooksSystem({
1918
beforeEval: new SyncHook(),
2019
afterEval: new SyncHook(),
2120
beforeMount: new SyncHook(),
@@ -25,6 +24,5 @@ export function appLifecycle() {
2524
errorMountApp: new SyncHook(),
2625
errorUnmountApp: new SyncHook(),
2726
errorExecCode: new SyncHook(),
28-
};
29-
return new HooksSystem('app', hooks);
27+
});
3028
}

packages/runtime/hooks/src/asyncHook.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { SyncHook } from './syncHook';
22

33
export class AsyncHook extends SyncHook {
44
emit(...data: Array<any>) {
5-
const hs = this.hooks;
6-
if (hs.length > 0) {
5+
const ls = Array.from(this.listeners);
6+
if (ls.length > 0) {
77
let i = 0;
88
const call = (stop?: any) => {
9-
if (stop !== false && i < hs.length) {
10-
const result = hs[i++].fn.apply(null, data);
9+
if (stop !== false && i < ls.length) {
10+
const result = ls[i++].apply(null, data);
1111
return Promise.resolve(result).then(call);
1212
}
1313
};

packages/runtime/hooks/src/channel.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

packages/runtime/hooks/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
export { Channel } from './channel';
21
export { SyncHook } from './syncHook';
32
export { AsyncHook } from './asyncHook';
43
export { LoaderPlugin } from './loaderPlugin';

packages/runtime/hooks/src/syncHook.ts

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,40 @@ import { warn } from '@garfish/utils';
33
type Callback = (...args: Array<any>) => void;
44

55
export class SyncHook {
6-
public type: string = '';
7-
public hooks: Array<{ name: string; fn: Callback }> = [];
6+
type: string = '';
7+
listeners = new Set<Callback>();
88

99
constructor(type?: string) {
1010
if (type) this.type = type;
1111
}
1212

13-
on(name: string, fn: Callback) {
14-
if (typeof name === 'string' && typeof fn === 'function') {
15-
this.hooks.push({ name, fn });
13+
on(fn: Callback) {
14+
if (typeof fn === 'function') {
15+
this.listeners.add(fn);
1616
} else if (__DEV__) {
1717
warn('Invalid parameter');
1818
}
1919
}
2020

21-
once(name: string, fn: Callback) {
21+
once(fn: Function) {
2222
const self = this;
23-
this.on(name, function wrapper(...args: Array<any>) {
24-
self.remove(name, wrapper);
23+
this.on(function wrapper(...args: Array<any>) {
24+
self.remove(wrapper);
2525
fn(...args);
2626
});
2727
}
2828

2929
emit(...data: Array<any>) {
30-
if (this.hooks.length > 0) {
31-
this.hooks.forEach((hook) => hook.fn.apply(null, data));
30+
if (this.listeners.size > 0) {
31+
this.listeners.forEach((fn) => fn.apply(null, data));
3232
}
3333
}
3434

35-
remove(name: string, fn: Callback) {
36-
for (let i = 0; i < this.hooks.length; i++) {
37-
const hook = this.hooks[i];
38-
if (name === hook.name) {
39-
if (fn && fn !== hook.fn) {
40-
continue;
41-
}
42-
this.hooks.splice(i, 1);
43-
i--;
44-
}
45-
}
35+
remove(fn: Callback) {
36+
return this.listeners.delete(fn);
4637
}
4738

4839
removeAll() {
49-
this.hooks.length = 0;
40+
this.listeners.clear();
5041
}
5142
}

rollup.config.js

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,21 +114,19 @@ function allExternal() {
114114
}
115115

116116
function extractTsDeclare() {
117-
let outputoptions;
118117
let pkgDir = '';
119118
let pkgName = '';
120119
return {
121120
name: 'garfish-extractTsDeclare',
122121
options(op) {
123-
outputoptions = op;
124122
pkgDir = op.input.replace('/src/index.ts', '');
125-
let splitPkg = pkgDir.split('/');
123+
const splitPkg = pkgDir.split('/');
126124
pkgName = splitPkg[splitPkg.length - 1];
127125
},
128126
writeBundle() {
129127
if (!pkgName) return;
130128

131-
let tsTypeDir = path.resolve(
129+
const tsTypeDir = path.resolve(
132130
pkgDir,
133131
`dist/packages/runtime/${pkgName}/src`,
134132
);
@@ -137,21 +135,12 @@ function extractTsDeclare() {
137135
if (!fs.existsSync(tsTypeDir)) return;
138136
fs.copySync(
139137
path.resolve(pkgDir, tsTypeDir),
140-
path.resolve(pkgDir, `dist/`),
138+
path.resolve(pkgDir, 'dist/'),
141139
{
142140
overwrite: true,
143141
},
144142
);
145143
}, 1000);
146-
// setTimeout(() => {
147-
// const args = require('minimist')(process.argv.slice(2));
148-
// const watch = args.watch || args.w;
149-
// // if (!watch) {
150-
// fs.remove(path.resolve(pkgDir, `dist/packages`));
151-
// fs.remove(path.resolve(pkgDir, `dist/dist`));
152-
// fs.remove(path.resolve(pkgDir, `temp`));
153-
// // }
154-
// }, 3000);
155144
},
156145
};
157146
}

scripts/build.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ run();
3131
async function run() {
3232
const buildAll = async (targets) => {
3333
for (const target of targets) {
34-
// watch mode can't await
35-
if (target.indexOf('hooks') !== -1) continue;
3634
if (watch) {
3735
build(target);
3836
} else {

scripts/publish.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
const path = require('path');
2-
const os = require('os');
31
const lernaPublish = require('@lerna/publish');
42

53
const opts = {
@@ -17,8 +15,7 @@ const opts = {
1715
};
1816

1917
function publish(canary) {
20-
// eslint-disable-next-line no-console
21-
console.log(`publish ${canary ? `测试版本` : `正式版本`}\n`);
18+
console.log(`publish ${canary ? '测试版本' : '正式版本'}\n`);
2219

2320
return lernaPublish({
2421
...opts,

0 commit comments

Comments
 (0)