diff --git a/src/loader/egg_loader.ts b/src/loader/egg_loader.ts index 4f2fe1c4..5f2ef4cc 100644 --- a/src/loader/egg_loader.ts +++ b/src/loader/egg_loader.ts @@ -2,8 +2,8 @@ import fs from 'node:fs'; import path from 'node:path'; import assert from 'node:assert'; import { debuglog, inspect } from 'node:util'; -import { isAsyncFunction, isClass, isGeneratorFunction, isObject } from 'is-type-of'; import { homedir } from 'node-homedir'; +import { isAsyncFunction, isClass, isGeneratorFunction, isObject, isPromise } from 'is-type-of'; import type { Logger } from 'egg-logger'; import { getParamNames, readJSONSync, readJSON } from 'utility'; import { extend } from 'extend2'; @@ -1447,6 +1447,9 @@ export class EggLoader { let mod = await this.requireFile(fullpath); if (typeof mod === 'function' && !isClass(mod)) { mod = mod(...inject); + if (isPromise(mod)) { + mod = await mod; + } } return mod; } diff --git a/test/fixtures/load_file/async.js b/test/fixtures/load_file/async.js new file mode 100644 index 00000000..1e36c648 --- /dev/null +++ b/test/fixtures/load_file/async.js @@ -0,0 +1,5 @@ +"use strict"; + +module.exports = async () => { + return { clients: "Test Config" }; +}; diff --git a/test/fixtures/load_file/es-module-default-async.js b/test/fixtures/load_file/es-module-default-async.js new file mode 100644 index 00000000..4c3109c3 --- /dev/null +++ b/test/fixtures/load_file/es-module-default-async.js @@ -0,0 +1,5 @@ +"use strict"; +exports.__esModule = true; +exports["default"] = async function () { + return { clients: "Test Config" }; +}; diff --git a/test/fixtures/load_file/es-module-default-null.js b/test/fixtures/load_file/es-module-default-null.js new file mode 100644 index 00000000..fb3c8922 --- /dev/null +++ b/test/fixtures/load_file/es-module-default-null.js @@ -0,0 +1,3 @@ +"use strict"; +exports.__esModule = true; +exports["default"] = null; diff --git a/test/fixtures/load_file/es-module-default-promise.js b/test/fixtures/load_file/es-module-default-promise.js new file mode 100644 index 00000000..ed59b0e4 --- /dev/null +++ b/test/fixtures/load_file/es-module-default-promise.js @@ -0,0 +1,5 @@ +"use strict"; +exports.__esModule = true; +exports["default"] = function () { + return Promise.resolve({ clients: "Test Config" }); +}; diff --git a/test/fixtures/load_file/es-module-default.js b/test/fixtures/load_file/es-module-default.js new file mode 100644 index 00000000..665cac36 --- /dev/null +++ b/test/fixtures/load_file/es-module-default.js @@ -0,0 +1,5 @@ +"use strict"; +exports.__esModule = true; +exports["default"] = { + fn() {} +}; diff --git a/test/fixtures/load_file/promise_function.js b/test/fixtures/load_file/promise_function.js new file mode 100644 index 00000000..4811525c --- /dev/null +++ b/test/fixtures/load_file/promise_function.js @@ -0,0 +1,3 @@ +module.exports = function () { + return Promise.resolve({ clients: "Test Config" }); +}; diff --git a/test/fixtures/loadfile-esm/es-module-default-async.js b/test/fixtures/loadfile-esm/es-module-default-async.js new file mode 100644 index 00000000..22b2d681 --- /dev/null +++ b/test/fixtures/loadfile-esm/es-module-default-async.js @@ -0,0 +1,4 @@ +"use strict"; +export default async function () { + return { clients: "Test Config" }; +}; diff --git a/test/fixtures/loadfile-esm/es-module-default-promise.js b/test/fixtures/loadfile-esm/es-module-default-promise.js new file mode 100644 index 00000000..46338176 --- /dev/null +++ b/test/fixtures/loadfile-esm/es-module-default-promise.js @@ -0,0 +1,4 @@ +"use strict"; +export default function () { + return Promise.resolve({ clients: "Test Config" }); +}; diff --git a/test/fixtures/loadfile/es-module-default-async.js b/test/fixtures/loadfile/es-module-default-async.js new file mode 100644 index 00000000..4c3109c3 --- /dev/null +++ b/test/fixtures/loadfile/es-module-default-async.js @@ -0,0 +1,5 @@ +"use strict"; +exports.__esModule = true; +exports["default"] = async function () { + return { clients: "Test Config" }; +}; diff --git a/test/fixtures/loadfile/es-module-default-promise.js b/test/fixtures/loadfile/es-module-default-promise.js new file mode 100644 index 00000000..ed59b0e4 --- /dev/null +++ b/test/fixtures/loadfile/es-module-default-promise.js @@ -0,0 +1,5 @@ +"use strict"; +exports.__esModule = true; +exports["default"] = function () { + return Promise.resolve({ clients: "Test Config" }); +}; diff --git a/test/loader/load_file.test.ts b/test/loader/load_file.test.ts index 6e3b4315..2fd94555 100644 --- a/test/loader/load_file.test.ts +++ b/test/loader/load_file.test.ts @@ -36,4 +36,40 @@ describe('test/loader/load_file.test.ts', () => { } assert.equal(result, '---\nmap:\n a: 1\n b: 2'); }); + + it('should load cjs module file which returns function returning a promise', async () => { + app = createApp('load_file'); + const result = (await app.loader.loadFile(getFilepath('load_file/promise_function.js'))); + assert.deepEqual(result, { clients: 'Test Config' }); + }); + + it('should load cjs module file which returns async function', async () => { + app = createApp('load_file'); + const result = (await app.loader.loadFile(getFilepath('load_file/async.js'))); + assert.deepEqual(result, { clients: 'Test Config' }); + }); + + it('should load compiled es module file', async () => { + app = createApp('load_file'); + const result = (await app.loader.loadFile(getFilepath('load_file/es-module-default.js'))); + assert(result.fn); + }); + + it('should load compiled es module file which default = null', async () => { + app = createApp('load_file'); + const result = (await app.loader.loadFile(getFilepath('load_file/es-module-default-null.js'))); + assert.equal(result, null); + }); + + it('should load compiled es module file which default = function returning a promise', async () => { + app = createApp('load_file'); + const result = (await app.loader.loadFile(getFilepath('load_file/es-module-default-promise.js'))); + assert.deepEqual(result, { clients: 'Test Config' }); + }); + + it('should load compiled es module file which default = async function', async () => { + app = createApp('load_file'); + const result = (await app.loader.loadFile(getFilepath('load_file/es-module-default-async.js'))); + assert.deepEqual(result, { clients: 'Test Config' }); + }); }); diff --git a/test/utils/index.test.ts b/test/utils/index.test.ts index 263d2c1c..2d05a31c 100644 --- a/test/utils/index.test.ts +++ b/test/utils/index.test.ts @@ -57,6 +57,16 @@ describe('test/utils/index.test.ts', () => { assert.equal(result, null); }); + it('should load es module with default = async function', async () => { + const result = await utils.loadFile(path.join(baseDir, 'es-module-default-async.js')); + assert(typeof result().then === 'function'); + }); + + it('should load es module with default = function returning a promise', async () => { + const result = await utils.loadFile(path.join(baseDir, 'es-module-default-promise.js')); + assert(typeof result().then === 'function'); + }); + it('should load no js file', async () => { let result = (await utils.loadFile(path.join(baseDir, 'no-js.yml'))).toString(); if (process.platform === 'win32') { @@ -110,6 +120,16 @@ describe('test/utils/index.test.ts', () => { assert.equal(result, null); }); + it('should load es module with default = async function', async () => { + const result = await utils.loadFile(path.join(baseDir, 'es-module-default-async.js')); + assert(typeof result().then === 'function'); + }); + + it('should load es module with default = function returning a promise', async () => { + const result = await utils.loadFile(path.join(baseDir, 'es-module-default-promise.js')); + assert(typeof result().then === 'function'); + }); + it('should load no js file', async () => { let result = (await utils.loadFile(path.join(baseDir, 'no-js.yml'))).toString(); if (process.platform === 'win32') {