Skip to content

Commit e44df67

Browse files
committed
fix: load extend
1 parent 064c6ee commit e44df67

33 files changed

Lines changed: 269 additions & 291 deletions

File tree

package.json

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@eggjs/core",
3-
"version": "6.2.4",
3+
"version": "6.3.0-beta.0",
44
"publishConfig": {
55
"access": "public"
66
},
@@ -12,13 +12,14 @@
1212
},
1313
"description": "A core plugin framework based on @eggjs/koa",
1414
"scripts": {
15+
"clean": "rimraf dist",
1516
"lint": "eslint src test --ext ts",
16-
"pretest": "npm run lint -- --fix && npm run prepublishOnly",
17+
"pretest": "npm run clean && npm run lint -- --fix && npm run prepublishOnly",
1718
"test": "npm run test-local",
1819
"test-local": "egg-bin test",
19-
"preci": "npm run lint && npm run prepublishOnly && attw --pack",
20+
"preci": "npm run clean && npm run lint && npm run prepublishOnly",
2021
"ci": "egg-bin cov",
21-
"prepublishOnly": "tshy && tshy-after"
22+
"prepublishOnly": "tshy && tshy-after && attw --pack"
2223
},
2324
"repository": {
2425
"type": "git",
@@ -37,7 +38,7 @@
3738
"dependencies": {
3839
"@eggjs/koa": "^2.20.2",
3940
"@eggjs/router": "^3.0.5",
40-
"@eggjs/utils": "^4.0.2",
41+
"@eggjs/utils": "^4.1.5",
4142
"egg-logger": "^3.5.0",
4243
"egg-path-matching": "^2.0.0",
4344
"extend2": "^4.0.0",
@@ -52,19 +53,21 @@
5253
},
5354
"devDependencies": {
5455
"@arethetypeswrong/cli": "^0.17.1",
56+
"@eggjs/bin": "^7.0.0",
5557
"@eggjs/tsconfig": "1",
5658
"@types/js-yaml": "4",
5759
"@types/mocha": "10",
5860
"@types/node": "20",
5961
"@types/supertest": "6",
6062
"await-event": "2",
6163
"coffee": "5",
62-
"egg-bin": "6",
6364
"eslint": "8",
6465
"eslint-config-egg": "14",
6566
"gals": "1",
6667
"js-yaml": "3",
6768
"mm": "3",
69+
"pedding": "^2.0.0",
70+
"rimraf": "6",
6871
"supertest": "7",
6972
"ts-node": "10",
7073
"tshy": "3",

src/egg.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,17 +320,17 @@ export class EggCore extends KoaApplication {
320320
* Register a function that will be called when app close.
321321
*
322322
* Notice:
323-
* This method is now NOT recommanded directly used,
323+
* This method is now NOT recommended directly used,
324324
* Developers SHOULDN'T use app.beforeClose directly now,
325325
* but in the form of class to implement beforeClose instead.
326326
*
327327
* @see https://eggjs.org/en/advanced/loader.html#beforeclose
328328
*
329329
* @param {Function} fn - the function that can be generator function or async function.
330330
*/
331-
beforeClose(fn: Fun) {
331+
beforeClose(fn: Fun, name?: string) {
332332
this.deprecate('`beforeClose` was deprecated, please use "Life Cycles" instead, see https://www.eggjs.org/advanced/loader#life-cycles');
333-
this.lifecycle.registerBeforeClose(fn);
333+
this.lifecycle.registerBeforeClose(fn, name);
334334
}
335335

336336
/**

src/lifecycle.ts

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import utils from './utils/index.js';
1010
import type { Fun } from './utils/index.js';
1111
import type { EggCore } from './egg.js';
1212

13-
const debug = debuglog('@eggjs/core:lifecycle');
13+
const debug = debuglog('@eggjs/core/lifecycle');
1414

1515
export interface ILifecycleBoot {
1616
// loader auto set 'fullPath' property on boot class
@@ -62,13 +62,15 @@ export interface LifecycleOptions {
6262
logger: EggConsoleLogger;
6363
}
6464

65+
export type FunWithFullPath = Fun & { fullPath?: string };
66+
6567
export class Lifecycle extends EventEmitter {
6668
#init: boolean;
6769
#readyObject: ReadyObject;
6870
#bootHooks: (BootImplClass | ILifecycleBoot)[];
6971
#boots: ILifecycleBoot[];
7072
#isClosed: boolean;
71-
#closeFunctionSet: Set<Fun>;
73+
#closeFunctionSet: Set<FunWithFullPath>;
7274
loadReady: Ready;
7375
bootReady: Ready;
7476
options: LifecycleOptions;
@@ -96,10 +98,10 @@ export class Lifecycle extends EventEmitter {
9698
this.#initReady();
9799
this
98100
.on('ready_stat', data => {
99-
this.logger.info('[egg:core:ready_stat] end ready task %s, remain %j', data.id, data.remain);
101+
this.logger.info('[@eggjs/core/lifecycle:ready_stat] end ready task %s, remain %j', data.id, data.remain);
100102
})
101103
.on('ready_timeout', id => {
102-
this.logger.warn('[egg:core:ready_timeout] %s seconds later %s was still unable to finish.', this.readyTimeout / 1000, id);
104+
this.logger.warn('[@eggjs/core/lifecycle:ready_timeout] %s seconds later %s was still unable to finish.', this.readyTimeout / 1000, id);
103105
});
104106

105107
this.ready(err => {
@@ -149,37 +151,47 @@ export class Lifecycle extends EventEmitter {
149151
this.#bootHooks.push(bootHootOrBootClass);
150152
}
151153

152-
addFunctionAsBootHook<T = EggCore>(hook: (app: T) => void) {
154+
addFunctionAsBootHook<T = EggCore>(hook: (app: T) => void, fullPath?: string) {
153155
assert(this.#init === false, 'do not add hook when lifecycle has been initialized');
154156
// app.js is exported as a function
155157
// call this function in configDidLoad
156-
this.#bootHooks.push(class Boot implements ILifecycleBoot {
158+
class Boot implements ILifecycleBoot {
159+
static fullPath?: string;
157160
app: T;
158161
constructor(app: T) {
159162
this.app = app;
160163
}
161164
configDidLoad() {
162165
hook(this.app);
163166
}
164-
});
167+
}
168+
Boot.fullPath = fullPath;
169+
this.#bootHooks.push(Boot);
165170
}
166171

167172
/**
168173
* init boots and trigger config did config
169174
*/
170175
init() {
176+
debug('%s init lifecycle', this.app.type);
171177
assert(this.#init === false, 'lifecycle have been init');
172178
this.#init = true;
173179
this.#boots = this.#bootHooks.map(BootHootOrBootClass => {
180+
let instance = BootHootOrBootClass as ILifecycleBoot;
174181
if (isClass(BootHootOrBootClass)) {
175-
return new BootHootOrBootClass(this.app);
182+
instance = new BootHootOrBootClass(this.app);
183+
if (!instance.fullPath && 'fullPath' in BootHootOrBootClass) {
184+
instance.fullPath = BootHootOrBootClass.fullPath as string;
185+
}
176186
}
177-
return BootHootOrBootClass;
187+
debug('[init] add boot instance: %o', instance.fullPath);
188+
return instance;
178189
});
179190
}
180191

181192
registerBeforeStart(scope: Fun, name: string) {
182-
debug('add registerBeforeStart, name: %o', name);
193+
debug('%s add registerBeforeStart, name: %o',
194+
this.options.app.type, name);
183195
this.#registerReadyCallback({
184196
scope,
185197
ready: this.loadReady,
@@ -188,16 +200,24 @@ export class Lifecycle extends EventEmitter {
188200
});
189201
}
190202

191-
registerBeforeClose(fn: Fun) {
203+
registerBeforeClose(fn: FunWithFullPath, fullPath?: string) {
192204
assert(typeof fn === 'function', 'argument should be function');
193205
assert(this.#isClosed === false, 'app has been closed');
206+
if (fullPath) {
207+
fn.fullPath = fullPath;
208+
}
194209
this.#closeFunctionSet.add(fn);
210+
debug('%s register beforeClose at %o, count: %d',
211+
this.app.type, fullPath, this.#closeFunctionSet.size);
195212
}
196213

197214
async close() {
198215
// close in reverse order: first created, last closed
199216
const closeFns = Array.from(this.#closeFunctionSet);
217+
debug('%s start trigger %d beforeClose functions',
218+
this.app.type, closeFns.length);
200219
for (const fn of closeFns.reverse()) {
220+
debug('%s trigger beforeClose at %o', this.app.type, fn.fullPath);
201221
await utils.callFn(fn);
202222
this.#closeFunctionSet.delete(fn);
203223
}
@@ -206,12 +226,14 @@ export class Lifecycle extends EventEmitter {
206226
this.removeAllListeners();
207227
this.app.removeAllListeners();
208228
this.#isClosed = true;
229+
debug('%s closed', this.app.type);
209230
}
210231

211232
triggerConfigWillLoad() {
212233
debug('trigger configWillLoad start');
213234
for (const boot of this.#boots) {
214235
if (typeof boot.configWillLoad === 'function') {
236+
debug('trigger configWillLoad at %o', boot.fullPath);
215237
boot.configWillLoad();
216238
}
217239
}
@@ -223,12 +245,13 @@ export class Lifecycle extends EventEmitter {
223245
debug('trigger configDidLoad start');
224246
for (const boot of this.#boots) {
225247
if (typeof boot.configDidLoad === 'function') {
248+
debug('trigger configDidLoad at %o', boot.fullPath);
226249
boot.configDidLoad();
227250
}
228251
// function boot hook register after configDidLoad trigger
229252
if (typeof boot.beforeClose === 'function') {
230253
const beforeClose = boot.beforeClose.bind(boot);
231-
this.registerBeforeClose(beforeClose);
254+
this.registerBeforeClose(beforeClose, boot.fullPath);
232255
}
233256
}
234257
debug('trigger configDidLoad end');
@@ -274,10 +297,12 @@ export class Lifecycle extends EventEmitter {
274297
return (async () => {
275298
for (const boot of this.#boots) {
276299
if (typeof boot.didReady === 'function') {
300+
debug('trigger didReady at %o', boot.fullPath);
277301
try {
278302
await boot.didReady(err);
279-
} catch (e) {
280-
this.emit('error', e);
303+
} catch (err) {
304+
debug('trigger didReady error at %o, error: %s', boot.fullPath, err);
305+
this.emit('error', err);
281306
}
282307
}
283308
}
@@ -292,9 +317,11 @@ export class Lifecycle extends EventEmitter {
292317
if (typeof boot.serverDidReady !== 'function') {
293318
continue;
294319
}
320+
debug('trigger serverDidReady at %o', boot.fullPath);
295321
try {
296322
await boot.serverDidReady();
297323
} catch (err) {
324+
debug('trigger serverDidReady error at %o, error: %s', boot.fullPath, err);
298325
this.emit('error', err);
299326
}
300327
}

src/loader/egg_loader.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ export class EggLoader {
781781
const pluginPkgFile = utils.resolvePath(`${name}/package.json`, { paths: [ ...this.lookupDirs ] });
782782
return path.dirname(pluginPkgFile);
783783
} catch (err) {
784-
debug('[resolvePluginPath] error: %o', err);
784+
debug('[resolvePluginPath] error: %o, plugin info: %o', err, plugin);
785785
throw new Error(`Can not find plugin ${name} in "${[ ...this.lookupDirs ].join(', ')}"`, {
786786
cause: err,
787787
});
@@ -1166,19 +1166,23 @@ export class EggLoader {
11661166
async #loadBootHook(fileName: string) {
11671167
this.timing.start(`Load ${fileName}.js`);
11681168
for (const unit of this.getLoadUnits()) {
1169-
const bootFilePath = this.resolveModule(path.join(unit.path, fileName));
1169+
const bootFile = path.join(unit.path, fileName);
1170+
const bootFilePath = this.resolveModule(bootFile);
11701171
if (!bootFilePath) {
1172+
// debug('[loadBootHook] %o not found', bootFile);
11711173
continue;
11721174
}
11731175
const bootHook = await this.requireFile(bootFilePath);
11741176
if (isClass(bootHook)) {
11751177
bootHook.prototype.fullPath = bootFilePath;
11761178
// if is boot class, add to lifecycle
11771179
this.lifecycle.addBootHook(bootHook);
1180+
debug('[loadBootHook] add BootHookClass from %o', bootFilePath);
11781181
} else if (typeof bootHook === 'function') {
11791182
// if is boot function, wrap to class
11801183
// for compatibility
1181-
this.lifecycle.addFunctionAsBootHook(bootHook);
1184+
this.lifecycle.addFunctionAsBootHook(bootHook, bootFilePath);
1185+
debug('[loadBootHook] add bootHookFunction from %o', bootFilePath);
11821186
} else {
11831187
this.options.logger.warn('[@eggjs/core:egg_loader] %s must exports a boot class', bootFilePath);
11841188
}
@@ -1595,13 +1599,13 @@ export class EggLoader {
15951599
let fullPath;
15961600
try {
15971601
fullPath = utils.resolvePath(filepath);
1598-
} catch (e) {
1599-
return undefined;
1600-
}
1601-
1602-
if (process.env.EGG_TYPESCRIPT !== 'true' && fullPath.endsWith('.ts')) {
1602+
} catch (err: any) {
1603+
// debug('[resolveModule] Module %o resolve error: %s', filepath, err.stack);
16031604
return undefined;
16041605
}
1606+
// if (process.env.EGG_TYPESCRIPT !== 'true' && fullPath.endsWith('.ts')) {
1607+
// return undefined;
1608+
// }
16051609
return fullPath;
16061610
}
16071611
}

0 commit comments

Comments
 (0)