The idea behind @rxdi is to create independent, dependency injection that can be used everywhere, Node and Browser with purpose also to share the same code without chainging nothing! First steps where with platform called @gapi you can check repository @gapi/core. Then because of the needs of the platform i decided to develop this Reactive Dependency Injection container helping me build progressive applications. Hope you like my journey! Any help and suggestions are appreciated! Main repository @rxdi/core
git clone https://github.com/rxdi/starter-client-rxdi-router-preact
npm install
For starting and building application we will use Parcel a new configuration-less web bundler ParcelJS
This project is with added ReactJS and when builded for production bundle is less than 800Kb!!
To install parcel type:
npm install -g parcel-bundler
parcel ./src/index.html --target browser
parcel build ./src/index.html --target browser
src/main.ts
import { Bootstrap } from '@rxdi/core';
import { AppModule } from './app/app.module';
Bootstrap(AppModule, {
init: false,
initOptions: {
services: true,
},
logger: {
logging: true,
date: true,
hashes: true,
exitHandler: true,
fileService: true
}
})
.subscribe(
() => console.log('Started!'),
(e) => console.error(e)
);
src/app/app.module.ts
import { Module } from "@rxdi/core";
import { AppComponent } from "./app.component";
@Module({
bootstrap: [AppComponent]
})
export class AppModule {}
src/app/app.component.tsx
import { Component } from "@rxdi/core";
import { h, render, Component as PreactComponent } from 'preact';
import AsyncRoute from 'preact-async-route';
import { Router, Link } from 'preact-router';
@Component()
export class AppComponent extends PreactComponent {
OnBefore() {
render(<AppComponent />, document.body);
}
render() {
return <div>
<nav>
<Link activeClassName="active" href="/">Home</Link>
<Link activeClassName="active" href="/about">About</Link>
</nav>
<Router>
<AsyncRoute
path="/"
getComponent={this.getHomeComponent}
loading={() => <div>loading...</div>}
/>
<AsyncRoute
path="/about"
getComponent={this.getAboutComponent}
loading={() => <div>loading...</div>}
/>
</Router>
</div>
}
async getAboutComponent() {
return (await import('./about/about.component')).AboutComponent;
}
async getHomeComponent() {
return (await import('./home/home.component')).HomeComponent;
}
}
import { Component } from "@rxdi/core";
import { h, Component as PreactComponent } from 'preact';
@Component()
export class AboutComponent extends PreactComponent<any> {
render() {
return <div>
<h1>About </h1>
<h1>Yey</h1>
</div>;
}
}
import { Component } from "@rxdi/core";
import { h, Component as PreactComponent } from 'preact';
@Component()
export class HomeComponent extends PreactComponent {
render() {
return <div>
<h1>Lazy routed module </h1>
<h1>Route: </h1>
</div>;
}
}
@Injector()
- Decorator also can be used which will depend imediately instance of Class can be used as follow
@Component()
export class AppComponent extends PreactComponent<any, any> {
@Injector(AppService) private appService: AppService;
}
InjectSoft
- Function is added due to problem when extending React.Component or Preact Component
class.
Dependencies are not resolved and extended correctly by React.Component class.This is temporary solution for injecting Services when constructor is intialized and setting properties to correct constructor.
Except @Component()
when extending React.Component
all other decorators work as expected depending inside constructor.
When using NodeJS reamains unchanged
Later releases will be created separated class extending react and will be inside othe repository @rxdi/reactive-components
Can be extended as follow
import { Component } from "@rxdi/core";
import { ReactComponent } from "@rxdi/reactive-components";
import { ReactiveService } from "../components/react.service";
@Component()
export class AppComponent extends ReactComponent<any, any> {
// private reactiveService: ReactiveService = InjectSoft(ReactiveService); older version
constructor(
private reactiveService: ReactiveService
) {
super();
}
}