Closed soundarpandiyan closed 6 years ago
This is not a native typescript feature yet but could be supported by the standard of promise imports: http://2ality.com/2017/01/import-operator.html At the moment this is not available on NodeJS yet (as far as I know). So this is the wrong place for this issue. I suggest to close this issue.
@soundarpandiyan https://docs.nestjs.com/modules Dynamic Modules section.
Seems like I misunderstood the question. Sorry 😅
Hi kamil, marc. thanks for the response. I'm using DynamicModules section and posted the sample code and the issue. Can you please gives some idea on this
20:49 core module - applicationmodule plugin module - Ecash, AccountManagement, etc.. At the time of loading the core module i want to load the config file and check for the necessary plugin module and load in the ApplicationModule ex. @module { modules : [modules will be retrieved dynamically]} sample code: // code is not accurate just for demo purpose In Helper class, static getmodules () : DynamicModule{
Promise.all([ import('./ecash/ecash.module')]) .then(([myModule]) => { console.log(myModule); var EcashModule = myModule.EcashModule; });
Promise.all([ import('./account.module')]) .then(([myModule]) => { console.log(myModule); var AccountModule = myModule.AccountModule; });
return {
module : [],
modules : [EcashModule, AcountModule]};
}
In ApplicationModule class, @Module{ modules: ...Helper.getmodules().modules}
Issue: ApplicationModule is not waiting until the promise is resolved. In the mean time itself it try to load the Promise
I have posted it in the Gitter and waiting for some good solutions. I'm new to UI so code was bit nasty above.
Hi guys, Is it possible to achieve Dynamic loading of modules in nestjs. we are in the discussion on taking decision on using this framework for one our project. It would be great helpful if you could someone confirm on this. Thanks in advance
Hi, i have done this way. Does anyone have better suggestions. The only drawback is i'm not able to import dynamically but still achieve the requirement.
In Helper class,
import { Module1 } from '../Module1;
import { Module2} from '../Module2';
import { Module, DynamicModule } from '@nestjs/common';
var fs = require('fs'), xml2js = require('xml2js');
var _ = require('underscore');
export class DynamicModuleLoader{
static ModulesObject = [];
static PushModules(){
DynamicModuleLoader.ModulesObject.push(
{key: 'Module1', value: Module1},
{key: 'Module2', value: Module2}
);
}
static GetDynamicModules() : DynamicModule {
var Plugins = [];
var parser = new xml2js.Parser();
DynamicModuleLoader.PushModules();
let fileData = fs.readFileSync('.\shared.moduleconf.xml', 'ascii');
parser.parseString(fileData.substring(0, fileData.length), function (err, result) {
_.each(result.Modules.Module, (res) => {
let moduleDetails = DynamicModuleLoader.FindModulesByName(res.Name);
if(moduleDetails && res.PluginStatus == 'true')
Plugins.push(moduleDetails.value);
})
});
return {
module : [],
modules : [...Plugins]};
}
static FindModulesByName(moduleName)
{
let extractedModule = _.find(DynamicModuleLoader.ModulesObject, function(x){
return x.key == moduleName;
});
return extractedModule;
}
}
XML file:
<Modules>
<Module>
<Name>Module1</Name>
<PluginStatus>false</PluginStatus>
</Module>
<Module>
<Name>Module2</Name>
<PluginStatus>true</PluginStatus>
</Module>
</Modules>
In Core Module class:
@module(
{
modules: [ SharedModule, ...DynamicModuleLoader.GetDynamicModules().modules]
})
Please format you code with ``` Read this https://help.github.com/articles/creating-and-highlighting-code-blocks/
I got the solution from gitter community. Thanks for your time. It was great architecture to work with Nest js.
@soundarpandiyan this was your last solution or at last you could improve it?
@ericzon - Before creating the core module, we are importing the modules dynamically and added in the core module using reflect. I have mentioned the code as well below so it may be useful to someone. Please let me know if any other better approaches as well.
Thanks @luqezman for pointed out this idea.
async function bootstrap() {
var loadedModules;
loadedModules = await GetDynamicModules();
const currentModules = Reflect.getOwnMetadata('modules', ApplicationModule);
Reflect.defineMetadata('modules', [...currentModules, ...loadedModules], ApplicationModule);
const app = await NestFactory.create(ApplicationModule);
await app.listen(9000);
}
async function GetDynamicModules() {
var Plugins = [];
var parser = new xml2js.Parser();
let fileData: any;
let result: any;
fileData = await new Promise((resolve, reject) => fs.readFile('e:\\Apigee\\NodeServerNestJs\\src\\Shared\\shared.moduleconf.xml', 'ascii', function (err, data) {
if (err) reject(err);
else resolve(data);
}));
result = await new Promise((resolve, reject) => parser.parseString(fileData.substring(0, fileData.length), async function (err, result) {
if (err) reject(err);
else resolve(result);
}));
for (const moduleDetails of result.Modules.Module) {
if (moduleDetails.PluginStatus == 'true') {
let detail = await GetModules(moduleDetails);
Plugins.push(detail[moduleDetails.Name[0]]);
}
}
return new Promise(resolve => resolve(Plugins));
}
async function GetModules(moduleDetails) {
let promise = await new Promise(resolve => resolve(import(moduleDetails.Path[0])));
return promise
}
bootstrap();
xml file:
<Modules>
<Module>
<Name>Module1</Name>
<PluginStatus>false</PluginStatus>
<Path>.//Module1//Module1.module</Path>
</Module>
<Module>
<Name>Module2</Name>
<PluginStatus>true</PluginStatus>
<Path>.//Module2//Module2.module</Path>
</Module>
</Modules>
@soundarpadian, hope the code is working :)
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
we are planning to use nest js framework for middleware application using node js and typescript. i would like to load my modules (module1, module2.. ) dynamically based on the value given in the xml. It will help us to plug-in the feature to the application dynamically. your support and help are much appreciated on this. @Module({ imports: [...object], // object contains all the imported modules dynamically })