Reputation: 1447
I have node.js application written in TypeScript and I need to switch between two interface implementations based on the config file. Currently I have this code which seems to be working.
"use strict";
import { config } from "../config";
let Something;
if (config.useFakeSomething) {
Something = require("./FakeSomething").FakeSomething;
} else {
Something = require("./RealSomething").RealSomething;
}
...
let s = new Something();
s.DoStuff();
...
But I have bad gut feeling about that (mainly because of the mixing require and import for loading modules). Is there some other way how to achieve implementation switching based on config file without importing both modules?
Upvotes: 19
Views: 25388
Reputation: 919
A modern answer using the import() function:
import { config } from "../config";
let Something;
if (config.useFakeSomething) {
Something = (await import("./FakeSomething")).FakeSomething;
} else {
Something = (await import("./RealSomething")).RealSomething;
}
...
let s = new Something();
s.DoStuff();
...
Remember that import() is non blocking, so you need to add await if the code that follows needs the result from the import().
Upvotes: 8
Reputation: 1156
In addition to the correct answers above, in case you need this switching for many files within a single folder, you can use a symbolic-link (not available on Windows) that referenced to the right folder, so your code remains clean.
This approach is good for switching between real code and stubs, for instance
Upvotes: 0
Reputation: 983
You can do it like that:
let moduleLoader:any;
if( pladform == 1 ) {
moduleLoader = require('./module1');
} else {
moduleLoader = require('./module2');
}
and then
if( pladform === 1 ) {
platformBrowserDynamic().bootstrapModule(moduleLoader.module1, [ languageService ]);
}
else if ( pladform === 2 ) {
platformBrowserDynamic().bootstrapModule(moduleLoader.module2, [ languageService ]);
}
Upvotes: 1
Reputation: 3104
If you want to keep the client-code for your Something
class clean, you can move the conditional importing to a single file. You can have the following directory structure for your Something module:
/Something
RealSomething.ts
FakeSomething.ts
index.ts
And in your index.ts, you can have the following:
import { config } from '../config';
const Something = config.useFakeSomething ?
require('./FakeSomething').FakeSomething :
require('./RealSomething').RealSomething;
export default Something;
And in your client code, you can just import Something
:
import Something from './Something/index';
Upvotes: 8
Reputation: 22352
I can see nothing wrong with your approach. In fact lines like
import { config } from "../config";
When targeting commonjs will be compiled to the following javascript (ES6):
const config = require('../config');
So they are effectively identical and you are not mixing different module loading techniques.
Upvotes: 6