ng-di-transpiler
DI Transpiler for Angular
![Licence](https://img.shields.io/npm/l/ng-di-transpiler.svg?maxAge=2592000)
This is still in early stages but fully functional already.
What and Why?
See this.
Installation
$ npm install ng-di-transpiler --save
Usage
Integration
-
Fist you need to define interface of all platform tokens required in your app.
To do so create interface that extends from TokenProviders
from this library.
Extending is necessary because that's how library will know where to get tokens.
-
Create classes for each token extending from TokenProvider<T>
and providing
interface that real entity should implement by replacing T
.
-
Set properties to interface created in step #1 with types created in step #2.
In this way you will guarantee correctness of provided tokens for each platform.
-
Create as many providers.%platform%.ts
files as you need and export from there
const of type interface you created in step #1 and provide all tokens for platform.
-
Load platform specific file providers.%platform%.compiled.ts
into your application
providers.
You can always customize which files to transpile and what postfix for transpiled files to use.
Transpilation
Via CLI available as ngdt
.
To integrate with your build run this command just before build begins.
By default it will look and transpile file matching globe src/**/providers.*.ts
.
Generated files will live along originals but named %file_name%.compiled.ts
.
For CLI usage run ngdt -h
.
You can also customize transpiler by providing ngdtOptions
in your tsconfig.json
:
{
"ngdtOptions": {
"files": string[],
"postfix": string
}
}
Example use-case
Suppose your app requires some interfaces to be provided to different platforms.
We will start off be specifying wich providers should be provided and what interfaces they should implement:
import { TokenProviders, TokenProvider } from 'ng-di-transpiler';
import { CONSOLE_TOKEN, ConsoleInterface } from './console';
import { STORAGE_TOKEN, StorageInterface } from './storage';
export interface PlatformTokens extends TokenProviders {
console: ConsoleProvider;
storage: StorageProvider;
}
export class ConsoleProvider extends TokenProvider<ConsoleInterface> {
provider: CONSOLE_TOKEN;
}
export class StorageProvider extends TokenProvider<StorageInterface> {
provider: STORAGE_TOKEN;
}
Now it's time to provide real implementations for each specific platform.
Let's do first for Browser:
import { PlatformTokens, ConsoleProvider, StorageProvider } from './platform-tokens';
import { ConsoleLogger } from './browser/console-logger';
import { LocalStorage } from './browser/local-storage';
export const TOKENS: PlatformTokens = {
console: new ConsoleProvider(ConsoleLogger);
storage: new StorageProvider(LocalStorage);
};
Now let's provide implementations maybe for mobile:
import { PlatformTokens, ConsoleProvider, StorageProvider } from './platform-tokens';
import { MobileLogger } from './mobile/logger';
import { MobileStorage } from './mobile/storage';
export const TOKENS: PlatformTokens = {
console: new ConsoleProvider(MobileLogger);
storage: new StorageProvider(MobileStorage);
};
Thanks to this structure we can easily manage large amount of tokens for different platforms
ae we will get static analisys of our tokens.
If we will run ngdt
against this files above, we will have next files generated:
- ./src/core/platform/providers.browser.compiled.ts (from providers.browser.ts)
- ./src/core/platform/providers.mobile.compiled.ts (from providers.mobile.ts)
So we can safely include one of them depending for which platform we compiling our app.
We can keep our target platform in global variable TARGET
and provide it at compile time
via Webpack's DefinePlugin
or some similar technique and create next final file for platform tokens:
let PLATFORM_TOKENS = [];
if (TARGET === 'browser') {
PLATFORM_TOKENS = require('./providers.browser.compiled.ts').TOKENS || [];
} else if (TARGET === 'mobile') {
PLATFORM_TOKENS = require('./providers.mobile.compiled.ts').TOKENS || [];
}
export { PLATFORM_TOKENS };
NOTE: We could use import
statements here but Webpack would not eliminate those unused imports so
require
will make sure that our final bundle will have only neccessary tokens for selected platform.
And then we just consume our providers as usual in our AppModule:
import { PLATFORM_TOKENS } from './core/platform';
@NgModule({
providers: [
...PLATFORM_TOKENS,
]
})
export class AppModule { }
Development
To build project run:
$ npm run build
No tests yet and so no coverage and no travis - so no automatic deployment =)
Just yet!
License
MIT © Alex Malkevich