diff --git a/.gitignore b/.gitignore index 9c6c60ea..0eacba65 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ plugin/dal/test/fixtures/modules/*/dal/ !plugin/orm/test/fixtures/prepare.js !benchmark/**/*.js plugin/tegg/test/fixtures/apps/**/*.js +!standalone/standalone/test/fixtures/**/node_modules +!standalone/standalone/test/fixtures/**/node_modules/**/*.js diff --git a/standalone/standalone/src/Runner.ts b/standalone/standalone/src/Runner.ts index 1807b269..0707eafd 100644 --- a/standalone/standalone/src/Runner.ts +++ b/standalone/standalone/src/Runner.ts @@ -1,4 +1,4 @@ -import { ModuleConfigUtil, ModuleReference, RuntimeConfig } from '@eggjs/tegg-common-util'; +import { ModuleConfigUtil, ModuleReference, ReadModuleReferenceOptions, RuntimeConfig } from '@eggjs/tegg-common-util'; import { EggPrototype, EggPrototypeLifecycleUtil, LoadUnit, @@ -26,6 +26,10 @@ import { ConfigSourceQualifierAttribute } from './ConfigSource'; import { ConfigSourceLoadUnitHook } from './ConfigSourceLoadUnitHook'; import { LoadUnitInnerClassHook } from './LoadUnitInnerClassHook'; +export interface ModuleDependency extends ReadModuleReferenceOptions { + baseDir: string; +} + export interface RunnerOptions { /** * @deprecated @@ -35,6 +39,7 @@ export interface RunnerOptions { env?: string; name?: string; innerObjectHandlers?: Record; + dependencies?: (string | ModuleDependency)[]; } export class Runner { @@ -62,7 +67,11 @@ export class Runner { this.cwd = cwd; this.env = options?.env; this.name = options?.name; - this.moduleReferences = ModuleConfigUtil.readModuleReference(this.cwd); + const moduleDirs = (options?.dependencies || []).concat(this.cwd); + this.moduleReferences = moduleDirs.reduce((list, baseDir) => { + const module = typeof baseDir === 'string' ? { baseDir } : baseDir; + return list.concat(...ModuleConfigUtil.readModuleReference(module.baseDir, module)); + }, [] as readonly ModuleReference[]); this.moduleConfigs = {}; this.innerObjects = { moduleConfigs: [{ diff --git a/standalone/standalone/test/fixtures/dependency/foo.ts b/standalone/standalone/test/fixtures/dependency/foo.ts new file mode 100644 index 00000000..0f143b38 --- /dev/null +++ b/standalone/standalone/test/fixtures/dependency/foo.ts @@ -0,0 +1,19 @@ +import { ContextProto, Inject } from '@eggjs/tegg'; +import { Runner, MainRunner } from '@eggjs/tegg/standalone'; +import { Hello } from 'dependency-2/foo'; +import { ConfigSourceQualifier } from '../../../src/ConfigSource'; + +@ContextProto() +@Runner() +export class Foo implements MainRunner { + @Inject() + hello: Hello; + + @Inject() + @ConfigSourceQualifier('dependency2') + moduleConfig: any; + + async main(): Promise { + return this.hello.hello() + JSON.stringify(this.moduleConfig); + } +} diff --git a/standalone/standalone/test/fixtures/dependency/node_modules/dependency-1/package.json b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-1/package.json new file mode 100644 index 00000000..b466485a --- /dev/null +++ b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-1/package.json @@ -0,0 +1,9 @@ +{ + "name": "dependency-1", + "eggModule": { + "name": "dependency-1" + }, + "dependencies": { + "dependency-2": "*" + } +} diff --git a/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/foo.js b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/foo.js new file mode 100644 index 00000000..be45aaf7 --- /dev/null +++ b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/foo.js @@ -0,0 +1,16 @@ +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; + +const { SingletonProto, AccessLevel } = require('@eggjs/tegg'); + +class Hello { + hello() { + return 'hello!'; + } +} + +exports.Hello = __decorate([SingletonProto({ accessLevel: AccessLevel.PUBLIC })], Hello); diff --git a/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/module.yml b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/module.yml new file mode 100644 index 00000000..a0046c04 --- /dev/null +++ b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/module.yml @@ -0,0 +1,3 @@ +features: + dynamic: + foo: 'bar' diff --git a/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/package.json b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/package.json new file mode 100644 index 00000000..6937b57d --- /dev/null +++ b/standalone/standalone/test/fixtures/dependency/node_modules/dependency-2/package.json @@ -0,0 +1,6 @@ +{ + "name": "dependency-2", + "eggModule": { + "name": "dependency2" + } +} diff --git a/standalone/standalone/test/fixtures/dependency/package.json b/standalone/standalone/test/fixtures/dependency/package.json new file mode 100644 index 00000000..3f7079f6 --- /dev/null +++ b/standalone/standalone/test/fixtures/dependency/package.json @@ -0,0 +1,6 @@ +{ + "name": "entry", + "eggModule": { + "name": "entry" + } +} diff --git a/standalone/standalone/test/index.test.ts b/standalone/standalone/test/index.test.ts index 01c6966d..2203d03d 100644 --- a/standalone/standalone/test/index.test.ts +++ b/standalone/standalone/test/index.test.ts @@ -14,6 +14,17 @@ describe('test/index.test.ts', () => { }); }); + describe('runner with dependency', () => { + it('should work', async () => { + const msg: string = await main(path.join(__dirname, './fixtures/dependency'), { + dependencies: [ + path.join(__dirname, './fixtures/dependency/node_modules/dependency-1'), + ], + }); + assert(msg === 'hello!{"features":{"dynamic":{"foo":"bar"}}}'); + }); + }); + describe('runner with inner object', () => { it('should work', async () => { const msg: string = await main(path.join(__dirname, './fixtures/inner-object'), {