Retax helps you to bootstrap your universal react / redux application. It also comes with a set of optional opinionated helpers to structure and reduce your application code.
You could look at the examples folder to see how to use retax or look at a complete retax seed here (work in progress).
WARNING:
- The core of retax is stable and tested. 👍
- Optional modules (ActionsCreator, Api and RetaxComponent) are unstable and may change in a near future
Install retax:
npm install --save retax
And satisfy peer dependencies (yay, there are many...):
"peerDependencies": {
"cookie-parser": "^1.4.1",
"express": "^4.13.4",
"immutable": "^3.8.0",
"react-dom": "^0.14.0 || ^15.0.0-0",
"react-helmet": "^3.0.1",
"react-redux": "^4.4.5",
"react-router-redux": "^4.0.2",
"react-router": "^2.2.4",
"react": "^0.14.0 || ^15.0.0-0",
"redux": "^3.4.0",
"reflect-metadata": "^0.1.3",
"webpack-isomorphic-tools": "^2.2.26"
}
Retax also uses es6-generators, be sure to have a polyfill for that. babel-polyfill does the trick!
We want to render this simple react/redux app:
// app.js
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Route } from 'react-router';
export function counterReducer(state: number = 0, action: any): number {
switch (action.type) {
case 'INC':
return state + 1;
default:
return state;
}
}
function incrementActionCreator() {
return { type: 'INC' };
}
const About = connect(
({ counter }) => ({ counter }),
dispatch => bindActionCreators({ incrementActionCreator }, dispatch)
)(
({ counter, incrementActionCreator }) => (
<div onClick={incrementActionCreator}>
Hello About! Here is the counter value: {counter}
</div>
)
);
export default (
<Route path="/">
<Route path="about" component={About}/>
</Route>
);
Let's do that with retax!
First, define a retax configuration file.
// retax.config.js
import rootRoute, { counterReducer } from './app';
// retax configuration file support many more options, like redux-middleware, redux-store-enhancer, dynamic rootRoute evaluation, etc...
// the complete doc is comming very soon
export default {
router: {
static: rootRoute,
},
store: {
reducers: {
counter: counterReducer,
},
},
};
Finally, bootstrap the app.
// clientEntry.js
import { retax } from 'retax';
import retaxConfig from './retax.config';
retax.config(retaxConfig);
const rootElement = document.getElementById('root');
retax.bootstrap(rootElement);
That's all!
How many times react / redux developpers should edit the app configuration files (like createReduxStore.js
, clientEntry.js
, serverRenderingMiddleware.js
, etc...)?
Only once. But in practice. this is not really like that...
- If
react-router
has an new update with a change in its API, you will have to edit theclientEntry.js
, maybe theserverRenderingMiddleware.js
, and others... - If
redux
has a new update and expose a new function that does something more efficiently, you surely want to have this. - If
react
has a new... etc...
You got it? It could be a serious pain to update the structure of the app. (the more you have external dependencies, the harder it is!) And we have not talking about creating the real app yet...
Retax helps you with this. You have just to give it a configuration file and it will take care of everything. All its bootstrapping process is highly customizable if you need it. You can found here some details about it.
Here is a non exhaustive list of retax features:
- Support universal javascript
- Initialize your redux store
- You could provide your redux middlewares
- You also could provide your store enhancers
- And obviously, your reducers!
- Initialize react-router
- Just give retax a root route object (JSX or plain object)
- Support out-of-the-box code splitting (useful if you are using
require.ensure
into your react-router routes) - Initialize react-router-redux
- Render the react app
- you could append JSX elements in the render loop, useful if your want to include redux
<DevTools />
- you could append JSX elements in the render loop, useful if your want to include redux
- Support lifecycle hooks to customize and inject data during the bootstrapping process. For instance you could:
- Prefetch initial state before doing the route matching
- Prefetch components data once the route matching is done.
After the bootstrapping, you could still use all modules exposed by react, react-router, redux, react-router-redux, ...
(Eg. <Link />
from react-router, bindActionCreators
from redux)
As explained here, retax wraps your app with a component that has access to an IoC container. This allows you to register into it services and inject them later into other components.
All the following items are considered as retax modules.
Let's say uou want to do an ajax call to an API but you have to be authentified. Your auth token is in your session
reducer.
Each time you call your doAjaxCall
actions creator, your have to:
- read the store state
- retrieve the auth token
- pass it to your API Connector class
So much boilerplate code especially if you have to manage several API endpoints.
Retax API module helps you create an API class (with base methods, GET, POST, DELETE, PUT (can be extended)) and will inject into it the current auth token. This API class can later be injected into an Actions Creator.
Create an Actions Creator class with the possibility to inject into it other Actions Creator and APIs.
Create a React component with the possibility to inject into it Actions Creators.
Check builder and builder-ts-library
This project is shipped with typescript typings. If you are using typescript@^1.6, you don't have to do anything, it will detect the definition types automatically.
You can check the roadmap here.
Thanks to remojansen for the project inversify. This project is intensively used by retax.
##License MIT License (MIT)