我正在开发一个具有插件的MEAN堆栈应用程序 . 在服务器应用程序中,我设法使用 fs.lstatSync()stat.isDirectory() 加载插件文件 . 我还设法使用 app.use( pluginPublicPath, express.static( pluginServerPath )); 向公众公开每个插件的 /public 目录 .

现在我必须在angular应用程序中注入每个插件的 main-service.ts . 我正在使用标准的Typescript Angular 2服务,如下图所示 . 应用程序类是使用 system.js 导入的,没什么特别的 .

Project structure

project
└─── plugins
|    └─── my-plugin
|    |    └─── server // Some server stuff, all ok here
|    |    └─── public // Managed to expose it in the browser
|    |         └─── main.ts
|    |         └─── ...
|    └─── some-plugin
|    |     └─── server
|    |     └─── public
|    └─── another-plugin
|          └─── server
|          └─── public
└─── server // The server app
|    └─── ...
└─── public // The public angular app, nothing special, the usual files
|    └─── services
|    |    └─── foo-service.ts
|    |    └─── ...
|    └─── app.component.ts
|    └─── main-module.ts
|    └─── ...
└─── server.js
└─── package.json
└─── ...

foo-service.ts

// Static file, known and fixed path, no trouble here
import { Injectable } from '@angular/core';
import { AnotherService } from './another-service'

@Injectable()
export class MyService {
    constructor( private _anotherService: AnotherService ) {}
}

我可以直接在 constructor() 方法中输入 app.component.tsfoo-service.ts 中的插件 main-service.ts .

import { MyPluginMainService } from '../../plugins/my-plugin/public/main-service'
export class MyService {
    constructor( private _myPluginMainService : MyPluginMainService ) {}
}

我想要实现的是动态地从每个插件导入 main-service.ts 文件 . 基本上我想有一个插件框架按惯例加载插件,而不是配置 . 我追求这个设计是为了避免在项目中添加新插件时更改核心文件 . 与CMS如何自动检测插件类似 .

我期望通过从服务器生成的列表中注入插件服务来实现此目的 . 服务器应用程序已经知道哪些插件可用并已启用 . 我应该如何继续动态注入 plugins/some-plugin/main-service.ts ?我可以通过 api/modules endpoints 从服务器导出引导公共应用程序所需的文件名和文件路径列表 . 此外,还欢迎提供涵盖这种情况的代码示例 . 谢谢!

app.components.ts - 我疯狂猜测......

modules.forEach( module => import { module.name } from module.path );
export class MyService {
    constructor( ??? ) {}
}

也是我猜测 main-module.ts

listOfProviders = [];

modules.forEach( module => 
    listOfProviders.push( import { module.name } from module.path );
);

@NgModule({
    imports: ...
    declarations: ...
    providers: listOfProviders,
    bootstrap: [ AppComponent ]
})