From 6f41af7d0da0dafeea48c0b2e6c85fb854efd948 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 4 Jan 2025 15:32:22 +0800 Subject: [PATCH] fix: support load plugin from typescript dir --- package.json | 2 +- src/loader/egg_loader.ts | 46 ++++++++++++------- test/fixtures/plugin-ts-src/config/config.js | 3 ++ test/fixtures/plugin-ts-src/config/plugin.js | 7 +++ test/fixtures/plugin-ts-src/package.json | 3 ++ .../plugin-ts-src/plugins/g/package.json | 11 +++++ .../plugin-ts-src/plugins/g/src/index.ts | 1 + test/loader/mixin/load_plugin.test.ts | 7 +++ 8 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 test/fixtures/plugin-ts-src/config/config.js create mode 100644 test/fixtures/plugin-ts-src/config/plugin.js create mode 100644 test/fixtures/plugin-ts-src/package.json create mode 100644 test/fixtures/plugin-ts-src/plugins/g/package.json create mode 100644 test/fixtures/plugin-ts-src/plugins/g/src/index.ts diff --git a/package.json b/package.json index 0f06241d..24d5fbd6 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "dependencies": { "@eggjs/koa": "^2.20.6", "@eggjs/router": "^3.0.5", - "@eggjs/utils": "^4.1.5", + "@eggjs/utils": "^4.2.4", "egg-logger": "^3.5.0", "egg-path-matching": "^2.0.0", "extend2": "^4.0.0", diff --git a/src/loader/egg_loader.ts b/src/loader/egg_loader.ts index 4d2b5c83..24224279 100644 --- a/src/loader/egg_loader.ts +++ b/src/loader/egg_loader.ts @@ -5,9 +5,13 @@ import { debuglog, inspect } from 'node:util'; 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 { + getParamNames, readJSONSync, readJSON, exists, +} from 'utility'; import { extend } from 'extend2'; import { Request, Response, Application, Context as KoaContext } from '@eggjs/koa'; +import { register as tsconfigPathsRegister } from 'tsconfig-paths'; +import { isESM, isSupportTypeScript } from '@eggjs/utils'; import { pathMatching, type PathMatchingOptions } from 'egg-path-matching'; import { now, diff } from 'performance-ms'; import { CaseStyle, FULLPATH, FileLoader, FileLoaderOptions } from './file_loader.js'; @@ -65,7 +69,6 @@ export class EggLoader { readonly appInfo: EggAppInfo; dirs?: EggDirInfo[]; - /** * @class * @param {Object} options - options @@ -95,12 +98,11 @@ export class EggLoader { if (process.env.EGG_TYPESCRIPT === 'true' || (this.pkg.egg && this.pkg.egg.typescript)) { // skip require tsconfig-paths if tsconfig.json not exists const tsConfigFile = path.join(this.options.baseDir, 'tsconfig.json'); - // FIXME: support esm - if (fs.existsSync(tsConfigFile) && typeof require === 'function') { - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('tsconfig-paths').register({ cwd: this.options.baseDir }); + if (fs.existsSync(tsConfigFile)) { + tsconfigPathsRegister({ cwd: this.options.baseDir } as any); } else { - this.logger.info('[@eggjs/core/egg_loader] skip register "tsconfig-paths" because tsconfig.json not exists at %s', + this.logger.info( + '[@eggjs/core/egg_loader] skip register "tsconfig-paths" because tsconfig.json not exists at %s', tsConfigFile); } } @@ -599,7 +601,7 @@ export class EggLoader { plugin.version = pkg.version; } // support commonjs and esm dist files - plugin.path = this.#formatPluginPathFromPackageJSON(plugin.path!, pkg); + plugin.path = await this.#formatPluginPathFromPackageJSON(plugin.path!, pkg); } const logger = this.options.logger; @@ -753,26 +755,36 @@ export class EggLoader { } } - #formatPluginPathFromPackageJSON(pluginPath: string, pluginPkg: { + async #formatPluginPathFromPackageJSON(pluginPath: string, pluginPkg: { eggPlugin?: { exports?: { import?: string; require?: string; + typescript?: string; }; }; - }) { - if (pluginPkg.eggPlugin?.exports) { - if (typeof require === 'function') { - if (pluginPkg.eggPlugin.exports.require) { - pluginPath = path.join(pluginPath, pluginPkg.eggPlugin.exports.require); + }): Promise { + let realPluginPath = pluginPath; + const exports = pluginPkg.eggPlugin?.exports; + if (exports) { + if (isESM) { + if (exports.import) { + realPluginPath = path.join(pluginPath, exports.import); } } else { - if (pluginPkg.eggPlugin.exports.import) { - pluginPath = path.join(pluginPath, pluginPkg.eggPlugin.exports.import); + if (exports.require) { + realPluginPath = path.join(pluginPath, exports.require); + } + } + if (exports.typescript && isSupportTypeScript()) { + if (!(await exists(realPluginPath))) { + // if require/import path not exists, use typescript path for development stage + realPluginPath = path.join(pluginPath, exports.typescript); + debug('[formatPluginPathFromPackageJSON] use typescript path %o', realPluginPath); } } } - return pluginPath; + return realPluginPath; } #extendPlugins(targets: Record, plugins: Record) { diff --git a/test/fixtures/plugin-ts-src/config/config.js b/test/fixtures/plugin-ts-src/config/config.js new file mode 100644 index 00000000..cc35c707 --- /dev/null +++ b/test/fixtures/plugin-ts-src/config/config.js @@ -0,0 +1,3 @@ +exports.plugin = 'override plugin'; + +exports.middleware = []; diff --git a/test/fixtures/plugin-ts-src/config/plugin.js b/test/fixtures/plugin-ts-src/config/plugin.js new file mode 100644 index 00000000..8240e44f --- /dev/null +++ b/test/fixtures/plugin-ts-src/config/plugin.js @@ -0,0 +1,7 @@ +const path = require('path'); + +module.exports = { + agg: { + path: path.join(__dirname, '../plugins/g'), + }, +}; diff --git a/test/fixtures/plugin-ts-src/package.json b/test/fixtures/plugin-ts-src/package.json new file mode 100644 index 00000000..4f143291 --- /dev/null +++ b/test/fixtures/plugin-ts-src/package.json @@ -0,0 +1,3 @@ +{ + "name": "plugin-ts-src" +} diff --git a/test/fixtures/plugin-ts-src/plugins/g/package.json b/test/fixtures/plugin-ts-src/plugins/g/package.json new file mode 100644 index 00000000..32b610da --- /dev/null +++ b/test/fixtures/plugin-ts-src/plugins/g/package.json @@ -0,0 +1,11 @@ +{ + "eggPlugin": { + "name": "g", + "exports": { + "require": "./dist/commonjs", + "import": "./dist/esm", + "typescript": "./src" + } + }, + "version": "1.0.0" +} diff --git a/test/fixtures/plugin-ts-src/plugins/g/src/index.ts b/test/fixtures/plugin-ts-src/plugins/g/src/index.ts new file mode 100644 index 00000000..c155820b --- /dev/null +++ b/test/fixtures/plugin-ts-src/plugins/g/src/index.ts @@ -0,0 +1 @@ +export const foo = 'bar'; diff --git a/test/loader/mixin/load_plugin.test.ts b/test/loader/mixin/load_plugin.test.ts index a48db6b8..e64c14aa 100644 --- a/test/loader/mixin/load_plugin.test.ts +++ b/test/loader/mixin/load_plugin.test.ts @@ -222,6 +222,13 @@ describe('test/loader/mixin/load_plugin.test.ts', () => { assert(!message); }); + it('should load plugin when eggPlugin.exports.typescript = "./src" exists', async () => { + app = createApp('plugin-ts-src'); + const loader = app.loader; + await loader.loadPlugin(); + assert.match(loader.allPlugins.agg.path!, /src$/); + }); + it('should loadConfig plugins with custom plugins config', async () => { const baseDir = getFilepath('plugin'); const plugins = {